vpn

package
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2022 License: GPL-3.0 Imports: 32 Imported by: 0

Documentation

Overview

Package vpn contains the API to create an OpenVPN client that can connect to a remote OpenVPN endpoint and provide you with a tunnel where to send packets.

The recommended way to use this package is to use the dialer methods.

Index

Constants

View Source
const (
	UDPMode = iota
	TCPMode
)

Variables

View Source
var (
	// ErrDialError is a generic error while dialing
	ErrDialError = errors.New("dial error")

	// ErrAlreadyStarted is returned when trying to start the tunnel more than once
	ErrAlreadyStarted = errors.New("tunnel already started")
)
View Source
var (
	ErrBadHandshake     = errors.New("bad vpn handshake")
	ErrBadDataHandshake = errors.New("bad data handshake")
)
View Source
var (
	// ErrBadTLSHandshake is returned when the OpenVPN handshake failed.
	ErrBadTLSHandshake = errors.New("handshake failure")
	// ErrBadCA is returned when the CA file cannot be found or is not valid.
	ErrBadCA = errors.New("bad ca conf")
	// ErrBadKeypair is returned when the key or cert file cannot be found or is not valid.
	ErrBadKeypair = errors.New("bad keypair conf")
	// ErrBadParrot is returned for errors during TLS parroting
	ErrBadParrot = errors.New("cannot parrot")
	// ErrCannotVerifyCertChain is returned for certificate chain validation errors.
	ErrCannotVerifyCertChain = errors.New("cannot verify chain")
)
View Source
var (
	// ErrBadConnNetwork indicates that the conn's network is neither TCP nor UDP.
	ErrBadConnNetwork = errors.New("bad conn.Network value")

	// ErrPacketTooShort indicates that a packet is too short.
	ErrPacketTooShort = errors.New("packet too short")
)

Functions

func NewClientFromOptions

func NewClientFromOptions(opt *Options) vpnClient

NewClientFromOptions returns a Client configured with the given Options.

Types

type Client

type Client struct {
	Opts   *Options
	Dialer DialerContext

	Log Logger
	// contains filtered or unexported fields
}

Client implements the OpenVPN protocol. If you're just interested in writing to and reading from the tunnel you should use the dialer methods instead. This type is only intended to be instantiated by users that need a finer control of the protocol steps (i.e., you want to be sure that you are only calling the handshake, etc.)

func (*Client) Close

func (c *Client) Close() error

Close closes the tunnel connection.

func (*Client) Dial

func (c *Client) Dial(ctx context.Context) (net.Conn, error)

Dial opens a TCP/UDP socket against the remote, and creates an internal data channel. It is the second step in an OpenVPN connection (out of five). (In UDP mode no network connection is done at this step).

func (*Client) LocalAddr

func (c *Client) LocalAddr() net.Addr

LocalAddr returns the local address on the tunnel virtual device.

func (*Client) Read

func (c *Client) Read(b []byte) (int, error)

Read reads bytes from the tunnel.

func (*Client) RemoteAddr

func (c *Client) RemoteAddr() net.Addr

TODO(ainghazal): should get the remote _tunnel_ ip addr somehow

func (*Client) SetDeadline

func (c *Client) SetDeadline(t time.Time) error

func (*Client) SetReadDeadline

func (c *Client) SetReadDeadline(t time.Time) error

func (*Client) SetWriteDeadline

func (c *Client) SetWriteDeadline(t time.Time) error

func (*Client) Start

func (c *Client) Start(ctx context.Context) error

Start starts the OpenVPN tunnel.

func (*Client) Write

func (c *Client) Write(b []byte) (int, error)

Write sends bytes into the tunnel.

type DialContextFn

type DialContextFn func(context.Context, string, string) (net.Conn, error)

type DialerContext

type DialerContext interface {
	DialContext(context.Context, string, string) (net.Conn, error)
}

DialerContext is anything that features a net.Dialer-like DialContext method.

type Logger

type Logger interface {
	// Debug emits a debug message.
	Debug(msg string)

	// Debugf formats and emits a debug message.
	Debugf(format string, v ...interface{})

	// Info emits an informational message.
	Info(msg string)

	// Infof formats and emits an informational message.
	Infof(format string, v ...interface{})

	// Warn emits a warning message.
	Warn(msg string)

	// Warnf formats and emits a warning message.
	Warnf(format string, v ...interface{})

	// Error emits an error message
	Error(msg string)

	// Errorf formats and emits an error message.
	Errorf(format string, v ...interface{})
}

Logger is compatible with github.com/apex/log

type Options

type Options struct {
	Remote    string
	Port      string
	Proto     int
	Username  string
	Password  string
	Ca        string
	Cert      string
	Key       string
	Compress  compression
	Cipher    string
	Auth      string
	TLSMaxVer string
	// below are options that do not conform to the OpenVPN configuration format.
	ProxyOBFS4 string
	Log        Logger
}

Options make all the relevant configuration options accessible to the different modules that need it.

func ParseConfigFile

func ParseConfigFile(filePath string) (*Options, error)

ParseConfigFile expects a path to a valid config file and returns an Option object after parsing the file.

func (*Options) String

func (o *Options) String() string

