tor

package
v0.0.0-...-0c21b66 Latest Latest
Warning

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

Go to latest
Published: Sep 3, 2022 License: MIT Imports: 21 Imported by: 1

README

tor

The tor package contains utility functions that allow for interacting with the Tor daemon. So far, supported functions include:

  • Routing all traffic over Tor's exposed SOCKS5 proxy.
  • Routing DNS queries over Tor (A, AAAA, SRV).
  • Limited Tor Control functionality (synchronous messages only). So far, this includes:
    • Support for SAFECOOKIE, HASHEDPASSWORD, and NULL authentication methods.
    • Creating v2 and v3 onion services.

In the future, the Tor Control functionality will be extended to support v3 onion services, asynchronous messages, etc.

Installation and Updating

⛰  go get -u github.com/brronsuite/broln/tor

Documentation

Index

Constants

View Source
const (

	// ProtocolInfoVersion is the `protocolinfo` version currently supported
	// by the Tor server.
	ProtocolInfoVersion = 1

	// MinTorVersion is the minimum supported version that the Tor server
	// must be running on. This is needed in order to create v3 onion
	// services through Tor's control port.
	MinTorVersion = "0.3.3.6"
)
View Source
const (

	// OnionSuffix is the ".onion" suffix for v2 and v3 onion addresses.
	OnionSuffix = ".onion"

	// OnionSuffixLen is the length of the ".onion" suffix.
	OnionSuffixLen = len(OnionSuffix)

	// V2DecodedLen is the length of a decoded v2 onion service.
	V2DecodedLen = 10

	// V2Len is the length of a v2 onion service including the ".onion"
	// suffix.
	V2Len = 22

	// V3DecodedLen is the length of a decoded v3 onion service.
	V3DecodedLen = 35

	// V3Len is the length of a v3 onion service including the ".onion"
	// suffix.
	V3Len = 62
)
View Source
const (
	// DefaultConnTimeout is the maximum amount of time a dial will wait for
	// a connect to complete.
	DefaultConnTimeout time.Duration = time.Second * 120
)
View Source
const Subsystem = "TORC" // TORC as in Tor Controller.

Subsystem defines the logging code for this subsystem.

Variables

View Source
var (
	// ErrServiceNotCreated is used when we want to query info on an onion
	// service while it's not been created yet.
	ErrServiceNotCreated = errors.New("onion service hasn't been created")

	// ErrServiceIDMismatch is used when the serviceID the controller has
	// doesn't match the serviceID the Tor daemon has.
	ErrServiceIDMismatch = errors.New("onion serviceIDs don't match")

	// ErrNoServiceFound is used when the Tor daemon replies no active
	// onion services found for the current control connection while we
	// expect one.
	ErrNoServiceFound = errors.New("no active service found")
)
View Source
var (
	// Base32Encoding represents the Tor's base32-encoding scheme for v2 and
	// v3 onion addresses.
	Base32Encoding = base32.NewEncoding(base32Alphabet)
)
View Source
var (
	// ErrNoPrivateKey is an error returned by the OnionStore.PrivateKey
	// method when a private key hasn't yet been stored.
	ErrNoPrivateKey = errors.New("private key not found")
)

Functions

func Dial

func Dial(address, socksAddr string, streamIsolation bool,
	skipProxyForClearNetTargets bool,
	timeout time.Duration) (net.Conn, error)

Dial is a wrapper over the non-exported dial function that returns a wrapper around net.Conn in order to expose the actual remote address we're dialing, rather than the proxy's address.

func DisableLog

func DisableLog()

DisableLog disables all library log output. Logging output is disabled by default until UseLogger is called.

func FakeIPToOnionHost

func FakeIPToOnionHost(fakeIP net.Addr) (net.Addr, error)

FakeIPToOnionHost turns a fake IPv6 address that encodes an Onion v2 address back into its onion host address representation. For example, this will turn the fake tcp6 address [fd87:d87e:eb43:58f9:f82e:3e3e:83f3:c625]:8333 back into ld47qlr6h2b7hrrf.onion:8333.

func IsOnionFakeIP

func IsOnionFakeIP(addr net.Addr) bool

IsOnionFakeIP checks whether a given net.Addr is a fake IPv6 address that encodes an Onion v2 address.

func IsOnionHost

func IsOnionHost(host string) bool

IsOnionHost determines whether a host is part of an onion address.

func LookupHost

func LookupHost(host, socksAddr string) ([]string, error)

LookupHost performs DNS resolution on a given host via Tor's native resolver. Only IPv4 addresses are returned.

func LookupSRV

func LookupSRV(service, proto, name, socksAddr,
	dnsServer string, streamIsolation bool, skipProxyForClearNetTargets bool,
	timeout time.Duration) (string, []*net.SRV, error)

LookupSRV uses Tor's SOCKS proxy to route DNS SRV queries. Tor does not natively support SRV queries so we must route all SRV queries through the proxy by connecting directly to a DNS server and querying it. The DNS server must have TCP resolution enabled for the given port.

