Skip to content

Commit

Permalink
Added TcpToTls, QuicToTls, TlsToQuic
Browse files Browse the repository at this point in the history
  • Loading branch information
opencoff committed Jul 3, 2020
1 parent 1e2c348 commit 9030d64
Show file tree
Hide file tree
Showing 4 changed files with 278 additions and 5 deletions.
8 changes: 4 additions & 4 deletions gotun/mocked_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,15 @@ func (s *tcpserver) accept() {
}

func (s *tcpserver) relay(fd net.Conn) {
there := fd.RemoteAddr().String()
there := fd.LocalAddr().String()
assert := newAsserter(s.t)
done := s.ctx.Done()
from := fmt.Sprintf("%s--%s", there, fd.LocalAddr().String())
from := fmt.Sprintf("%s--%s", there, fd.RemoteAddr().String())

defer func() {
s.wg.Done()
fd.Close()
s.t.Logf("mock tcp server: closed conn from %s\n", there)
s.t.Logf("mock tcp server: closed conn %s\n", from)
}()

s.t.Logf("mock tcp server: new conn from %s\n", there)
Expand All @@ -108,7 +108,7 @@ func (s *tcpserver) relay(fd net.Conn) {
assert(err == nil, "TLS handshake failed: %s", err)
fd = econn

s.t.Logf("mock tcp server: Upgraded %s to TLS\n", there)
s.t.Logf("mock tcp server: Upgraded %s to TLS\n", from)
}

buf := make([]byte, IOSIZE)
Expand Down
96 changes: 96 additions & 0 deletions gotun/quic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,102 @@ func TestQuicAuthToTcp(t *testing.T) {
log.Close()
}

// Client -> gotun Quic with client auth
// gotun -> backend TLS
func TestQuicAuthToTls(t *testing.T) {
assert := newAsserter(t)

pki, err := newPKI()
assert(err == nil, "can't create PKI: %s", err)

pkic, err := newPKI()
assert(err == nil, "can't create client PKI: %s", err)

clientCert, err := pkic.ClientCert("client.name")
assert(err == nil, "can't create client cert: %s", err)

spool := x509.NewCertPool()
spool.AddCert(pki.ca)

cpool := x509.NewCertPool()
cpool.AddCert(pkic.ca)

cfg := quicSetup(8020, 8021)
lc := cfg.Listen[0]

cert, err := pki.ServerCert("server.name", lc.Addr)
assert(err == nil, "can't create server cert: %s", err)

// config for quic server
qtlsCfg := &tls.Config{
MinVersion: tls.VersionTLS13,
ServerName: "server.name",
SessionTicketsDisabled: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,

// Best disabled, as they don't provide Forward Secrecy,
// but might be necessary for some clients
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
},
NextProtos: []string{"relay"},
RootCAs: spool,
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: cpool,
CurvePreferences: []tls.CurveID{
tls.CurveP256,
tls.X25519,
},
}

// mock TLS server config
stlsCfg := *qtlsCfg
stlsCfg.ClientAuth = tls.NoClientCert
stlsCfg.ClientCAs = nil

// gotun TLS client config
gtlsCfg := *qtlsCfg
gtlsCfg.Certificates = nil
gtlsCfg.ClientAuth = tls.NoClientCert
gtlsCfg.ClientCAs = nil

lc.serverCfg = qtlsCfg
lc.clientCfg = &gtlsCfg

// client quic config; we need the proper root and client certs
ctlsCfg := *qtlsCfg
ctlsCfg.Certificates = []tls.Certificate{clientCert}

// create a TLS server on the other end of a connector
s := newTcpServer("tcp", lc.Connect.Addr, &stlsCfg, t)
assert(s != nil, "server creation failed")

log := newLogger(t)
gt := NewServer(lc, cfg, log)
gt.Start()

// Now create a mock client to send data to mock server
c := newQuicClient("udp", lc.Addr, &ctlsCfg, t)
assert(c != nil, "client creation failed")

c.start(10)

assert(c.nw == s.nr, "i/o mismatch: client TX %d, server RX %d", c.nw, s.nr)
assert(c.nr == s.nw, "i/o mismatch: server TX %d, client RX %d", s.nw, c.nr)

c.stop()
s.stop()
gt.Stop()
log.Close()
}

