Fixes #45: Added Support fot Mutual TLS Authentication
This commit is contained in:
+18
-2
@@ -32,8 +32,8 @@ import (
|
|||||||
var ServerCmd = &cobra.Command{
|
var ServerCmd = &cobra.Command{
|
||||||
Use: "server [optional flags] [optional pow file(s)]",
|
Use: "server [optional flags] [optional pow file(s)]",
|
||||||
Short: "Start a kapow server",
|
Short: "Start a kapow server",
|
||||||
Long: `Start a Kapow server with, by default with client interface, data interface
|
Long: `Start a Kapow server with a client interface, a data interface and an
|
||||||
and admin interface`,
|
admin interface`,
|
||||||
PreRunE: validateServerCommandArguments,
|
PreRunE: validateServerCommandArguments,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
var sConf server.ServerConfig = server.ServerConfig{}
|
var sConf server.ServerConfig = server.ServerConfig{}
|
||||||
@@ -44,6 +44,9 @@ var ServerCmd = &cobra.Command{
|
|||||||
sConf.CertFile, _ = cmd.Flags().GetString("certfile")
|
sConf.CertFile, _ = cmd.Flags().GetString("certfile")
|
||||||
sConf.KeyFile, _ = cmd.Flags().GetString("keyfile")
|
sConf.KeyFile, _ = cmd.Flags().GetString("keyfile")
|
||||||
|
|
||||||
|
sConf.ClientAuth, _ = cmd.Flags().GetBool("clientauth")
|
||||||
|
sConf.ClientCaFile, _ = cmd.Flags().GetString("clientcafile")
|
||||||
|
|
||||||
go server.StartServer(sConf)
|
go server.StartServer(sConf)
|
||||||
|
|
||||||
// start sub shell + ENV(KAPOW_CONTROL_URL)
|
// start sub shell + ENV(KAPOW_CONTROL_URL)
|
||||||
@@ -78,13 +81,26 @@ func init() {
|
|||||||
|
|
||||||
ServerCmd.Flags().String("certfile", "", "Cert file to serve thru https")
|
ServerCmd.Flags().String("certfile", "", "Cert file to serve thru https")
|
||||||
ServerCmd.Flags().String("keyfile", "", "Key file to serve thru https")
|
ServerCmd.Flags().String("keyfile", "", "Key file to serve thru https")
|
||||||
|
|
||||||
|
ServerCmd.Flags().Bool("clientauth", false, "Activate client mutual tls authentication")
|
||||||
|
ServerCmd.Flags().String("clientcafile", "", "Cert file to validate client certificates")
|
||||||
}
|
}
|
||||||
|
|
||||||
func validateServerCommandArguments(cmd *cobra.Command, args []string) error {
|
func validateServerCommandArguments(cmd *cobra.Command, args []string) error {
|
||||||
cert, _ := cmd.Flags().GetString("certfile")
|
cert, _ := cmd.Flags().GetString("certfile")
|
||||||
key, _ := cmd.Flags().GetString("keyfile")
|
key, _ := cmd.Flags().GetString("keyfile")
|
||||||
|
cliAuth, _ := cmd.Flags().GetBool("clientauth")
|
||||||
|
|
||||||
if (cert == "") != (key == "") {
|
if (cert == "") != (key == "") {
|
||||||
return errors.New("expected both or neither (certfile and keyfile)")
|
return errors.New("expected both or neither (certfile and keyfile)")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cert == "" {
|
||||||
|
// If we don't serve thru https client authentication can't be enabled
|
||||||
|
if cliAuth {
|
||||||
|
return errors.New("Client authentication can't be active in a non https server")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,14 +27,17 @@ type ServerConfig struct {
|
|||||||
DataBindAddr,
|
DataBindAddr,
|
||||||
UserBindAddr,
|
UserBindAddr,
|
||||||
KeyFile,
|
KeyFile,
|
||||||
CertFile string
|
CertFile,
|
||||||
|
ClientCaFile string
|
||||||
|
|
||||||
|
ClientAuth bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// StartServer Starts one instance of each server in a goroutine and remains listening on a channel for trace events generated by them
|
// StartServer Starts one instance of each server in a goroutine and remains listening on a channel for trace events generated by them
|
||||||
func StartServer(config ServerConfig) {
|
func StartServer(config ServerConfig) {
|
||||||
go control.Run(config.ControlBindAddr)
|
go control.Run(config.ControlBindAddr)
|
||||||
go data.Run(config.DataBindAddr)
|
go data.Run(config.DataBindAddr)
|
||||||
go user.Run(config.UserBindAddr, config.CertFile, config.KeyFile)
|
go user.Run(config.UserBindAddr, config.CertFile, config.KeyFile, config.ClientCaFile, config.ClientAuth)
|
||||||
|
|
||||||
// Wait for ever
|
// Wait for ever
|
||||||
select {}
|
select {}
|
||||||
|
|||||||
@@ -17,6 +17,9 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@@ -29,13 +32,32 @@ var Server = http.Server{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run finishes configuring Server and runs ListenAndServe on it
|
// Run finishes configuring Server and runs ListenAndServe on it
|
||||||
func Run(bindAddr, certFile, keyFile string) {
|
func Run(bindAddr, certFile, keyFile, cliCaFile string, cliAuth bool) {
|
||||||
Server = http.Server{
|
Server = http.Server{
|
||||||
Addr: bindAddr,
|
Addr: bindAddr,
|
||||||
Handler: mux.New(),
|
Handler: mux.New(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if (certFile != "") && (keyFile != "") {
|
if (certFile != "") && (keyFile != "") {
|
||||||
|
if cliAuth {
|
||||||
|
if Server.TLSConfig == nil {
|
||||||
|
Server.TLSConfig = &tls.Config{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
Server.TLSConfig.ClientCAs, err = loadCertificatesFromFile(cliCaFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("UserServer failed to load CA certs: %s\nDefault to system CA store.", err)
|
||||||
|
} else {
|
||||||
|
CAStore := "System store"
|
||||||
|
if Server.TLSConfig.ClientCAs != nil {
|
||||||
|
CAStore = cliCaFile
|
||||||
|
}
|
||||||
|
log.Printf("UserServer using CA certs from %s\n", CAStore)
|
||||||
|
Server.TLSConfig.ClientAuth = tls.RequireAndVerifyClientCert
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err := Server.ListenAndServeTLS(certFile, keyFile); err != http.ErrServerClosed {
|
if err := Server.ListenAndServeTLS(certFile, keyFile); err != http.ErrServerClosed {
|
||||||
log.Fatalf("UserServer failed: %s", err)
|
log.Fatalf("UserServer failed: %s", err)
|
||||||
}
|
}
|
||||||
@@ -45,3 +67,15 @@ func Run(bindAddr, certFile, keyFile string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadCertificatesFromFile(certFile string) (pool *x509.CertPool, err error) {
|
||||||
|
if certFile != "" {
|
||||||
|
caCerts, err := ioutil.ReadFile(certFile)
|
||||||
|
if err == nil {
|
||||||
|
pool = x509.NewCertPool()
|
||||||
|
pool.AppendCertsFromPEM(caCerts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user