Skip to content

Commit e8cb2a4

Browse files
ikheifets-splunkomrozowicz-splunkajasnosz
authored
feat: mTLS for Splunk 10 (#1197)
* feat: mTLS support for Splunk 10 * docs: fix typo --------- Co-authored-by: Olga <[email protected]> Co-authored-by: ajasnosz <[email protected]>
1 parent 2c2473c commit e8cb2a4

File tree

7 files changed

+192
-1
lines changed

7 files changed

+192
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
### Changed
6+
- implemented mTLS for Splunk 10
67

78
### Fixed
89

charts/splunk-connect-for-snmp/templates/worker/sender/deployment.yaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ spec:
4646
env:
4747
{{- include "environmental-variables" . | nindent 12 }}
4848
{{- include "environmental-variables-sender" . | nindent 12 }}
49+
{{- if .Values.splunk.mtls.enabled }}
50+
- name: SPLUNK_HEC_MTLS_CLIENT_CERT
51+
value: /app/hec-mtls/tls.crt
52+
- name: SPLUNK_HEC_MTLS_CLIENT_KEY
53+
value: /app/hec-mtls/tls.key
54+
- name: SPLUNK_HEC_MTLS_CA_CERT
55+
value: /app/hec-mtls/cacert.pem
56+
{{- end }}
4957
{{- if .Values.worker.livenessProbe.enabled }}
5058
livenessProbe:
5159
exec:
@@ -63,6 +71,11 @@ spec:
6371
periodSeconds: {{ .Values.worker.readinessProbe.periodSeconds }}
6472
{{- end }}
6573
volumeMounts:
74+
{{- if .Values.splunk.mtls.enabled }}
75+
- name: hec-mtls
76+
mountPath: "/app/hec-mtls"
77+
readOnly: true
78+
{{- end }}
6679
- name: config
6780
mountPath: "/app/config"
6881
readOnly: true
@@ -102,6 +115,11 @@ spec:
102115
{{- toYaml . | nindent 8 }}
103116
{{- end }}
104117
volumes:
118+
{{- if .Values.splunk.mtls.enabled }}
119+
- name: hec-mtls
120+
secret:
121+
secretName: {{ .Values.splunk.mtls.secretRef }}
122+
{{- end }}
105123
# You set volumes at the Pod level, then mount them into containers inside that Pod
106124
- name: config
107125
configMap:

charts/splunk-connect-for-snmp/values.schema.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,18 @@
185185
},
186186
"metricsIndex": {
187187
"type": "string"
188+
},
189+
"mtls": {
190+
"type": "object",
191+
"additionalProperties": false,
192+
"properties": {
193+
"enabled": {
194+
"type": "boolean"
195+
},
196+
"secretRef": {
197+
"type": "string"
198+
}
199+
}
188200
}
189201
}
190202
},

charts/splunk-connect-for-snmp/values.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ splunk:
9393
# name of the metrics index
9494
metricsIndex: "netmetrics"
9595

96+
# new encryption appeared in Splunk 10
97+
mtls:
98+
enabled: false
99+
# name of existing secret (should be created manully), that will store certs for mTLS
100+
secretRef: ""
101+
96102
################################################################################
97103
# Splunk Observability configuration
98104
################################################################################

