add client connection whitelist
This commit is contained in:
parent
b8cf135c45
commit
e47ecba665
|
@ -21,6 +21,7 @@ import (
|
||||||
telebit "git.rootprojects.org/root/telebit"
|
telebit "git.rootprojects.org/root/telebit"
|
||||||
"git.rootprojects.org/root/telebit/dbg"
|
"git.rootprojects.org/root/telebit/dbg"
|
||||||
tbDns01 "git.rootprojects.org/root/telebit/dns01"
|
tbDns01 "git.rootprojects.org/root/telebit/dns01"
|
||||||
|
"git.rootprojects.org/root/telebit/iplist"
|
||||||
"git.rootprojects.org/root/telebit/mgmt"
|
"git.rootprojects.org/root/telebit/mgmt"
|
||||||
"git.rootprojects.org/root/telebit/mgmt/authstore"
|
"git.rootprojects.org/root/telebit/mgmt/authstore"
|
||||||
"git.rootprojects.org/root/telebit/table"
|
"git.rootprojects.org/root/telebit/table"
|
||||||
|
@ -81,6 +82,7 @@ func main() {
|
||||||
var forwards []Forward
|
var forwards []Forward
|
||||||
var portForwards []Forward
|
var portForwards []Forward
|
||||||
|
|
||||||
|
spfDomain := flag.String("spf-domain", "", "domain with SPF-like list of IP addresses which are allowed to connect to clients")
|
||||||
// TODO replace the websocket connection with a mock server
|
// TODO replace the websocket connection with a mock server
|
||||||
vendorID := flag.String("vendor-id", "", "a unique identifier for a deploy target environment")
|
vendorID := flag.String("vendor-id", "", "a unique identifier for a deploy target environment")
|
||||||
email := flag.String("acme-email", "", "email to use for Let's Encrypt / ACME registration")
|
email := flag.String("acme-email", "", "email to use for Let's Encrypt / ACME registration")
|
||||||
|
@ -107,6 +109,14 @@ func main() {
|
||||||
dbg.Debug = *verbose
|
dbg.Debug = *verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spfRecords := iplist.Init(*spfDomain)
|
||||||
|
if len(spfRecords) > 0 {
|
||||||
|
fmt.Println(
|
||||||
|
"Allow client connections from:",
|
||||||
|
strings.Join(spfRecords, " "),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if len(os.Args) >= 2 {
|
if len(os.Args) >= 2 {
|
||||||
if "version" == os.Args[1] {
|
if "version" == os.Args[1] {
|
||||||
fmt.Printf("telebit %s %s %s\n", GitVersion, GitRev[:7], GitTimestamp)
|
fmt.Printf("telebit %s %s %s\n", GitVersion, GitRev[:7], GitTimestamp)
|
||||||
|
@ -477,8 +487,6 @@ func muxAll(
|
||||||
fmt.Println(msg)
|
fmt.Println(msg)
|
||||||
mux.ForwardTCP(fwd.pattern, "localhost:"+fwd.port, 120*time.Second, msg, "[Port Forward]")
|
mux.ForwardTCP(fwd.pattern, "localhost:"+fwd.port, 120*time.Second, msg, "[Port Forward]")
|
||||||
}
|
}
|
||||||
// TODO close connection on invalid hostname
|
|
||||||
mux.HandleTCP("*", telebit.HandlerFunc(routeSubscribersAndClients), "[Tun => Remote Servers]")
|
|
||||||
|
|
||||||
if 0 == len(*apiHostname) {
|
if 0 == len(*apiHostname) {
|
||||||
*apiHostname = os.Getenv("API_HOSTNAME")
|
*apiHostname = os.Getenv("API_HOSTNAME")
|
||||||
|
@ -506,6 +514,9 @@ func muxAll(
|
||||||
}), "[Admin API & Server Relays]")
|
}), "[Admin API & Server Relays]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO close connection on invalid hostname
|
||||||
|
mux.HandleTCP("*", telebit.HandlerFunc(routeSubscribersAndClients), "[Tun => Remote Servers]")
|
||||||
|
|
||||||
if nil != grants {
|
if nil != grants {
|
||||||
for i, domainname := range grants.Domains {
|
for i, domainname := range grants.Domains {
|
||||||
fmt.Printf("[%d] Will decrypt remote requests to %q\n", i, domainname)
|
fmt.Printf("[%d] Will decrypt remote requests to %q\n", i, domainname)
|
||||||
|
@ -544,7 +555,7 @@ func routeSubscribersAndClients(client net.Conn) error {
|
||||||
case *telebit.ConnWrap:
|
case *telebit.ConnWrap:
|
||||||
wconn = conn
|
wconn = conn
|
||||||
default:
|
default:
|
||||||
panic("HandleTun is special in that it must receive &ConnWrap{ Conn: conn }")
|
panic("routeSubscribersAndClients is special in that it must receive &ConnWrap{ Conn: conn }")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We know this to be two parts "ip:port"
|
// We know this to be two parts "ip:port"
|
||||||
|
@ -618,6 +629,32 @@ func tryToServeName(servername string, wconn *telebit.ConnWrap) bool {
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// Note: timing can reveal if the client exists
|
||||||
|
|
||||||
|
if allowAll, _ := iplist.IsAllowed(nil); !allowAll {
|
||||||
|
addr := wconn.RemoteAddr()
|
||||||
|
if nil == addr {
|
||||||
|
// handled by denial
|
||||||
|
wconn.Close()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteAddr := addr.String()
|
||||||
|
if "127.0.0.1" != remoteAddr &&
|
||||||
|
"::1" != remoteAddr &&
|
||||||
|
"localhost" != remoteAddr {
|
||||||
|
ipAddr := net.ParseIP(remoteAddr)
|
||||||
|
if nil == ipAddr {
|
||||||
|
wconn.Close()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok, err := iplist.IsAllowed(ipAddr); !ok || nil != err {
|
||||||
|
wconn.Close()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// async so that the call stack can complete and be released
|
// async so that the call stack can complete and be released
|
||||||
//srv.clients.Store(wconn.LocalAddr().String(), wconn)
|
//srv.clients.Store(wconn.LocalAddr().String(), wconn)
|
||||||
|
|
|
@ -92,6 +92,9 @@ func IsAllowed(remoteIP net.IP) (bool, error) {
|
||||||
if 0 == len(fields) {
|
if 0 == len(fields) {
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
if nil == remoteIP {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
for _, section := range fields {
|
for _, section := range fields {
|
||||||
parts := strings.Split(section, ":")
|
parts := strings.Split(section, ":")
|
||||||
|
|
|
@ -186,14 +186,16 @@ func (wsw *WebsocketTunnel) Close() error {
|
||||||
func (wsw *WebsocketTunnel) LocalAddr() net.Addr {
|
func (wsw *WebsocketTunnel) LocalAddr() net.Addr {
|
||||||
// TODO do we reverse this since the "local" address is that of the relay?
|
// TODO do we reverse this since the "local" address is that of the relay?
|
||||||
// return wsw.wsconn.RemoteAddr()
|
// return wsw.wsconn.RemoteAddr()
|
||||||
panic("no LocalAddr() implementation")
|
fmt.Fprintf(os.Stderr, "no LocalAddr() implementation\n")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoteAddr is not implemented and will panic. Additionally, it wouldn't mean anything useful anyway.
|
// RemoteAddr is not implemented and will panic. Additionally, it wouldn't mean anything useful anyway.
|
||||||
func (wsw *WebsocketTunnel) RemoteAddr() net.Addr {
|
func (wsw *WebsocketTunnel) RemoteAddr() net.Addr {
|
||||||
// TODO do we reverse this since the "remote" address means nothing / is that of one of the clients?
|
// TODO do we reverse this since the "remote" address means nothing / is that of one of the clients?
|
||||||
// return wsw.wsconn.LocalAddr()
|
// return wsw.wsconn.LocalAddr()
|
||||||
panic("no RemoteAddr() implementation")
|
fmt.Fprintf(os.Stderr, "no RemoteAddr() implementation\n")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDeadline sets the read and write deadlines associated
|
// SetDeadline sets the read and write deadlines associated
|
||||||
|
|
Loading…
Reference in New Issue