tunneld: Add option to authenticate client certificate

This commit is contained in:
Riccardo Gori 2017-11-24 13:52:47 +01:00 committed by Michał Matczuk
parent 71d91b673e
commit b8005dd868
2 changed files with 33 additions and 7 deletions

View file

@ -41,6 +41,7 @@ type options struct {
tunnelAddr string
tlsCrt string
tlsKey string
rootCA string
clients string
logTo string
logLevel int
@ -53,6 +54,7 @@ func parseArgs() *options {
tunnelAddr := flag.String("tunnelAddr", ":5223", "Public address listening for tunnel client")
tlsCrt := flag.String("tlsCrt", "server.crt", "Path to a TLS certificate file")
tlsKey := flag.String("tlsKey", "server.key", "Path to a TLS key file")
rootCA := flag.String("rootCA", "", "Path to the trusted certificate chian used for client certificate authentication. If empty do not authenticate clients.")
clients := flag.String("clients", "", "Comma-separated list of tunnel client ids")
logTo := flag.String("log", "stdout", "Write log messages to this file, file name or 'stdout', 'stderr', 'none'")
logLevel := flag.Int("log-level", 1, "Level of messages to log, 0-3")
@ -65,6 +67,7 @@ func parseArgs() *options {
tunnelAddr: *tunnelAddr,
tlsCrt: *tlsCrt,
tlsKey: *tlsKey,
rootCA: *rootCA,
clients: *clients,
logTo: *logTo,
logLevel: *logLevel,

View file

@ -6,7 +6,9 @@ package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net/http"
"os"
"strings"
@ -31,16 +33,15 @@ func main() {
fatal("failed to init logger: %s", err)
}
// load certs
cert, err := tls.LoadX509KeyPair(opts.tlsCrt, opts.tlsKey)
tlsconf, err := tlsConfig(opts)
if err != nil {
fatal("failed to load certificate: %s", err)
fatal("failed to configure tls: %s", err)
}
// setup server
server, err := tunnel.NewServer(&tunnel.ServerConfig{
Addr: opts.tunnelAddr,
TLSConfig: tlsConfig(cert),
TLSConfig: tlsconf,
Logger: logger,
})
if err != nil {
@ -101,16 +102,38 @@ func main() {
server.Start()
}
func tlsConfig(cert tls.Certificate) *tls.Config {
func tlsConfig(opts *options) (*tls.Config, error) {
// load certs
cert, err := tls.LoadX509KeyPair(opts.tlsCrt, opts.tlsKey)
if err != nil {
return nil, err
}
// load root CA for client authentication
clientAuth := tls.RequireAnyClientCert
var roots *x509.CertPool
if opts.rootCA != "" {
roots = x509.NewCertPool()
rootPEM, err := ioutil.ReadFile(opts.rootCA)
if err != nil {
return nil, err
}
if ok := roots.AppendCertsFromPEM(rootPEM); !ok {
return nil, err
}
clientAuth = tls.RequireAndVerifyClientCert
}
return &tls.Config{
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAnyClientCert,
ClientAuth: clientAuth,
ClientCAs: roots,
SessionTicketsDisabled: true,
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
PreferServerCipherSuites: true,
NextProtos: []string{"h2"},
}
}, nil
}
func fatal(format string, a ...interface{}) {