derpnet

package module
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Feb 5, 2024 License: MIT Imports: 19 Imported by: 2

README

DerpNET

(Ab)using Tailscale's DERP servers to connect any two machines without a Tailscale account.

Tailscale operates many DERP servers which implement the DERP protocol. DERP servers support routing a packet to any client connected to the same DERP server using their curve25519 address.

We (ab)use this routing to implement UDP-like connections through DERP server. Instead of IP addresses, we use curve25519 public keys as the address. TCP-like stream semantics are added by running QUIC on top of the UDP-like connection.

This project is not affiliated with Tailscale in any way. I've used it to connect to small HTTP servers on my personal machine. It is not optimized for high bandwidth.

Usage

To install the binary, run:
go install github.com/ntnj/derpnet/cmd/derpconnect@latest

Find a DERP server closest to you from here. Use it as the value of --derp flags in the commands below.

To expose a port running on a server:
derpconnect --derp=... serve <port>
The above command will print a public key, which you can use on different client machine.

On a client machine, run:
derpconnect --derp=... join <pubkey> <listen_port>
This will start listening on <listen_port>, and any connections to that port are forwarded to <port> on the server.

Use as a library

To get a UDP like connection, you can use derpnet.ListenPacket, which is similar to net.ListenPacket function:

import github.com/ntnj/derpnet

conn, err := derpnet.ListenPacket("<derp>.tailscale.com", <privatekeybytes>)

n, err := conn.WriteTo(<msg>, <pubkeybytes>)

n, addr, err := conn.ReadFrom(<bytes>)

TCP-like semantics are added based on QUIC streams implemented with quic-go.

On server side:

import github.com/ntnj/derpnet/derpquic

l, err := derpquic.Listen("<derp>.tailscale.com", <privatekeybytes>)

for {
    conn, err := l.Accept()
    // conn implements net.Conn
}

On the client:

import github.com/ntnj/derpnet/derpquic

d, err := derpquic.NewDialer("<derp>.tailscale.com", <privatekeybytes>)

conn, err := d.Dial(<pubkeybytes>)
// conn implements net.Conn
Caveats
  • It doesn't attempt to establish P2P connections like Tailscale does, so will be limited by DERP server's bandwidth and latency.
  • quic-go doesn't currently allow setting configurable packet size and uses a default of 1200, which causes a large amount of packets to be sent to DERP server for connections sending a lot of data.
  • It doesn't currently handle reconnecting to DERP server in case the connection to the DERP server drops.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Debug = false

Functions

func ListenPacket

func ListenPacket(derpURL string, key Key) (net.PacketConn, error)

ListenPacket connects to a DERP server URL with the provided private key. It returns net.PacketConn derpURL should be a valid server name compatible with the Tailscale's DERP protocol. key should have a length of 32 bytes

Types

type Addr

type Addr []byte

Addr implements net.Addr, and represents the public addr of the connection.

func (Addr) EncodedString

func (a Addr) EncodedString() string

func (Addr) Network

func (Addr) Network() string

Network implements net.Addr.

func (Addr) String

func (a Addr) String() string

String implements net.Addr.

type Key

type Key []byte

func GenerateKey

func GenerateKey() (Key, error)

func (Key) Bytes

func (k Key) Bytes() []byte

func (Key) IsValid

func (k Key) IsValid() bool

func (Key) PublicKey

func (k Key) PublicKey() (PublicKey, error)

type ListenConfig

type ListenConfig struct{}

func (*ListenConfig) ListenPacket

func (lc *ListenConfig) ListenPacket(ctx context.Context, derpURL string, key Key) (net.PacketConn, error)

ListenPacket connects to a DERP server URL with the provided private key.

type PacketConn

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

PacketConn implements net.PacketConn.

func (*PacketConn) Close

func (c *PacketConn) Close() error

Close implements net.PacketConn.

func (*PacketConn) LocalAddr

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

LocalAddr implements net.PacketConn.

func (*PacketConn) ReadFrom

func (c *PacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error)

ReadFrom implements net.PacketConn.

func (*PacketConn) SetDeadline

func (*PacketConn) SetDeadline(t time.Time) error

SetDeadline implements net.PacketConn.

func (*PacketConn) SetReadDeadline

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

SetReadDeadline implements net.PacketConn.

func (*PacketConn) SetWriteDeadline

func (*PacketConn) SetWriteDeadline(t time.Time) error

SetWriteDeadline implements net.PacketConn.

func (*PacketConn) WriteTo

func (c *PacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error)

WriteTo implements net.PacketConn.

type PublicKey

type PublicKey []byte

func (PublicKey) Bytes

func (p PublicKey) Bytes() []byte

Directories

Path Synopsis
cmd
derpconnect Module
derpquic module

Jump to

Keyboard shortcuts

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