// Client -> tcp
// gotun -> backend quic
func TestTcpToQuicAuth(t *testing.T) {
Expand Down
7 changes: 6 additions & 1 deletion gotun/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,12 @@ func (p *TCPServer) Start() {
go func() {
defer p.wg.Done()

p.log.Info("Starting TCP server ..")
if p.tls != nil {
p.log.Info("Starting TLS server ..")
} else {
p.log.Info("Starting TCP server ..")
}

p.log.Info("Ratelimit: Global %d req/s, Per-host: %d req/s",
p.Ratelimit.Global, p.Ratelimit.PerHost)

Expand Down
172 changes: 172 additions & 0 deletions gotun/tcp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,78 @@ func TestTcpToTcp(t *testing.T) {

lc := cfg.Listen[0]

pki, err := newPKI()
assert(err == nil, "can't create PKI: %s", err)

cert, err := pki.ServerCert("server.name", lc.Addr)
assert(err == nil, "can't create server cert: %s", err)

pool := x509.NewCertPool()
pool.AddCert(pki.ca)
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS13,
ServerName: "server.name",
SessionTicketsDisabled: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,

// Best disabled, as they don't provide Forward Secrecy,
// but might be necessary for some clients
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
},
RootCAs: pool,
Certificates: []tls.Certificate{cert},
ClientAuth: tls.NoClientCert,
CurvePreferences: []tls.CurveID{
tls.CurveP256,
tls.X25519,
},
}

// client config
ctlsCfg := *tlsCfg
ctlsCfg.Certificates = []tls.Certificate{}
lc.clientCfg = &ctlsCfg

// create a TLS server on the other end of a connector
s := newTcpServer("tcp", lc.Connect.Addr, tlsCfg, t)
assert(s != nil, "server creation failed")

gt := NewServer(lc, cfg, log)
gt.Start()

// Now create a mock client to send data to mock server
c := newTcpClient("tcp", lc.Addr, nil, t)
assert(c != nil, "client creation failed")

err = c.start(10)
assert(err == nil, "can't start tcp client: %s", err)

assert(c.nw == s.nr, "i/o mismatch: client TX %d, server RX %d", c.nw, s.nr)
assert(c.nr == s.nw, "i/o mismatch: server TX %d, client RX %d", s.nw, c.nr)

c.stop()
s.stop()
gt.Stop()
log.Close()
}

func TestTcpToTls(t *testing.T) {
assert := newAsserter(t)

// create a logger
log := newLogger(t)

cfg := testSetup(9010, 9011)

lc := cfg.Listen[0]

// create a server on the other end of a connector
s := newTcpServer("tcp", lc.Connect.Addr, nil, t)
assert(s != nil, "server creation failed")
Expand Down Expand Up @@ -222,6 +294,106 @@ func TestClientTlsToTcp(t *testing.T) {
log.Close()
}

// Client -> gotun TLS with client auth
// gotun -> backend Quic
func TestClientTlsToQuic(t *testing.T) {
assert := newAsserter(t)
log := newLogger(t)

pki, err := newPKI()
assert(err == nil, "can't create PKI: %s", err)

pkic, err := newPKI()
assert(err == nil, "can't create client PKI: %s", err)

clientCert, err := pkic.ClientCert("client.name")
assert(err == nil, "can't create client cert: %s", err)

spool := x509.NewCertPool()
spool.AddCert(pki.ca)

cpool := x509.NewCertPool()
cpool.AddCert(pkic.ca)

cfg := testSetup(9012, 9013)
lc := cfg.Listen[0]

cert, err := pki.ServerCert("server.name", lc.Addr)
assert(err == nil, "can't create server cert: %s", err)

tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS13,
ServerName: "server.name",
SessionTicketsDisabled: true,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305, // Go 1.8 only
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,

// Best disabled, as they don't provide Forward Secrecy,
// but might be necessary for some clients
// tls.TLS_RSA_WITH_AES_256_GCM_SHA384,
// tls.TLS_RSA_WITH_AES_128_GCM_SHA256,
},
RootCAs: spool,
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: cpool,
CurvePreferences: []tls.CurveID{
tls.CurveP256,
tls.X25519,
},
}

// mock quic server TLS config
mtlsCfg := *tlsCfg
mtlsCfg.ClientAuth = tls.NoClientCert
mtlsCfg.ClientCAs = nil
mtlsCfg.NextProtos = []string{"relay"}

// tls client config for gotun
qtlsCfg := *tlsCfg
qtlsCfg.ClientAuth = tls.NoClientCert
qtlsCfg.ClientCAs = nil
qtlsCfg.Certificates = nil
qtlsCfg.NextProtos = []string{"relay"}

lc.serverCfg = tlsCfg
lc.clientCfg = &qtlsCfg
lc.Connect.Quic = true

cfg.Dump(log)

// client TLS config; we need the proper root and client certs
ctlsCfg := *tlsCfg
ctlsCfg.Certificates = []tls.Certificate{clientCert}

// create a server on the other end of a connector
s := newQuicServer("tcp", lc.Connect.Addr, &mtlsCfg, t)
assert(s != nil, "server creation failed")

gt := NewServer(lc, cfg, log)
gt.Start()

// Now create a mock client to send data to mock server
c := newTcpClient("tcp", lc.Addr, &ctlsCfg, t)
assert(c != nil, "client creation failed")

err = c.start(10)
assert(err == nil, "can't start tls client: %s", err)

assert(c.nw == s.nr, "i/o mismatch: client TX %d, server RX %d", c.nw, s.nr)
assert(c.nr == s.nw, "i/o mismatch: server TX %d, client RX %d", s.nw, c.nr)

c.stop()
s.stop()
gt.Stop()
log.Close()
}

// Client -> gotun TLS with *bad* client auth
// gotun -> backend TCP
func TestClientBadTlsToTcp(t *testing.T) {
Expand Down

0 comments on commit 9030d64

Please sign in to comment.