gated

package module
v0.0.0-...-1c66c14 Latest Latest
Warning

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

Go to latest
Published: Sep 14, 2022 License: MIT Imports: 30 Imported by: 0

README

gated

Go Report Card

What for

gated is a decentralized system that allows user to access multiple hosts in different LANs by creating a global virtual domain on a HTTP proxy server. I personally use it to easily and securely access any service on my router/raspberry pi/server in different locations.

Each peer can publish some virtual host names (which are aliases of some local IP addresses or real host names) in a global virtual domain, then any peer will be able to connect to this host via the virtual host name.

When a network failure occurs, some peers can't be directly connected, and gated may automatically choose a third peer that can reach both peers at the same time to forward the traffic.

Peers without public IP address can also publish local services. In this case, a reverse proxy will be performed automatically.

For now, this tool is only designed to handle small clusters.

Traffic over untrusted network is carried by multiplexed mTLS tunnels.

      Trusted     |   Untrusted   |     Trusted
                              +-------+    +-------+
                         +-1->| gated |-n->| Peer2 |
                         |    +-------+    +-------+
+-------+    +-------+   |    +-------+    +-------+
| Peer1 |-n->| gated |---+-1->| gated |-n->| Peer3 |
+-------+    +-------+   |    +-------+    +-------+
                         |    +-------+    +-------+
                         +-1->| gated |-n->| Peer4 |
                              +-------+    +-------+

Protocol Stack

+-------------------------------+
|          HTTP Proxy           |
+-------------------------------+
|   yamux stream multiplexing   |
+-------------------------------+
|        mutual TLS 1.3         |
+-------------------------------+
|  TCP/IP (untrusted network)   |
+-------------------------------+

Authentication Model

Like SSH, each peer needs to generate a key pair(certificate + private key). Only certificates in a peer's authorized certificates list can communicate with this peer.

This behavior is based on golang's mutual TLS 1.3 implementation.

By default, all certificates are self-signed. This will not reduce security.

Quick Start

1. Generate new self-signed certificates with OpenSSL (or you may use existing ones):
./gencerts.sh peer1 peer2

gencerts.sh is in cmd/gated

2. Create "config.json" per peer
Peer1 (with public IP address 203.0.113.1)
{
    "name": "peer1",
    "listen": ":50100",
    "addr": "203.0.113.1:50100",
    "httplisten": "192.168.123.1:8080",
    "hosts": {
        "server.lan": "127.0.0.1"
    },
    "auth": {
        "cert": "peer1-cert.pem",
        "key": "peer1-key.pem",
        "authcerts": [
            "peer2-cert.pem"
        ]
    }
}
Peer2 (without public IP address)
{
    "name": "peer2",
    "httplisten": ":8080",
    "servers": [
        {
            "addr": "203.0.113.1:50100"
        }
    ],
    "hosts": {
        "router.peer2.lan": "192.168.1.1",
        "peer2.lan": "192.168.1.2"
    },
    "auth": {
        "cert": "peer2-cert.pem",
        "key": "peer2-key.pem",
        "authcerts": [
            "peer1-cert.pem"
        ]
    }
}
Options
  • "name": peer name
  • "listen": listen address for other peers
  • "addr": advertised address for other peers to connect
  • "httplisten": listen address of the local HTTP proxy
  • "servers": bootstrap server info
  • "servers[*].addr": bootstrap server address
  • "hosts": local hosts
  • "hosts[name]": host LAN address
  • "cert": peer certificate
  • "key": peer private key
  • "authcerts": peer authorized certificates list, bundles are supported

see source code for complete document

see config.json for example config file

3. Start
./gated -c config.json

You may also found the systemd user unit gated.service is useful.

4. Use

Check http://api.gated.lan/status over the HTTP proxy for service status.

Build/Install

# get source code
git clone https://github.com/hexian000/gated.git
cd gated
# build for native system
./make.sh

or

go install github.com/hexian000/gated/cmd/gated@latest

Credits

Documentation

Index

Constants

View Source
const (
	PathStatus  = "/status"
	PathCluster = "/cluster"
	PathRPC     = "/v1/rpc"
)

Variables

View Source
var ErrUnsupportedTransferEncoding = errors.New("unsupported transfer encoding")

Functions

func Int64Log2

func Int64Log2(x uint64) int

Types

type Config

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

func NewConfig

func NewConfig(cfg *config.Main) (*Config, error)

func (*Config) CacheTimeout

func (c *Config) CacheTimeout() time.Duration

func (*Config) Current

func (c *Config) Current() *config.Main

func (*Config) GetFQDN

func (c *Config) GetFQDN(host string) string

func (*Config) Load

func (c *Config) Load(cfg *config.Main) error

func (*Config) MuxConfig

func (c *Config) MuxConfig(tag string) *yamux.Config

func (*Config) SetConnParams

func (c *Config) SetConnParams(conn net.Conn)

func (*Config) TLSConfig

func (c *Config) TLSConfig(sni string) *tls.Config

func (*Config) Timeout

func (c *Config) Timeout() time.Duration

func (*Config) Timestamp

func (c *Config) Timestamp() int64

type RPC

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

func (*RPC) Bootstrap

func (r *RPC) Bootstrap(args *proto.Cluster, reply *proto.Cluster) error

func (*RPC) Lookup

func (r *RPC) Lookup(args *proto.Lookup, reply *proto.Lookup) error

func (*RPC) Update

func (r *RPC) Update(args *proto.Cluster, reply *proto.Cluster) error

type Resolver

type Resolver interface {
	Resolve(host string) (*url.URL, error)
	Proxy(req *http.Request) (*url.URL, error)
}

type Router

type Router struct {
	*http.Transport
	// contains filtered or unexported fields
}

func NewRouter

func NewRouter(server *Server) *Router

func (*Router) CollectMetrics

func (r *Router) CollectMetrics(w *bufio.Writer)

func (*Router) DialContext

func (r *Router) DialContext(ctx context.Context, network, addr string) (net.Conn, error)

func (*Router) Proxy

func (r *Router) Proxy(req *http.Request) (*url.URL, error)

func (*Router) Resolve

func (r *Router) Resolve(host string) (*url.URL, error)

func (*Router) Routes

func (r *Router) Routes() map[string]string

func (*Router) UpdateProxy

func (r *Router) UpdateProxy(destination string)

type Server

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

func NewServer

func NewServer(cfg *Config) *Server

func (*Server) BootstrapFromConfig

func (s *Server) BootstrapFromConfig()

func (*Server) Broadcast

func (s *Server) Broadcast(ctx context.Context, method, except string, mayDial bool, args interface{}, replyType reflect.Type) <-chan rpcResult

func (*Server) ClusterInfo

func (s *Server) ClusterInfo() *proto.Cluster

func (*Server) CollectMetrics

func (s *Server) CollectMetrics(w *bufio.Writer)

func (*Server) DialPeerContext

func (s *Server) DialPeerContext(ctx context.Context, peer string) (net.Conn, error)

func (*Server) FindProxy

func (s *Server) FindProxy(peer string, tryDirect, fast bool) (string, error)

func (*Server) LocalPeerName

func (s *Server) LocalPeerName() string

func (*Server) MergeCluster

func (s *Server) MergeCluster(cluster *proto.Cluster) bool

func (*Server) OnPeerLost

func (s *Server) OnPeerLost(p *peer)

func (*Server) Serve

func (s *Server) Serve(l net.Listener)

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

func (*Server) Start

func (s *Server) Start() error

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

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