Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions docs/ADVANCED.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Let's dive into the nitty-gritty on how to tweak the setup of your containerized
* [Enable SmartStore](#enable-smartstore)
* [Using deployment servers](#using-deployment-servers)
* [Deploy distributed topology](#deploy-distributed-topology)
* [Enable SSL internal communication](#enable-ssl-internal-communication)
* [Build from source](#build-from-source)
* [base-debian-9](#base-debian-9)
* [splunk-debian-9](#splunk-debian-9)
Expand Down Expand Up @@ -248,6 +249,25 @@ While running a standalone Splunk instance may be fine for testing and developme

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

## Enable SSL Internal Communication
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.

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.
```
splunk:
...
s2s:
ca: /mnt/certs/ca.pem
cert: /mnt/certs/cert.pem
enable: true
password: abcd1234
port: 9997
ssl: true
...
```

For more instructions on how to bring your own certificates, please see: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates

## Build from source
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.

Expand Down
157 changes: 157 additions & 0 deletions tests/test_docker_splunk.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,15 @@ def teardown_method(self, method):
self.compose_file_name, self.project_name = None, None
self._clean_docker_env()

def cleanup_files(self, files):
try:
for file in files:
os.remove(file)
except OSError as e:
pass
except Exception as e:
raise e

def _clean_docker_env(self):
# Remove anything spun up by docker-compose
containers = self.client.containers(filters={"label": "com.docker.compose.version"})
Expand Down Expand Up @@ -1224,6 +1233,154 @@ def test_adhoc_1uf_hec_ssl_disabled(self):
except OSError:
pass

def test_adhoc_1so_splunktcp_ssl(self):
# Generate default.yml
cid = self.client.create_container(self.SPLUNK_IMAGE_NAME, tty=True, command="create-defaults")
self.client.start(cid.get("Id"))
output = self.get_container_logs(cid.get("Id"))
self.client.remove_container(cid.get("Id"), v=True, force=True)
# Get the password
password = re.search(" password: (.*)", output).group(1).strip()
assert password
# Commands to generate self-signed certificates for Splunk here: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates
passphrase = "abcd1234"
cmds = [
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/ca.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
"openssl req -new -key {path}/ca.key -passin pass:{pw} -out {path}/ca.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
"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),
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/server.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
"openssl req -new -passin pass:{pw} -key {path}/server.key -out {path}/server.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
"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),
"cat {path}/server.pem {path}/server.key {path}/ca.pem > {path}/cert.pem".format(path=FIXTURES_DIR)
]
for cmd in cmds:
execute_cmd = subprocess.check_output(["/bin/sh", "-c", cmd])
# Update s2s ssl settings
output = re.sub(r''' s2s:.*?ssl: false''', r''' s2s:
ca: /tmp/defaults/ca.pem
cert: /tmp/defaults/cert.pem
enable: true
password: {}
port: 9997
ssl: true'''.format(passphrase), output, flags=re.DOTALL)
# Write the default.yml to a file
with open(os.path.join(FIXTURES_DIR, "default.yml"), "w") as f:
f.write(output)
# Create the container and mount the default.yml
cid = None
try:
splunk_container_name = generate_random_string()
cid = self.client.create_container(self.SPLUNK_IMAGE_NAME, tty=True, ports=[8000, 8089],
volumes=["/tmp/defaults/"], name=splunk_container_name,
environment={"DEBUG": "true",
"SPLUNK_START_ARGS": "--accept-license",
"SPLUNK_PASSWORD": password},
host_config=self.client.create_host_config(binds=[FIXTURES_DIR + ":/tmp/defaults/"],
port_bindings={8089: ("0.0.0.0",), 8000: ("0.0.0.0",)})
)
cid = cid.get("Id")
self.client.start(cid)
# Poll for the container to be ready
assert self.wait_for_containers(1, name=splunk_container_name)
# Check splunkd
assert self.check_splunkd("admin", password)
# Check if the created file exists
exec_command = self.client.exec_create(cid, "cat /opt/splunk/etc/system/local/inputs.conf", user="splunk")
std_out = self.client.exec_start(exec_command)
assert "[splunktcp-ssl:9997]" in std_out
assert "serverCert = /tmp/defaults/cert.pem" in std_out
except Exception as e:
self.logger.error(e)
raise e
finally:
if cid:
self.client.remove_container(cid, v=True, force=True)
files = [
os.path.join(FIXTURES_DIR, "ca.key"),
os.path.join(FIXTURES_DIR, "ca.csr"),
os.path.join(FIXTURES_DIR, "ca.pem"),
os.path.join(FIXTURES_DIR, "server.key"),
os.path.join(FIXTURES_DIR, "server.csr"),
os.path.join(FIXTURES_DIR, "server.pem"),
os.path.join(FIXTURES_DIR, "cert.pem"),
os.path.join(FIXTURES_DIR, "default.yml")
]
self.cleanup_files(files)

def test_adhoc_1uf_splunktcp_ssl(self):
# Generate default.yml
cid = self.client.create_container(self.UF_IMAGE_NAME, tty=True, command="create-defaults")
self.client.start(cid.get("Id"))
output = self.get_container_logs(cid.get("Id"))
self.client.remove_container(cid.get("Id"), v=True, force=True)
# Get the password
password = re.search(" password: (.*)", output).group(1).strip()
assert password
# Commands to generate self-signed certificates for Splunk here: https://docs.splunk.com/Documentation/Splunk/latest/Security/ConfigureSplunkforwardingtousesignedcertificates
passphrase = "abcd1234"
cmds = [
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/ca.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
"openssl req -new -key {path}/ca.key -passin pass:{pw} -out {path}/ca.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
"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),
"openssl genrsa -aes256 -passout pass:{pw} -out {path}/server.key 2048".format(pw=passphrase, path=FIXTURES_DIR),
"openssl req -new -passin pass:{pw} -key {path}/server.key -out {path}/server.csr -subj /CN=localhost".format(pw=passphrase, path=FIXTURES_DIR),
"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),
"cat {path}/server.pem {path}/server.key {path}/ca.pem > {path}/cert.pem".format(path=FIXTURES_DIR)
]
for cmd in cmds:
execute_cmd = subprocess.check_output(["/bin/sh", "-c", cmd])
# Update s2s ssl settings
output = re.sub(r''' s2s:.*?ssl: false''', r''' s2s:
ca: /tmp/defaults/ca.pem
cert: /tmp/defaults/cert.pem
enable: true
password: {}
port: 9997
ssl: true'''.format(passphrase), output, flags=re.DOTALL)
# Write the default.yml to a file
with open(os.path.join(FIXTURES_DIR, "default.yml"), "w") as f:
f.write(output)
# Create the container and mount the default.yml
cid = None
try:
splunk_container_name = generate_random_string()
cid = self.client.create_container(self.UF_IMAGE_NAME, tty=True, ports=[8000, 8089],
volumes=["/tmp/defaults/"], name=splunk_container_name,
environment={"DEBUG": "true",
"SPLUNK_START_ARGS": "--accept-license",
"SPLUNK_PASSWORD": password},
host_config=self.client.create_host_config(binds=[FIXTURES_DIR + ":/tmp/defaults/"],
port_bindings={8089: ("0.0.0.0",), 8000: ("0.0.0.0",)})
)
cid = cid.get("Id")
self.client.start(cid)
# Poll for the container to be ready
assert self.wait_for_containers(1, name=splunk_container_name)
# Check splunkd
assert self.check_splunkd("admin", password)
# Check if the created file exists
exec_command = self.client.exec_create(cid, "cat /opt/splunkforwarder/etc/system/local/inputs.conf", user="splunk")
std_out = self.client.exec_start(exec_command)
assert "[splunktcp-ssl:9997]" in std_out
assert "serverCert = /tmp/defaults/cert.pem" in std_out
except Exception as e:
self.logger.error(e)
raise e
finally:
if cid:
self.client.remove_container(cid, v=True, force=True)
files = [
os.path.join(FIXTURES_DIR, "ca.key"),
os.path.join(FIXTURES_DIR, "ca.csr"),
os.path.join(FIXTURES_DIR, "ca.pem"),
os.path.join(FIXTURES_DIR, "server.key"),
os.path.join(FIXTURES_DIR, "server.csr"),
os.path.join(FIXTURES_DIR, "server.pem"),
os.path.join(FIXTURES_DIR, "cert.pem"),
os.path.join(FIXTURES_DIR, "default.yml")
]
self.cleanup_files(files)

def test_adhoc_1so_web_ssl(self):
# Generate a password
password = generate_random_string()
Expand Down