docs/mtls.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# mTLS
2+
3+
4+
## Intro
5+
6+
!!! info
7+
mTLS encryption support is available beginning with Splunk 10
8+
9+
Mutual TLS (mTLS) is an extension of the standard TLS protocol that provides mutual authentication between a client and a server. While TLS typically ensures that the client can verify the server’s identity, mTLS requires both parties to verify each other’s identities using digital certificates. In our case client is SC4SNMP and server is Splunk.
10+
11+
12+
## How to setup Splunk
13+
14+
!!! info
15+
If you are using Splunk Cloud, reach out to your administrator to configure mutual TLS (mTLS).
16+
17+
1. Ensure that client and server mTLS certificates are already prepared
18+
19+
2. Update `$SPLUNK_HOME/etc/system/local/server.conf`:
20+
21+
```
22+
[sslConfig]
23+
requireClientCert = true
24+
[kvstore]
25+
hostnameOption = fullyqualifiedname
26+
```
27+
28+
3. Update `$SPLUNK_HOME/etc/system/local/web.conf`:
29+
30+
```
31+
[settings]
32+
sslPassword = password
33+
sslRootCAPath = cacert.pem
34+
enableSplunkWebSSL = true
35+
```
36+
37+
4. Restart Splunk:
38+
39+
```
40+
$SPLUNK_HOME/bin/splunk restart
41+
```
42+
43+
## How to setup SC4SNMP
44+
45+
/// tab | microk8s
46+
1. Add your **client** mTLS certificates to secrets:
47+
48+
```
49+
microk8s kubectl create secret generic mtls -n sc4snmp \
50+
--from-file=client.crt=./client.crt \
51+
--from-file=client.key=./client.key \
52+
--from-file=cacert.pem=./cacert.pem
53+
```
54+
55+
2. Use https protocol to communicate with Splunk. To enforce this, set the `splunk.protocol` variable in the configuration file values.yaml:
56+
57+
```
58+
splunk:
59+
protocol: "https"
60+
```
61+
62+
3. Add `mtls` section and provide your secret with certificates inside. To do this, update the `values.yaml` file under the splunk section as shown below:
63+
64+
```
65+
splunk:
66+
mtls:
67+
enabled: true
68+
secretRef: "mtls"
69+
```
70+
71+
4. Redeploy SC4SNMP
72+
///
73+
74+
/// tab | docker-compose
75+
1. Add your **client** mTLS certificates to secrets. To do this, update the docker-compose.yaml file by adding the following section at the end:
76+
77+
```
78+
secrets:
79+
cert:
80+
file: client.crt
81+
key:
82+
file: client.key
83+
ca:
84+
file: cacert.pem
85+
```
86+
87+
2. To provide the certificates to the `worker-sender` service, update its definition in the `docker-compose.yaml` file as shown below:
88+
89+
```
90+
worker-sender:
91+
environment:
92+
SPLUNK_HEC_MTLS_CLIENT_CERT: /run/secrets/cert
93+
SPLUNK_HEC_MTLS_CLIENT_KEY: /run/secrets/key
94+
SPLUNK_HEC_MTLS_CA_CERT: /run/secrets/ca
95+
secrets:
96+
- cert
97+
- key
98+
- ca
99+
```
100+
3. Use https protocol to communicate with Splunk. To enforce this, set the `SPLUNK_HEC_PROTOCOL` variable in the configuration file `.env`:
101+
102+
```
103+
SPLUNK_HEC_PROTOCOL=https
104+
```
105+
106+
4. Redeploy SC4SNMP
107+
///
108+
109+
110+
## Troubleshooting
111+
112+
1. Double-check that the mTLS certificates you are using are valid. To do this, send a test log message using `curl` in verbose mode, which can help identify any issues with the certificates:
113+
114+
```
115+
curl -k https://${HEC_URL} \
116+
-H "Authorization: Splunk ${HEC_TOKEN}" \
117+
-H "Content-Type: application/json" \
118+
-d '{"event": "Hello", "sourcetype": "manual", "host": "myhost", "source": "myapp"}' \
119+
--cert client.crt \
120+
--key client.key \
121+
--cacert cacert.pem \
122+
-vvv
123+
```
124+
125+
2. Check logs of `worker-sender`. Refer to the instructions on how to configure logs for `kubernetes` or `docker` deployment.
126+
127+

mkdocs.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ markdown_extensions:
1717
- admonition
1818
- pymdownx.details
1919
- pymdownx.superfences
20+
- pymdownx.blocks.tab:
21+
alternate_style: true
2022

2123
plugins:
2224
- search:
@@ -96,6 +98,7 @@ nav:
9698
- Releases: "releases.md"
9799
- Request MIB: "mib-request.md"
98100
- Security: "security.md"
101+
- mTLS: "mtls.md"
99102
- Troubleshooting:
100103
- Accessing and configuring logs: "troubleshooting/configuring-logs.md"
101104
- Docker commands: "troubleshooting/docker-commands.md"

splunk_connect_for_snmp/splunk/tasks.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737
SPLUNK_HEC_HOST = os.getenv("SPLUNK_HEC_HOST", "127.0.0.1")
3838
SPLUNK_HEC_PORT = os.getenv("SPLUNK_HEC_PORT", None)
3939
SPLUNK_HEC_PATH = os.getenv("SPLUNK_HEC_PATH", "services/collector")
40+
SPLUNK_HEC_MTLS_CLIENT_CERT = os.getenv("SPLUNK_HEC_MTLS_CLIENT_CERT", None)
41+
SPLUNK_HEC_MTLS_CLIENT_KEY = os.getenv("SPLUNK_HEC_MTLS_CLIENT_KEY", None)
42+
SPLUNK_HEC_MTLS_CA_CERT = os.getenv("SPLUNK_HEC_MTLS_CA_CERT", None)
4043
METRICS_INDEXING_ENABLED = human_bool(os.getenv("METRICS_INDEXING_ENABLED", "false"))
4144

4245
url = {
@@ -101,10 +104,31 @@
101104
class HECTask(Task):
102105
def __init__(self):
103106
self.session = Session()
104-
self.session.verify = SPLUNK_HEC_TLSVERIFY
107+
108+
# if we have CA cert for verifacation and we are not under insecureSSL mode
109+
if (
110+
SPLUNK_HEC_MTLS_CA_CERT is not None
111+
and os.path.exists(SPLUNK_HEC_MTLS_CA_CERT)
112+
and SPLUNK_HEC_TLSVERIFY
113+
):
114+
self.session.verify = SPLUNK_HEC_MTLS_CA_CERT
115+
else:
116+
self.session.verify = SPLUNK_HEC_TLSVERIFY
117+
105118
self.session.headers = SPLUNK_HEC_HEADERS
106119
self.session.logger = logger
107120

121+
if (
122+
SPLUNK_HEC_MTLS_CLIENT_CERT is not None
123+
and SPLUNK_HEC_MTLS_CLIENT_KEY is not None
124+
and os.path.exists(SPLUNK_HEC_MTLS_CLIENT_CERT)
125+
and os.path.exists(SPLUNK_HEC_MTLS_CLIENT_KEY)
126+
):
127+
self.session.cert = (
128+
SPLUNK_HEC_MTLS_CLIENT_CERT,
129+
SPLUNK_HEC_MTLS_CLIENT_KEY,
130+
)
131+
108132

109133
class PrepareTask(Task):
110134
def __init__(self):

0 commit comments

Comments
 (0)