type RawDialer

type RawDialer struct {
	Options *Options
	// contains filtered or unexported fields
}

func NewRawDialer

func NewRawDialer(opts *Options) *RawDialer

NewRawDialer returns a new *RawDialer constructed from the passed options.

func (*RawDialer) Dial

func (d *RawDialer) Dial() (net.Conn, error)

Dial returns a net.Conn that writes to and reads (raw packets) from the VPN tunnel.

func (*RawDialer) DialContext

func (d *RawDialer) DialContext(ctx context.Context) (net.Conn, error)

DialContext returns a net.Conn that writes to and reads (raw packets) from the VPN tunnel.

type TLSConn

type TLSConn struct {
	// contains filtered or unexported fields
}

TLSConn implements net.Conn, and is passed to the tls.Client to perform a TLS Handshake over OpenVPN control packets.

func NewTLSConn

func NewTLSConn(conn net.Conn, s *session) (*TLSConn, error)

NewTLSConn returns a TLSConn. It requires the on-the-wire net.Conn that will be used underneath, and a configured session. It returns also an error if the operation cannot be completed.

func (*TLSConn) Close

func (t *TLSConn) Close() error

Close closes the tls connection.

func (*TLSConn) LocalAddr

func (t *TLSConn) LocalAddr() net.Addr

func (*TLSConn) Read

func (t *TLSConn) Read(b []byte) (int, error)

Read over the control channel. This method implements the reliability layer: it retries reads until the _next_ packet is received (according to the packetID). Returns also an error if the operation cannot be completed.

func (*TLSConn) RemoteAddr

func (t *TLSConn) RemoteAddr() net.Addr

func (*TLSConn) SetDeadline

func (t *TLSConn) SetDeadline(tt time.Time) error

func (*TLSConn) SetReadDeadline

func (t *TLSConn) SetReadDeadline(tt time.Time) error

func (*TLSConn) SetWriteDeadline

func (t *TLSConn) SetWriteDeadline(tt time.Time) error

func (*TLSConn) Write

func (t *TLSConn) Write(b []byte) (int, error)

Write writes the given data to the tls connection.

type TLSModeTransporter

type TLSModeTransporter interface {
	// ReadPacket reads an OpenVPN packet from the wire.
	ReadPacket() (p *packet, err error)

	// WritePacket writes an OpenVPN packet to the wire.
	WritePacket(opcodeKeyID uint8, data []byte) error

	// SetDeadline sets the underlying conn's deadline.
	SetDeadline(deadline time.Time) error

	// SetReadDeadline sets the underlying conn's read deadline.
	SetReadDeadline(deadline time.Time) error

	// SetWriteDeadline sets the underlying conn's write deadline.
	SetWriteDeadline(deadline time.Time) error

	// Close closes the underlying conn.
	Close() error

	// LocalAddr returns the underlying conn's local addr.
	LocalAddr() net.Addr

	// RemoteAddr returns the underlying conn's remote addr.
	RemoteAddr() net.Addr
}

TLSModeTransporter is a transport for OpenVPN in TLS mode.

See https://openvpn.net/community-resources/openvpn-protocol/ for documentation on the protocol used by OpenVPN on the wire.

func NewTLSModeTransport

func NewTLSModeTransport(conn net.Conn, s *session) (TLSModeTransporter, error)

NewTLSModeTransport creates a new TLSModeTransporter using the given net.Conn.

type TunDialer

type TunDialer struct {
	Dialer DialerContext
	// contains filtered or unexported fields
}

A TunDialer contains options for obtaining a network connection tunneled through an OpenVPN endpoint. It uses a userspace gVisor virtual device over the raw VPN tunnel.

func NewTunDialer

func NewTunDialer(raw *RawDialer) TunDialer

NewTunDialer creates a new Dialer with the default nameservers (OpenDNS).

func NewTunDialerFromOptions

func NewTunDialerFromOptions(opt *Options) TunDialer

NewDialerFromOptions creates a new Dialer directly from an Options object.

func NewTunDialerWithNameservers

func NewTunDialerWithNameservers(raw *RawDialer, ns1, ns2 string) TunDialer

NewDialerWithNameservers creates a new Dialer with the passed nameservers. You probably want to pass the nameservers for your own VPN service here.

func (TunDialer) Dial

func (td TunDialer) Dial(network, address string) (net.Conn, error)

Dial connects to the address on the named network, via the OpenVPN endpoint that is configured in the dialer.

The return value implements the net.Conn interface, but it is a socket created on a virtual device, using gVisor userspace network stack. This means that the kernel only sees UDP packets with an encrypted payload.

The addresses are resolved via the OpenVPN tunnel too, and against the nameservers configured in the dialer. This feature uses wireguard's little custom DNS client implementation.

Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ping4", "ping6".

func (TunDialer) DialContext

func (td TunDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error)

DialContext connects to the address on the named network using the provided context.

func (TunDialer) DialTimeout

func (td TunDialer) DialTimeout(network, address string, timeout time.Duration) (net.Conn, error)

DialTimeout acts like Dial but takes a timeout.

Notes

Bugs

  • we cannot use the tun-mtu that the remote advertises, so we subtract a "safety" margin for now.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL