httptunnel

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Jan 7, 2025 License: BSD-2-Clause Imports: 17 Imported by: 0

README

Easy HTTP Tunneling

What does it do?

The goal is to make it easy to tunnel through http(s).

Why was it made?

Not a new concept, but I had wanted to see how easy this would be. Parts of the underlying library were copy/pasted from github.com/gorilla/websocket (almost everything in helpers.go). I think there could be other advantages to tunneling established protocols over http as well.

Take ssh, for example. By tunneling ssh over http you:

  • Make it less clear that ssh is available (since it goes through port 80/443 instead of a different port)
  • Close one more port on your firewall
  • Can use http middlewares to some degree
  • Can easily make urls dynamic (maybe like one-time passwords, but instead urls for connections)
  • Ensure you are connecting to the correct (https) server with Domain Validation (or better) certificates

Try it yourself

$ go get -u github.com/TylerZeroMaster/httptunnel

See httpssh for a full example.

Where to next?

This is probably the end. If I did continue, I would probably

  • Work on improving the options for the dialer/hijacker. Ideally, more boilerplate code could be kept in these standard implementations and options, or some other mechanism, could be fleshed out for more customization.
  • Fix some of the minor issues that exist in the examples (no show stoppers that I am aware of)
  • Get to 100% test coverage (currently around 80%)

Documentation

Index

Constants

View Source
const Version = "0.1.1"

Variables

View Source
var DefaultDialer = &Dialer{
	Proxy:            http.ProxyFromEnvironment,
	HandshakeTimeout: 45 * time.Second,
}
View Source
var ErrBadOrigin = errors.New("httptunnel: request origin not allowed by HijackOptions.checkOrigin")
View Source
var License = `
=====================================
github.com/TylerZeroMaster/httptunnel
=====================================

` + license + `
============================
github.com/gorilla/websocket
============================
` + gorillaWebsocketsLicense

Functions

This section is empty.

Types

type ConnectionOptions

type ConnectionOptions struct {
	OverrideGetUrl    func(string) (*url.URL, error)
	PrepareRequest    func(r *http.Request) error
	OverrideNewReader func(net.Conn) (*bufio.Reader, error)
}

func (ConnectionOptions) GetUrl

func (opts ConnectionOptions) GetUrl(urlString string) (*url.URL, error)

func (ConnectionOptions) NewReader

func (opts ConnectionOptions) NewReader(conn net.Conn) (*bufio.Reader, error)

type Dialer

type Dialer struct {
	// NetDial specifies the dial function for creating TCP connections. If
	// NetDial is nil, net.Dialer DialContext is used.
	NetDial func(network, addr string) (net.Conn, error)

	// NetDialContext specifies the dial function for creating TCP connections. If
	// NetDialContext is nil, NetDial is used.
	NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)

	// NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If
	// NetDialTLSContext is nil, NetDialContext is used.
	// If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and
	// TLSClientConfig is ignored.
	NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)

	// Proxy specifies a function to return a proxy for a given
	// Request. If the function returns a non-nil error, the
	// request is aborted with the provided error.
	// If Proxy is nil or returns a nil *URL, no proxy is used.
	Proxy func(*http.Request) (*url.URL, error)

	// TLSClientConfig specifies the TLS configuration to use with tls.Client.
	// If nil, the default configuration is used.
	// If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake
	// is done there and TLSClientConfig is ignored.
	TLSClientConfig *tls.Config

	// HandshakeTimeout specifies the duration for the handshake to complete.
	HandshakeTimeout time.Duration

	// ReadBufferSize and WriteBufferSize specify I/O buffer sizes in bytes. If a buffer
	// size is zero, then a useful default size is used. The I/O buffer sizes
	// do not limit the size of the messages that can be sent or received.
	ReadBufferSize, WriteBufferSize int

	// Jar specifies the cookie jar.
	// If Jar is nil, cookies are not sent in requests and ignored
	// in responses.
	Jar http.CookieJar
}

A Dialer contains options for connecting to an http tunneling server.

It is safe to call Dialer's methods concurrently.

func (*Dialer) Dial

func (d *Dialer) Dial(
	urlStr string,
	options *ConnectionOptions,
) (net.Conn, *bufio.Reader, *http.Response, error)

Dial creates a new client connection by calling DialContext with a background context.

func (*Dialer) DialContext

func (d *Dialer) DialContext(
	ctx context.Context,
	urlStr string,
	options *ConnectionOptions,
) (net.Conn, *bufio.Reader, *http.Response, error)

DialContext creates a new client connection. Use ConnectionOptions.PrepareRequest to customize the request before it is sent.

The context will be used in the request and in the Dialer.

type Hijacker

type Hijacker struct {
	// Customize handling of http request
	// Useful if you want to embed some reusable validation into the hijacker
	OverrideHandleRequest func(*http.Request) error
	// Customize how origin is checked.
	// Default behavior is to ignore origin if the header is unset, otherwise
	// check that host matches between header and url
	OverrideCheckOrigin func(*http.Request) error
}

Define a Hijacker for later use while handling a request

func (Hijacker) Hijack

Hijack the underlying TCP connection

Jump to

Keyboard shortcuts

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