func OnionHostToFakeIP

func OnionHostToFakeIP(host string) (net.IP, error)

OnionHostToFakeIP encodes an Onion v2 address into a fake IPv6 address that encodes the same information but can be used for libraries that operate on an IP address base only, like brond's address manager. For example, this will turn the onion host ld47qlr6h2b7hrrf.onion into the ip6 address fd87:d87e:eb43:58f9:f82e:3e3e:83f3:c625.

func ParseAddr

func ParseAddr(address, socksAddr string) (net.Addr, error)

ParseAddr parses an address from its string format to a net.Addr.

func ResolveTCPAddr

func ResolveTCPAddr(address, socksAddr string) (*net.TCPAddr, error)

ResolveTCPAddr uses Tor's proxy to resolve TCP addresses instead of the standard system resolver provided in the `net` package.

func UseLogger

func UseLogger(logger bronlog.Logger)

UseLogger uses a specified Logger to output package logging info. This should be used in preference to SetLogWriter if the caller is also using bronlog.

Types

type AddOnionConfig

type AddOnionConfig struct {
	// Type denotes the type of the onion service that should be created.
	Type OnionType

	// VirtualPort is the externally reachable port of the onion address.
	VirtualPort int

	// TargetPorts is the set of ports that the service will be listening
	// on locally. The Tor server will use choose a random port from this
	// set to forward the traffic from the virtual port.
	//
	// NOTE: If nil/empty, the virtual port will be used as the only target
	// port.
	TargetPorts []int

	// Store is responsible for storing all onion service related
	// information.
	//
	// NOTE: If not specified, then nothing will be stored, making onion
	// services unrecoverable after shutdown.
	Store OnionStore
}

AddOnionConfig houses all of the required parameters in order to successfully create a new onion service or restore an existing one.

type ClearNet

type ClearNet struct{}

ClearNet is an implementation of the Net interface that defines behaviour for regular network connections.

func (*ClearNet) Dial

func (r *ClearNet) Dial(
	network, address string, timeout time.Duration) (net.Conn, error)

Dial on the regular network uses net.Dial

func (*ClearNet) LookupHost

func (r *ClearNet) LookupHost(host string) ([]string, error)

LookupHost for regular network uses the net.LookupHost function

func (*ClearNet) LookupSRV

func (r *ClearNet) LookupSRV(service, proto, name string,
	timeout time.Duration) (string, []*net.SRV, error)

LookupSRV for regular network uses net.LookupSRV function

func (*ClearNet) ResolveTCPAddr

func (r *ClearNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error)

ResolveTCPAddr for regular network uses net.ResolveTCPAddr function

type Controller

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

Controller is an implementation of the Tor Control protocol. This is used in order to communicate with a Tor server. Its only supported method of authentication is the SAFECOOKIE method.

NOTE: The connection to the Tor server must be authenticated before proceeding to send commands. Otherwise, the connection will be closed.

TODO:

  • if adding support for more commands, extend this with a command queue?
  • place under sub-package?
  • support async replies from the server

func NewController

func NewController(controlAddr string, targetIPAddress string,
	password string) *Controller

NewController returns a new Tor controller that will be able to interact with a Tor server.

func (*Controller) AddOnion

func (c *Controller) AddOnion(cfg AddOnionConfig) (*OnionAddr, error)

AddOnion creates an ephemeral onion service and returns its onion address. Once created, the new onion service will remain active until either,

  • the onion service is removed via `DEL_ONION`.
  • the Tor daemon terminates.
  • the controller connection that originated the `ADD_ONION` is closed.

Each connection can only see its own ephemeral services. If a service needs to survive beyond current controller connection, use the "Detach" flag when creating new service via `ADD_ONION`.

func (*Controller) CheckOnionService

func (c *Controller) CheckOnionService() error

CheckOnionService checks that the onion service created by the controller is active. It queries the Tor daemon using the endpoint "onions/current" to get the current onion service and checks that service ID matches the activeServiceID.

func (*Controller) DelOnion

func (c *Controller) DelOnion(serviceID string) error

DelOnion tells the Tor daemon to remove an onion service, which satisfies either,

  • the onion service was created on the same control connection as the "DEL_ONION" command.
  • the onion service was created using the "Detach" flag.

func (*Controller) Reconnect

func (c *Controller) Reconnect() error

Reconnect makes a new socket connection between the tor controller and daemon. It will attempt to close the old connection, make a new connection and authenticate, and finally reset the activeServiceID that the controller is aware of.

NOTE: Any old onion services will be removed once this function is called. In the case of a Tor daemon restart, previously created onion services will no longer be there. If the function is called without a Tor daemon restart, because the control connection is reset, all the onion services belonging to the old connection will be removed.

func (*Controller) Start

func (c *Controller) Start() error

Start establishes and authenticates the connection between the controller and a Tor server. Once done, the controller will be able to send commands and expect responses.

func (*Controller) Stop

