unixproxy

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Feb 19, 2024 License: Apache-2.0 Imports: 17 Imported by: 0

README

package unixproxy

Note: this package is experimental and potentially insecure.

Package unixproxy provides a reverse proxy to local Unix sockets. The intent is to facilitate local development of distributed systems, by creating semantically meaningful addresses for arbitrary localhost HTTP servers.

See package documentation for details.

Documentation

Overview

package unixproxy provides an EXPERIMENTAL reverse proxy to Unix sockets.

The intent of this package is to facilitate local development of distributed systems, by allowing normal HTTP clients that assume TCP (cURL, browsers, etc.) to address localhost servers via semantically-meaningful subdomains rather than opaque port numbers.

For example, rather than addressing your application server as localhost:8081 and your Prometheus instance as localhost:9090, you could use

http://myapp.unixproxy.localhost
http://prometheus.unixproxy.localhost

Or, you could have 3 clusters of 3 instances each, addressed as

http://{nyc,lax,fra}.{1,2,3}.unixproxy.localhost

The intermediating reverse-proxy, provided by Handler, works dynamically, without any explicit configuration. See documentation on that type for usage information.

Application servers need to be able to listen on Unix sockets. The ParseURI and ListenURI helpers exist for this purpose. They accept both typical listen addresses e.g. "localhost:8081" or ":8081" as well as e.g. "unix:///tmp/my.sock" as input. Applications can use these helpers to create listeners, and bind HTTP servers to those listeners, rather than using default helpers that assume TCP, like http.ListenAndServe.

cmd/unixproxy is an example program utilizing package unixproxy.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ListenURI

func ListenURI(ctx context.Context, uri string) (net.Listener, error)

ListenURI is a helper function that parses the provided URI via ParseURI, and returns a net.Listener listening on the parsed network and address.

func NewDNSServer added in v0.0.3

func NewDNSServer(addr string, logger *log.Logger) *dns.Server

NewDNSServer returns a DNS server which will listen on addr, and resolve all incoming A, AAAA, and HTTPS requests to localhost. Specifically, it resolves all A and HTTPS queries to the IPv4 address 127.0.0.1, and all AAAA queries to the IPv6 address ::1. It ignores all other request types.

A nil logger parameter is valid and will result in no log output.

This is intended for use on macOS systems, where many applications (including Safari and cURL) perform DNS lookups through a system resolver that ignores /etc/hosts. As a workaround, users can run this (limited) DNS resolver on a specific local port, and configure the system resolver to use it when resolving hosts matching the relevant host string.

Assuming the default host of unixproxy.localhost, and assuming this resolver runs on 127.0.0.1:5354, create /etc/resolver/localhost with the following content.

nameserver 127.0.0.1
port 5354

Then e.g. Safari will resolve any URL ending in .localhost by querying the resolver running on 127.0.0.1:5354. See `man 5 resolver` for more information on the /etc/resolver file format.

func ParseURI

func ParseURI(uri string) (network, address string, _ error)

ParseURI parses the given URI to a network and address that can be passed to e.g. net.Listen.

The URI scheme is interpreted as the network, and the host (and port) are interpreted as the address. For example, "tcp://:80" is parsed to a network of "tcp" and an address of ":80", and "unix:///tmp/my.sock" is parsed to a network of "unix" and an address of "/tmp/my.sock".

If the URI doesn't have a scheme, "tcp://" is assumed by default, in an attempt to keep basic compatibilty with common listen addresses like "localhost:8080" or ":9090".

Types

type Handler

type Handler struct {
	// Root is a valid directory on the local filesystem. The handler will look
	// in this directory tree, recursively, for destination Unix sockets, when
	// proxying an incoming request. See [Handler] for more detail.
	//
	// Required.
	Root string

	// Host is the base/apex domain which the Handler expects to receive as part
	// of all request Host headers. It should end in .localhost per RFC2606, and
	// the system should resolve that domain, and all subdomains, to a localhost
	// IP. Typically, this is done by adding an entry to /etc/hosts as follows.
	//
	//  127.0.0.1   localhost # note: separator must be a literal tab
	//
	// Modern macOS systems will ignore /etc/hosts in many contexts, see
	// [NewDNSServer] for a workaround.
	//
	// Optional. The default value is "unixproxy.localhost".
	Host string

	// ErrorLogWriter is used as the destination writer for the ErrorLog of the
	// [http.ReverseProxy] used to proxy individual requests.
	//
	// Optional. By default, each [http.ReverseProxy] has a nil ErrorLog.
	ErrorLogWriter io.Writer
	// contains filtered or unexported fields
}

Handler is a reverse proxy to Unix sockets on the local filesystem.

Requests are mapped to sockets based on their Host header. Each sub-domain element underneath the configured Host domain is parsed as a filepath element relative to Root directory. If the resulting filepath identifies a valid Unix socket, the request is proxied to that socket.

As an example, a Handler configured with Host "unixproxy.localhost" and Root "/tmp/abc" would map a request with Host header "foo.bar.unixproxy.localhost" to a socket at "/tmp/abc/foo/bar".

Parameters are evaluated during ServeHTTP.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements http.Handler. If the request Host header is equal to the Host field (i.e. has no subdomains), ServeHTTP will serve a list of valid subdomains. Otherwise, the request will be proxied to a local Unix domain socket based on its subdomain.

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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