Skip to content

Commit 8d32703

Browse files
author
Brent Boe
authored
Merge pull request #297 from splunk/test/splunktcp-ssl-feature
Test/splunktcp ssl feature
2 parents cba4558 + 1705020 commit 8d32703

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

docs/ADVANCED.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Let's dive into the nitty-gritty on how to tweak the setup of your containerized
1818
* [Enable SmartStore](#enable-smartstore)
1919
* [Using deployment servers](#using-deployment-servers)
2020
* [Deploy distributed topology](#deploy-distributed-topology)
21+
* [Enable SSL internal communication](#enable-ssl-internal-communication)
2122
* [Build from source](#build-from-source)
2223
* [base-debian-9](#base-debian-9)
2324
* [splunk-debian-9](#splunk-debian-9)
@@ -248,6 +249,25 @@ While running a standalone Splunk instance may be fine for testing and developme
248249

249250
See the [instructions on standing up a distributed environment](advanced/DISTRIBUTED_TOPOLOGY.md) to understand how to get started.
250251

252+
## Enable SSL Internal Communication
253+
For users looking to secure the network traffic from one Splunk instance to another Splunk instance (ex: forwarders to indexers), you can enable forwarding and receiving to use SSL certificates.
254+
255+
If you wish to enable SSL on one tier of your Splunk topology, it's very likely all instances will need it. To achieve this, we recommend you generate your server and CA certificates and add them to the `default.yml` which gets shared across all Splunk docker containers. Use this example `default.yml` snippet for the configuration of Splunk TCP with SSL.
256+
```
257+
splunk:
258+
...
259+
s2s:
260+
ca: /mnt/certs/ca.pem
261+
cert: /mnt/certs/cert.pem
262+
enable: true
263+
password: abcd1234
264+
port: 9997
265+
ssl: true
266+
...
267+
```
268+
269+
For more instructions on how to bring your own certificates, please see: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates
270+
251271
## Build from source
252272
While we don't support or recommend you building your own images from source, it is entirely possible. This can be useful if you want to incorporate very experimental features, test new features, and if you have your own registry for persistent images.
253273

tests/test_docker_splunk.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,15 @@ def teardown_method(self, method):
102102
self.compose_file_name, self.project_name = None, None
103103
self._clean_docker_env()
104104

105+
def cleanup_files(self, files):
106+
try:
107+
for file in files:
108+
os.remove(file)
109+
except OSError as e:
110+
pass
111+
except Exception as e:
112+
raise e
113+
105114
def _clean_docker_env(self):
106115
# Remove anything spun up by docker-compose
107116
containers = self.client.containers(filters={"label": "com.docker.compose.version"})
@@ -1224,6 +1233,154 @@ def test_adhoc_1uf_hec_ssl_disabled(self):
12241233
except OSError:
12251234
pass
12261235

1236+
def test_adhoc_1so_splunktcp_ssl(self):
1237+
# Generate default.yml
1238+
cid = self.client.create_container(self.SPLUNK_IMAGE_NAME, tty=True, command="create-defaults")
1239+
self.client.start(cid.get("Id"))
1240+
output = self.get_container_logs(cid.get("Id"))
1241+
self.client.remove_container(cid.get("Id"), v=True, force=True)
1242+
# Get the password
1243+
password = re.search(" password: (.*)", output).group(1).strip()
1244+
assert password
1245+
# Commands to generate self-signed certificates for Splunk here: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates
1246+
passphrase = "abcd1234"
1247+
cmds = [
1248+
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/ca.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
1249+
"openssl req -new -key {path}/ca.key -passin pass:{pw} -out {path}/ca.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
1250+
"openssl x509 -req -in {path}/ca.csr -sha512 -passin pass:{pw} -signkey {path}/ca.key -CAcreateserial -out {path}/ca.pem -days 3".format(pw=passphrase, path=FIXTURES_DIR),
1251+
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/server.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
1252+
"openssl req -new -passin pass:{pw} -key {path}/server.key -out {path}/server.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
1253+
"openssl x509 -req -passin pass:{pw} -in {path}/server.csr -SHA256 -CA {path}/ca.pem -CAkey {path}/ca.key -CAcreateserial -out {path}/server.pem -days 3".format(pw=passphrase, path=FIXTURES_DIR),
1254+
"cat {path}/server.pem {path}/server.key {path}/ca.pem > {path}/cert.pem".format(path=FIXTURES_DIR)
1255+
]
1256+
for cmd in cmds:
1257+
execute_cmd = subprocess.check_output(["/bin/sh", "-c", cmd])
1258+
# Update s2s ssl settings
1259+
output = re.sub(r''' s2s:.*?ssl: false''', r''' s2s:
1260+
ca: /tmp/defaults/ca.pem
1261+
cert: /tmp/defaults/cert.pem
1262+
enable: true
1263+
password: {}
1264+
port: 9997
1265+
ssl: true'''.format(passphrase), output, flags=re.DOTALL)
1266+
# Write the default.yml to a file
1267+
with open(os.path.join(FIXTURES_DIR, "default.yml"), "w") as f:
1268+
f.write(output)
1269+
# Create the container and mount the default.yml
1270+
cid = None
1271+
try:
1272+
splunk_container_name = generate_random_string()
1273+
cid = self.client.create_container(self.SPLUNK_IMAGE_NAME, tty=True, ports=[8000, 8089],
1274+
volumes=["/tmp/defaults/"], name=splunk_container_name,
1275+
environment={"DEBUG": "true",
1276+
"SPLUNK_START_ARGS": "--accept-license",
1277+
"SPLUNK_PASSWORD": password},
1278+
host_config=self.client.create_host_config(binds=[FIXTURES_DIR + ":/tmp/defaults/"],
1279+
port_bindings={8089: ("0.0.0.0",), 8000: ("0.0.0.0",)})
1280+
)
1281+
cid = cid.get("Id")
1282+
self.client.start(cid)
1283+
# Poll for the container to be ready
1284+
assert self.wait_for_containers(1, name=splunk_container_name)
1285+
# Check splunkd
1286+
assert self.check_splunkd("admin", password)
1287+
# Check if the created file exists
1288+
exec_command = self.client.exec_create(cid, "cat /opt/splunk/etc/system/local/inputs.conf", user="splunk")
1289+
std_out = self.client.exec_start(exec_command)
1290+
assert "[splunktcp-ssl:9997]" in std_out
1291+
assert "serverCert = /tmp/defaults/cert.pem" in std_out
1292+
except Exception as e:
1293+
self.logger.error(e)
1294+
raise e
1295+
finally:
1296+
if cid:
1297+
self.client.remove_container(cid, v=True, force=True)
1298+
files = [
1299+
os.path.join(FIXTURES_DIR, "ca.key"),
1300+
os.path.join(FIXTURES_DIR, "ca.csr"),
1301+
os.path.join(FIXTURES_DIR, "ca.pem"),
1302+
os.path.join(FIXTURES_DIR, "server.key"),
1303+
os.path.join(FIXTURES_DIR, "server.csr"),
1304+
os.path.join(FIXTURES_DIR, "server.pem"),
1305+
os.path.join(FIXTURES_DIR, "cert.pem"),
1306+
os.path.join(FIXTURES_DIR, "default.yml")
1307+
]
1308+
self.cleanup_files(files)
1309+
1310+
def test_adhoc_1uf_splunktcp_ssl(self):
1311+
# Generate default.yml
1312+
cid = self.client.create_container(self.UF_IMAGE_NAME, tty=True, command="create-defaults")
1313+
self.client.start(cid.get("Id"))
1314+
output = self.get_container_logs(cid.get("Id"))
1315+
self.client.remove_container(cid.get("Id"), v=True, force=True)
1316+
# Get the password
1317+
password = re.search(" password: (.*)", output).group(1).strip()
1318+
assert password
1319+
# Commands to generate self-signed certificates for Splunk here: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates
1320+
passphrase = "abcd1234"
1321+
cmds = [
1322+
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/ca.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
1323+
"openssl req -new -key {path}/ca.key -passin pass:{pw} -out {path}/ca.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
1324+
"openssl x509 -req -in {path}/ca.csr -sha512 -passin pass:{pw} -signkey {path}/ca.key -CAcreateserial -out {path}/ca.pem -days 3".format(pw=passphrase, path=FIXTURES_DIR),
1325+
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/server.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
1326+
"openssl req -new -passin pass:{pw} -key {path}/server.key -out {path}/server.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
1327+
"openssl x509 -req -passin pass:{pw} -in {path}/server.csr -SHA256 -CA {path}/ca.pem -CAkey {path}/ca.key -CAcreateserial -out {path}/server.pem -days 3".format(pw=passphrase, path=FIXTURES_DIR),
1328+
"cat {path}/server.pem {path}/server.key {path}/ca.pem > {path}/cert.pem".format(path=FIXTURES_DIR)
1329+
]
1330+
for cmd in cmds:
1331+
execute_cmd = subprocess.check_output(["/bin/sh", "-c", cmd])
1332+
# Update s2s ssl settings
1333+
output = re.sub(r''' s2s:.*?ssl: false''', r''' s2s:
1334+
ca: /tmp/defaults/ca.pem
1335+
cert: /tmp/defaults/cert.pem
1336+
enable: true
1337+
password: {}
1338+
port: 9997
1339+
ssl: true'''.format(passphrase), output, flags=re.DOTALL)
1340+
# Write the default.yml to a file
1341+
with open(os.path.join(FIXTURES_DIR, "default.yml"), "w") as f:
1342+
f.write(output)
1343+
# Create the container and mount the default.yml
1344+
cid = None
1345+
try:
1346+
splunk_container_name = generate_random_string()
1347+
cid = self.client.create_container(self.UF_IMAGE_NAME, tty=True, ports=[8000, 8089],
1348+
volumes=["/tmp/defaults/"], name=splunk_container_name,
1349+
environment={"DEBUG": "true",
1350+
"SPLUNK_START_ARGS": "--accept-license",
1351+
"SPLUNK_PASSWORD": password},
1352+
host_config=self.client.create_host_config(binds=[FIXTURES_DIR + ":/tmp/defaults/"],
1353+
port_bindings={8089: ("0.0.0.0",), 8000: ("0.0.0.0",)})
1354+
)
1355+
cid = cid.get("Id")
1356+
self.client.start(cid)
1357+
# Poll for the container to be ready
1358+
assert self.wait_for_containers(1, name=splunk_container_name)
1359+
# Check splunkd
1360+
assert self.check_splunkd("admin", password)
1361+
# Check if the created file exists
1362+
exec_command = self.client.exec_create(cid, "cat /opt/splunkforwarder/etc/system/local/inputs.conf", user="splunk")
1363+
std_out = self.client.exec_start(exec_command)
1364+
assert "[splunktcp-ssl:9997]" in std_out
1365+
assert "serverCert = /tmp/defaults/cert.pem" in std_out
1366+
except Exception as e:
1367+
self.logger.error(e)
1368+
raise e
1369+
finally:
1370+
if cid:
1371+
self.client.remove_container(cid, v=True, force=True)
1372+
files = [
1373+
os.path.join(FIXTURES_DIR, "ca.key"),
1374+
os.path.join(FIXTURES_DIR, "ca.csr"),
1375+
os.path.join(FIXTURES_DIR, "ca.pem"),
1376+
os.path.join(FIXTURES_DIR, "server.key"),
1377+
os.path.join(FIXTURES_DIR, "server.csr"),
1378+
os.path.join(FIXTURES_DIR, "server.pem"),
1379+
os.path.join(FIXTURES_DIR, "cert.pem"),
1380+
os.path.join(FIXTURES_DIR, "default.yml")
1381+
]
1382+
self.cleanup_files(files)
1383+
12271384
def test_adhoc_1so_web_ssl(self):
12281385
# Generate a password
12291386
password = generate_random_string()

0 commit comments

Comments
 (0)