use DuckDNS for demo
This commit is contained in:
parent
5a68908e66
commit
776aabf879
|
@ -13,10 +13,11 @@ import (
|
|||
// The Config struct holds all of the information needed to establish and handle a connection
|
||||
// with the RVPN server.
|
||||
type Config struct {
|
||||
Server string
|
||||
Token string
|
||||
Insecure bool
|
||||
Services RouteMap
|
||||
Server string
|
||||
Token string
|
||||
Insecure bool
|
||||
Services RouteMap
|
||||
TLSConfig *tls.Config
|
||||
}
|
||||
|
||||
// Run establishes a connection with the RVPN server specified in the config. If the first attempt
|
||||
|
@ -47,7 +48,7 @@ func Run(ctx context.Context, config *Config) error {
|
|||
return fmt.Errorf(`service %s missing port for "*"`, name)
|
||||
}
|
||||
}
|
||||
handler := NewWsHandler(config.Services)
|
||||
handler := NewWsHandler(config.Services, config.TLSConfig)
|
||||
|
||||
authenticated := false
|
||||
for {
|
||||
|
|
|
@ -2,6 +2,7 @@ package client
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -26,17 +27,19 @@ type WsHandler struct {
|
|||
|
||||
servicePorts RouteMap
|
||||
|
||||
ctx context.Context
|
||||
dataChan chan *packer.Packer
|
||||
ctx context.Context
|
||||
dataChan chan *packer.Packer
|
||||
tlsConfig *tls.Config
|
||||
}
|
||||
|
||||
// NewWsHandler creates a new handler ready to be given a websocket connection. The services
|
||||
// argument specifies what port each service type should be directed to on the local interface.
|
||||
func NewWsHandler(services RouteMap) *WsHandler {
|
||||
h := new(WsHandler)
|
||||
h.servicePorts = services
|
||||
h.localConns = make(map[string]net.Conn)
|
||||
return h
|
||||
func NewWsHandler(services RouteMap, tlsConfig *tls.Config) *WsHandler {
|
||||
return &WsHandler{
|
||||
servicePorts: services,
|
||||
localConns: make(map[string]net.Conn),
|
||||
tlsConfig: tlsConfig,
|
||||
}
|
||||
}
|
||||
|
||||
// HandleConn handles all of the traffic on the provided websocket connection. The function
|
||||
|
@ -81,7 +84,7 @@ func (h *WsHandler) HandleConn(ctx context.Context, conn *websocket.Conn) {
|
|||
}
|
||||
}
|
||||
|
||||
func (h *WsHandler) writeRemote(conn *websocket.Conn) {
|
||||
func (h *WsHandler) writeRemote(wsconn *websocket.Conn) {
|
||||
defer h.closeConnections()
|
||||
defer func() { h.dataChan = nil }()
|
||||
|
||||
|
@ -94,13 +97,13 @@ func (h *WsHandler) writeRemote(conn *websocket.Conn) {
|
|||
// all errors if it doesn't work.
|
||||
message := websocket.FormatCloseMessage(websocket.CloseGoingAway, "closing connection")
|
||||
deadline := time.Now().Add(10 * time.Second)
|
||||
conn.WriteControl(websocket.CloseMessage, message, deadline)
|
||||
conn.Close()
|
||||
wsconn.WriteControl(websocket.CloseMessage, message, deadline)
|
||||
wsconn.Close()
|
||||
return
|
||||
|
||||
case p := <-h.dataChan:
|
||||
packed := p.PackV1()
|
||||
conn.WriteMessage(websocket.BinaryMessage, packed.Bytes())
|
||||
wsconn.WriteMessage(websocket.BinaryMessage, packed.Bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +142,7 @@ func (h *WsHandler) getLocalConn(p *packer.Packer) net.Conn {
|
|||
}
|
||||
|
||||
var hostname string
|
||||
//var terminate bool
|
||||
if service == "http" {
|
||||
if match := hostRegexp.FindSubmatch(p.Data.Data()); match != nil {
|
||||
hostname = strings.Split(string(match[1]), ":")[0]
|
||||
|
@ -146,6 +150,7 @@ func (h *WsHandler) getLocalConn(p *packer.Packer) net.Conn {
|
|||
}
|
||||
} else if service == "https" {
|
||||
hostname, _ = sni.GetHostname(p.Data.Data())
|
||||
//terminate = true
|
||||
} else {
|
||||
hostname = "*"
|
||||
}
|
||||
|
@ -176,7 +181,14 @@ func (h *WsHandler) getLocalConn(p *packer.Packer) net.Conn {
|
|||
return nil
|
||||
}
|
||||
|
||||
h.localConns[key] = conn
|
||||
rconn := conn
|
||||
/*
|
||||
if terminate {
|
||||
rconn = tls.Server(conn, h.tlsConfig)
|
||||
//rconn = tls.Client(conn, h.tlsConfig)
|
||||
}
|
||||
*/
|
||||
h.localConns[key] = rconn
|
||||
loginfo.Printf("new client %q for %s:%d (%d clients)\n", key, hostname, term.Port, len(h.localConns))
|
||||
go h.readLocal(key, &p.Header)
|
||||
return conn
|
||||
|
@ -190,6 +202,7 @@ func (h *WsHandler) writeLocal(p *packer.Packer) {
|
|||
}
|
||||
|
||||
if p.Service() == "error" || p.Service() == "end" {
|
||||
// TODO XXX where's the opposite of this?
|
||||
conn.Close()
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
|
@ -12,7 +13,9 @@ import (
|
|||
|
||||
"git.coolaj86.com/coolaj86/go-telebitd/client"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
"github.com/go-acme/lego/v3/providers/dns/duckdns"
|
||||
|
||||
_ "github.com/joho/godotenv/autoload"
|
||||
)
|
||||
|
@ -264,17 +267,99 @@ func main() {
|
|||
ctx, quit := context.WithCancel(context.Background())
|
||||
defer quit()
|
||||
|
||||
acmeStorage := "./acme.d/"
|
||||
acmeEmail := ""
|
||||
acmeStaging := false
|
||||
//
|
||||
// CertMagic is Greenlock for Go
|
||||
//
|
||||
directory := certmagic.LetsEncryptProductionCA
|
||||
if acmeStaging {
|
||||
directory = certmagic.LetsEncryptStagingCA
|
||||
}
|
||||
magic, err := newCertMagic(directory, acmeEmail, &certmagic.FileStorage{Path: acmeStorage})
|
||||
if nil != err {
|
||||
fmt.Fprintf(os.Stderr, "failed to initialize certificate management (discovery url? local folder perms?): %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
GetCertificate: func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||
return magic.GetCertificate(hello)
|
||||
/*
|
||||
if false {
|
||||
_, _ = magic.GetCertificate(hello)
|
||||
}
|
||||
|
||||
// TODO
|
||||
// 1. call out to greenlock for validation
|
||||
// 2. push challenges through http channel
|
||||
// 3. receive certificates (or don't)
|
||||
certbundleT, err := tls.LoadX509KeyPair("certs/fullchain.pem", "certs/privkey.pem")
|
||||
certbundle := &certbundleT
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return certbundle, nil
|
||||
*/
|
||||
},
|
||||
}
|
||||
|
||||
config := client.Config{
|
||||
Insecure: insecure,
|
||||
Server: relay,
|
||||
Services: servicePorts,
|
||||
Token: token,
|
||||
Insecure: insecure,
|
||||
Server: relay,
|
||||
Services: servicePorts,
|
||||
Token: token,
|
||||
TLSConfig: tlsConfig,
|
||||
}
|
||||
|
||||
fmt.Printf("config:\n%#v\n", config)
|
||||
log.Fatal(client.Run(ctx, &config))
|
||||
}
|
||||
|
||||
func newCertMagic(directory string, email string, storage certmagic.Storage) (*certmagic.Config, error) {
|
||||
cache := certmagic.NewCache(certmagic.CacheOptions{
|
||||
GetConfigForCert: func(cert certmagic.Certificate) (*certmagic.Config, error) {
|
||||
// do whatever you need to do to get the right
|
||||
// configuration for this certificate; keep in
|
||||
// mind that this config value is used as a
|
||||
// template, and will be completed with any
|
||||
// defaults that are set in the Default config
|
||||
return &certmagic.Config{}, nil
|
||||
},
|
||||
})
|
||||
provider, err := newDuckDNSProvider(os.Getenv("DUCKDNS_TOKEN"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
magic := certmagic.New(cache, certmagic.Config{
|
||||
Storage: storage,
|
||||
OnDemand: &certmagic.OnDemandConfig{
|
||||
DecisionFunc: func(name string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
})
|
||||
// Ummm... just a little confusing
|
||||
magic.Issuer = certmagic.NewACMEManager(magic, certmagic.ACMEManager{
|
||||
DNSProvider: provider,
|
||||
CA: directory,
|
||||
Email: email,
|
||||
Agreed: true,
|
||||
DisableHTTPChallenge: true,
|
||||
DisableTLSALPNChallenge: true,
|
||||
// plus any other customizations you need
|
||||
})
|
||||
return magic, nil
|
||||
}
|
||||
|
||||
// newDuckDNSProvider is for the sake of demoing the tunnel
|
||||
func newDuckDNSProvider(token string) (*duckdns.DNSProvider, error) {
|
||||
config := duckdns.NewDefaultConfig()
|
||||
config.Token = token
|
||||
return duckdns.NewDNSProviderConfig(config)
|
||||
}
|
||||
|
||||
func stringSlice(csv string) []string {
|
||||
list := []string{}
|
||||
for _, item := range strings.Split(csv, ", ") {
|
||||
|
|
|
@ -332,6 +332,7 @@ func (mx *MPlexy) routeToTarget(ctx context.Context, extConn *tunnel.WedgeConn,
|
|||
}
|
||||
|
||||
for {
|
||||
fmt.Println("xxyyzz buffer")
|
||||
buffer, err := extConn.PeekAll()
|
||||
if err != nil {
|
||||
loginfo.Println("unable to peekAll", err)
|
||||
|
|
Loading…
Reference in New Issue