func (c *Controller) Stop() error

Stop closes the connection between the controller and the Tor server.

type DialFunc

type DialFunc func(net, addr string, timeout time.Duration) (net.Conn, error)

DialFunc is a type defines the signature of a dialer used by our Net interface.

type Net

type Net interface {
	// Dial connects to the address on the named network.
	Dial(network, address string, timeout time.Duration) (net.Conn, error)

	// LookupHost performs DNS resolution on a given host and returns its
	// addresses.
	LookupHost(host string) ([]string, error)

	// LookupSRV tries to resolve an SRV query of the given service,
	// protocol, and domain name.
	LookupSRV(service, proto, name string,
		timeout time.Duration) (string, []*net.SRV, error)

	// ResolveTCPAddr resolves TCP addresses.
	ResolveTCPAddr(network, address string) (*net.TCPAddr, error)
}

Net is an interface housing a Dial function and several DNS functions that allows us to abstract the implementations of these functions over different networks, e.g. clearnet, Tor net, etc.

type OnionAddr

type OnionAddr struct {
	// OnionService is the host of the onion address.
	OnionService string

	// Port is the port of the onion address.
	Port int
}

OnionAddr represents a Tor network end point onion address.

func (*OnionAddr) Network

func (o *OnionAddr) Network() string

Network returns the network that this implementation of net.Addr will use. In this case, because Tor only allows TCP connections, the network is "tcp".

func (*OnionAddr) String

func (o *OnionAddr) String() string

String returns the string representation of an onion address.

type OnionFile

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

OnionFile is a file-based implementation of the OnionStore interface that stores an onion service's private key.

func NewOnionFile

func NewOnionFile(privateKeyPath string,
	privateKeyPerm os.FileMode) *OnionFile

NewOnionFile creates a file-based implementation of the OnionStore interface to store an onion service's private key.

func (*OnionFile) DeletePrivateKey

func (f *OnionFile) DeletePrivateKey(_ OnionType) error

DeletePrivateKey removes the file containing the private key.

func (*OnionFile) PrivateKey

func (f *OnionFile) PrivateKey(_ OnionType) ([]byte, error)

PrivateKey retrieves the private key from its expected path. If the file does not exist, then ErrNoPrivateKey is returned.

func (*OnionFile) StorePrivateKey

func (f *OnionFile) StorePrivateKey(_ OnionType, privateKey []byte) error

StorePrivateKey stores the private key at its expected path.

type OnionStore

type OnionStore interface {
	// StorePrivateKey stores the private key according to the
	// implementation of the OnionStore interface.
	StorePrivateKey(OnionType, []byte) error

	// PrivateKey retrieves a stored private key. If it is not found, then
	// ErrNoPrivateKey should be returned.
	PrivateKey(OnionType) ([]byte, error)

	// DeletePrivateKey securely removes the private key from the store.
	DeletePrivateKey(OnionType) error
}

OnionStore is a store containing information about a particular onion service.

type OnionType

type OnionType int

OnionType denotes the type of the onion service.

const (
	// V2 denotes that the onion service is V2.
	V2 OnionType = iota

	// V3 denotes that the onion service is V3.
	V3
)

type ProxyNet

type ProxyNet struct {
	// SOCKS is the host:port which Tor's exposed SOCKS5 proxy is listening
	// on.
	SOCKS string

	// DNS is the host:port of the DNS server for Tor to use for SRV
	// queries.
	DNS string

	// StreamIsolation is a bool that determines if we should force the
	// creation of a new circuit for this connection. If true, then this
	// means that our traffic may be harder to correlate as each connection
	// will now use a distinct circuit.
	StreamIsolation bool

	// SkipProxyForClearNetTargets allows the proxy network to use direct
	// connections to non-onion service targets. If enabled, the node IP
	// address will be revealed while communicating with such targets.
	SkipProxyForClearNetTargets bool
}

ProxyNet is an implementation of the Net interface that defines behavior for Tor network connections.

func (*ProxyNet) Dial

func (p *ProxyNet) Dial(network, address string,
	timeout time.Duration) (net.Conn, error)

Dial uses the Tor Dial function in order to establish connections through Tor. Since Tor only supports TCP connections, only TCP networks are allowed.

func (*ProxyNet) LookupHost

func (p *ProxyNet) LookupHost(host string) ([]string, error)

LookupHost uses the Tor LookupHost function in order to resolve hosts over Tor.

func (*ProxyNet) LookupSRV

func (p *ProxyNet) LookupSRV(service, proto,
	name string, timeout time.Duration) (string, []*net.SRV, error)

LookupSRV uses the Tor LookupSRV function in order to resolve SRV DNS queries over Tor.

func (*ProxyNet) ResolveTCPAddr

func (p *ProxyNet) ResolveTCPAddr(network, address string) (*net.TCPAddr, error)

ResolveTCPAddr uses the Tor ResolveTCPAddr function in order to resolve TCP addresses over Tor.

Jump to

Keyboard shortcuts

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