Skip to content

Commit

Permalink
feat(config/mutualtls): Add separate options for cert files for mutua…
Browse files Browse the repository at this point in the history
…lTLS

Signed-off-by: Anna Simon <[email protected]>
  • Loading branch information
annadorottya authored and poiana committed Jun 14, 2023
1 parent 49de12e commit e078680
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 24 deletions.
33 changes: 23 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,17 @@ customfields: # custom fields are added to falco events, if the value starts wit
templatedfields: # templated fields are added to falco events and metrics, it uses Go template + output_fields values
# Dkey: '{{ or (index . "k8s.ns.labels.foo") "bar" }}'
# bracketreplacer: "_" # if not empty, replace the brackets in keys of Output Fields
mutualtlsfilespath: "/etc/certs" # folder which will used to store client.crt, client.key and ca.crt files for mutual tls for outputs (default: "/etc/certs")
mutualtlsfilespath: "/etc/certs" # folder which will used to store client.crt, client.key and ca.crt files for mutual tls for outputs, will be deprecated in the future (default: "/etc/certs")
mutualtlsclient: # takes priority over mutualtlsfilespath if not emtpy
certfile: "/etc/certs/client/client.crt" # client certification file
keyfile: "/etc/certs/client/client.key" # client key
cacertfile: "/etc/certs/client/ca.crt" # for server certification
tlsserver:
deploy: false # if true, TLS server will be deployed instead of HTTP
certfile: "/etc/certs/server.crt" # server certification file
keyfile: "/etc/certs/server.key" # server key
certfile: "/etc/certs/server/server.crt" # server certification file
keyfile: "/etc/certs/server/server.key" # server key
mutualtls: false # if true, mTLS server will be deployed instead of TLS, deploy also has to be true
cacertfile: "/etc/certs/ca.crt" # for client certification if mutualtls is true
cacertfile: "/etc/certs/server/ca.crt" # for client certification if mutualtls is true
slack:
webhookurl: "" # Slack WebhookURL (ex: https://hooks.slack.com/services/XXXX/YYYY/ZZZZ), if not empty, Slack output is enabled
Expand Down Expand Up @@ -663,12 +667,15 @@ care of lower/uppercases**) : `yaml: a.b --> envvar: A_B` :
events, syntax is "key:value,key:value"
- **TEMPLATEDFIELDS** : templated fields are added to falco events and metrics, it uses Go template + output_fields values
- **BRACKETREPLACER** : if not empty, the brackets in keys of Output Fields are replaced
- **MUTUALTLSFILESPATH**: path which will be used to stored certs and key for mutual tls authentication (default: "/etc/certs")
- **MUTUALTLSFILESPATH**: path which will be used to stored certs and key for mutual TLS authentication, will be deprecated in the future (default: "/etc/certs")
- **MUTUALTLSCLIENT_CERTFILE**: client certification file for mutual TLS client certification, takes priority over MUTUALTLSFILESPATH if not empty
- **MUTUALTLSCLIENT_KEYFILE**: client key file for mutual TLS client certification, takes priority over MUTUALTLSFILESPATH if not empty
- **MUTUALTLSCLIENT_CACERTFILE**: CA certification file for server certification for mutual TLS authentication, takes priority over MUTUALTLSFILESPATH if not empty
- **TLSSERVER_DEPLOY**: if _true_ TLS server will be deployed instead of HTTP
- **TLSSERVER_CERTFILE**: server certification file for TLS Server (default: "/etc/certs/server.crt")
- **TLSSERVER_KEYFILE**: server key file for TLS Server (default: "/etc/certs/server.key")
- **TLSSERVER_MUTUALTLS**: if _true_ mTLS server will be deployed instead of TLS, deploy also has to be true
- **TLSSERVER_CACERTFILE**: CA certification file for client certification (default: "/etc/certs/ca.crt")
- **TLSSERVER_CERTFILE**: server certification file for TLS Server (default: "/etc/certs/server/server.crt")
- **TLSSERVER_KEYFILE**: server key file for TLS Server (default: "/etc/certs/server/server.key")
- **TLSSERVER_MUTUALTLS**: if _true_ mutual TLS server will be deployed instead of TLS, deploy also has to be true
- **TLSSERVER_CACERTFILE**: CA certification file for client certification if TLSSERVER_MUTUALTLS is _true_ (default: "/etc/certs/server/ca.crt")
- **SLACK_WEBHOOKURL** : Slack Webhook URL (ex: https://hooks.slack.com/services/XXXX/YYYY/ZZZZ)
- **SLACK_CHANNEL** : Slack Channel (optionnal)
- **SLACK_FOOTER** : Slack footer
Expand Down Expand Up @@ -1208,7 +1215,13 @@ All logs are sent to `stdout`.

## Mutual TLS ##

Outputs with `mutualtls` enabled in their configuration require *client.crt*, *client.key* and *ca.crt* files to be stored in the path configured in **mutualtlsfilespath** global parameter (**important**: file names must be preserved)
Outputs with `mutualtls` enabled in their configuration require the *client.crt*, *client.key* and *ca.crt* filepaths to be configured in the **mutualtlsclient_certfile**, **mutualtlsclient_keyfile** and **mutualtlsclient_cacertfile** global parameter.

```bash
docker run -d -p 2801:2801 -e MUTUALTLSCLIENT_CERTFILE=/etc/certs/client/client.crt -e MUTUALTLSCLIENT_KEYFILE=/etc/certs/client/client.key -e MUTUALTLSCLIENT_CACERTFILE=/etc/certs/client/ca.crt -e ALERTMANAGER_HOSTPORT=https://XXXX -e ALERTMANAGER_MUTUALTLS=true -e INFLUXDB_HOSTPORT=https://XXXX -e INFLUXDB_MUTUALTLS=true -e WEBHOOK_ADDRESS=XXXX -v /localpath/myclientcert.crt:/etc/certs/client/client.crt -v /localpath/myclientkey.key:/etc/certs/client/client.key -v /localpath/ca.crt:/etc/certs/client/ca.crt falcosecurity/falcosidekick
```

Alternately the path where the *client.crt*, *client.key* and *ca.crt* files are stored can be configured in **mutualtlsfilespath** global parameter. (**Important**: file names must be preserved)

```bash
docker run -d -p 2801:2801 -e MUTUALTLSFILESPATH=/etc/certs -e ALERTMANAGER_HOSTPORT=https://XXXX -e ALERTMANAGER_MUTUALTLS=true -e INFLUXDB_HOSTPORT=https://XXXX -e INFLUXDB_MUTUALTLS=true -e WEBHOOK_ADDRESS=XXXX -v /localpath/myclientcert.crt:/etc/certs/client.crt -v /localpath/myclientkey.key:/etc/certs/client.key -v /localpath/ca.crt:/etc/certs/ca.crt falcosecurity/falcosidekick
Expand Down
9 changes: 6 additions & 3 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ func getConfig() *types.Configuration {
v.SetDefault("Debug", false)
v.SetDefault("BracketReplacer", "")
v.SetDefault("MutualTlsFilesPath", "/etc/certs")
v.SetDefault("MutualTLSClient.CertFile", "")
v.SetDefault("MutualTLSClient.KeyFile", "")
v.SetDefault("MutualTLSClient.CaCertFile", "")

v.SetDefault("TLSServer.Deploy", false)
v.SetDefault("TLSServer.CertFile", "/etc/certs/server.crt")
v.SetDefault("TLSServer.KeyFile", "/etc/certs/server.key")
v.SetDefault("TLSServer.CertFile", "/etc/certs/server/server.crt")
v.SetDefault("TLSServer.KeyFile", "/etc/certs/server/server.key")
v.SetDefault("TLSServer.MutualTLS", false)
v.SetDefault("TLSServer.CaCertFile", "/etc/certs/ca.crt")
v.SetDefault("TLSServer.CaCertFile", "/etc/certs/server/ca.crt")

v.SetDefault("Slack.WebhookURL", "")
v.SetDefault("Slack.Footer", "https://github.com/falcosecurity/falcosidekick")
Expand Down
12 changes: 8 additions & 4 deletions config_example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ customfields: # custom fields are added to falco events and metrics, if the valu
templatedfields: # templated fields are added to falco events and metrics, it uses Go template + output_fields values
# Dkey: '{{ or (index . "k8s.ns.labels.foo") "bar" }}'
# bracketreplacer: "_" # if not empty, the brackets in keys of Output Fields are replaced
mutualtlsfilespath: "/etc/certs" # folder which will used to store client.crt, client.key and ca.crt files for mutual tls for outputs (default: "/etc/certs")
mutualtlsfilespath: "/etc/certs" # folder which will used to store client.crt, client.key and ca.crt files for mutual tls for outputs, will be deprecated in the future (default: "/etc/certs")
mutualtlsclient: # takes priority over mutualtlsfilespath if not emtpy
certfile: "/etc/certs/client/client.crt" # client certification file
keyfile: "/etc/certs/client/client.key" # client key
cacertfile: "/etc/certs/client/ca.crt" # for server certification
tlsserver:
deploy: false # if true, TLS server will be deployed instead of HTTP
certfile: "/etc/certs/server.crt" # server certification file
keyfile: "/etc/certs/server.key" # server key
certfile: "/etc/certs/server/server.crt" # server certification file
keyfile: "/etc/certs/server/server.key" # server key
mutualtls: false # if true, mTLS server will be deployed instead of TLS, deploy also has to be true
cacertfile: "/etc/certs/ca.crt" # for client certification if mutualtls is true
cacertfile: "/etc/certs/server/ca.crt" # for client certification if mutualtls is true


slack:
Expand Down
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,10 @@ func main() {
log.Printf("[DEBUG] : running HTTP server")
}

if config.TLSServer.MutualTLS {
log.Printf("[WARN] : tlsserver.deploy is false but tlsserver.mutualtls is true, change tlsserver.deploy to true to use mTLS")
}

if err := server.ListenAndServe(); err != nil {
log.Fatalf("[ERROR] : %v", err.Error())
}
Expand Down
20 changes: 18 additions & 2 deletions outputs/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,13 +195,29 @@ func (c *Client) sendRequest(method string, payload interface{}) error {

if c.MutualTLSEnabled {
// Load client cert
cert, err := tls.LoadX509KeyPair(c.Config.MutualTLSFilesPath+MutualTLSClientCertFilename, c.Config.MutualTLSFilesPath+MutualTLSClientKeyFilename)
var MutualTLSClientCertPath, MutualTLSClientKeyPath, MutualTLSClientCaCertPath string
if c.Config.MutualTLSClient.CertFile != "" {
MutualTLSClientCertPath = c.Config.MutualTLSClient.CertFile
} else {
MutualTLSClientCertPath = c.Config.MutualTLSFilesPath + MutualTLSClientCertFilename
}
if c.Config.MutualTLSClient.KeyFile != "" {
MutualTLSClientKeyPath = c.Config.MutualTLSClient.KeyFile
} else {
MutualTLSClientKeyPath = c.Config.MutualTLSFilesPath + MutualTLSClientKeyFilename
}
if c.Config.MutualTLSClient.CaCertFile != "" {
MutualTLSClientCaCertPath = c.Config.MutualTLSClient.CaCertFile
} else {
MutualTLSClientCaCertPath = c.Config.MutualTLSFilesPath + MutualTLSCacertFilename
}
cert, err := tls.LoadX509KeyPair(MutualTLSClientCertPath, MutualTLSClientKeyPath)
if err != nil {
log.Printf("[ERROR] : %v - %v\n", c.OutputType, err.Error())
}

// Load CA cert
caCert, err := ioutil.ReadFile(c.Config.MutualTLSFilesPath + MutualTLSCacertFilename)
caCert, err := ioutil.ReadFile(MutualTLSClientCaCertPath)
if err != nil {
log.Printf("[ERROR] : %v - %v\n", c.OutputType, err.Error())
}
Expand Down
13 changes: 8 additions & 5 deletions outputs/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,10 @@ func TestHeadersResetAfterReq(t *testing.T) {

func TestMutualTlsPost(t *testing.T) {
config := &types.Configuration{}
config.MutualTLSFilesPath = "/tmp/falcosidekicktests"
config.MutualTLSFilesPath = "/tmp/falcosidekicktests/client"
config.MutualTLSClient.CertFile = "/tmp/falcosidekicktests/client/client.crt"
config.MutualTLSClient.KeyFile = "/tmp/falcosidekicktests/client/client.key"
config.MutualTLSClient.CaCertFile = "/tmp/falcosidekicktests/client/ca.crt"
// delete folder to avoid makedir failure
os.RemoveAll(config.MutualTLSFilesPath)

Expand Down Expand Up @@ -212,7 +215,7 @@ func TestMutualTlsPost(t *testing.T) {
}

func certsetup(config *types.Configuration) (serverTLSConf *tls.Config, err error) {
err = os.Mkdir(config.MutualTLSFilesPath, 0755)
err = os.MkdirAll(config.MutualTLSFilesPath, 0755)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -256,7 +259,7 @@ func certsetup(config *types.Configuration) (serverTLSConf *tls.Config, err erro
})

// save ca to ca.crt file (it will be used by Client)
err = ioutil.WriteFile(config.MutualTLSFilesPath+"/ca.crt", caPEM.Bytes(), 0600)
err = ioutil.WriteFile(config.MutualTLSClient.CaCertFile, caPEM.Bytes(), 0600)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -356,7 +359,7 @@ func certsetup(config *types.Configuration) (serverTLSConf *tls.Config, err erro
})

// save client cert and key to client.crt and client.key
err = ioutil.WriteFile(config.MutualTLSFilesPath+"/client.crt", clientCertPEM.Bytes(), 0600)
err = ioutil.WriteFile(config.MutualTLSClient.CertFile, clientCertPEM.Bytes(), 0600)
if err != nil {
return nil, err
}
Expand All @@ -365,7 +368,7 @@ func certsetup(config *types.Configuration) (serverTLSConf *tls.Config, err erro
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(clientCertPrivKey),
})
err = ioutil.WriteFile(config.MutualTLSFilesPath+"/client.key", clientCertPrivKeyPEM.Bytes(), 0600)
err = ioutil.WriteFile(config.MutualTLSClient.KeyFile, clientCertPrivKeyPEM.Bytes(), 0600)
if err != nil {
return nil, err
}
Expand Down
8 changes: 8 additions & 0 deletions types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ func (f FalcoPayload) Check() bool {
// Configuration is a struct to store configuration
type Configuration struct {
MutualTLSFilesPath string
MutualTLSClient MutualTLSClient
TLSServer TLSServer
Debug bool
ListenAddress string
Expand Down Expand Up @@ -106,6 +107,13 @@ type Configuration struct {
OpenObserve OpenObserveConfig
}

// MutualTLSClient represents parameters for mutual TLS as client
type MutualTLSClient struct {
CertFile string
KeyFile string
CaCertFile string
}

// TLSServer represents parameters for TLS Server
type TLSServer struct {
Deploy bool
Expand Down

0 comments on commit e078680

Please sign in to comment.