Skip to content

Commit

Permalink
feat: Edge Processor (#2328)
Browse files Browse the repository at this point in the history
* feat: adopot EP HEC implementation for SC4S

* feat: implement mTLS for EP

* feat: automation k8s secret creation of mTLS

* docs: describe mTLS encryption

* docs: review edge processor documentation (#2402)

* docs: Edge Processor docs

* Update edge_processor.md

Hi, please take a look at my edits to make sure i did not accidentally misinterpret the meaning of the original text. I'll do another final pass after that.

* Update edge_processor.md

* Update edge_processor.md

Updated docs based on feedback

* Update edge_processor.md

updated line 40 based on feedback

* docs: fix logical mistakes

---------

Co-authored-by: Ilya Kheifets <[email protected]>

* fix: small improvements

* fix: make generic deploy certs

---------

Co-authored-by: JENNIFER WORTHINGTON <[email protected]>
  • Loading branch information
ikheifets-splunk and jenworthington authored May 13, 2024
1 parent a265bad commit d4e4e79
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 3 deletions.
1 change: 1 addition & 0 deletions ansible/playbooks/microk8s.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@
openebs: true
tasks:
- include_tasks: ../tasks/mk8s/install_mk8s.yml
- include_tasks: ../tasks/mk8s/deploy_secrets.yml
- include_tasks: ../tasks/mk8s/install_helm_repo.yml
- include_tasks: ../tasks/mk8s/deploy_app.yml
1 change: 1 addition & 0 deletions ansible/playbooks/microk8s_ha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
openebs: true
tasks:
- include_tasks: ../tasks/mk8s/install_mk8s.yml
- include_tasks: ../tasks/mk8s/deploy_secrets.yml
- include_tasks: ../tasks/mk8s/install_helm_repo.yml
- include_tasks: ../tasks/mk8s/deploy_app.yml
- include_tasks: ../tasks/mk8s/get_registration_token.yml
Expand Down
25 changes: 25 additions & 0 deletions ansible/tasks/mk8s/deploy_secrets.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
- name: Load k8s secrets
include_vars:
file: "{{ item }}"
with_first_found:
- files:
- /opt/ansible/resources/k8s_secrets.yaml
- /opt/charts/splunk-connect-for-syslog/secrets.yaml

- name: Create mTLS secret
ansible.builtin.shell: |
microk8s kubectl apply -f - <<EOF
apiVersion: v1
kind: Secret
metadata:
name: {{ hec_tls.secret }}
type: Opaque
data:
key.pem: {{ hec_tls.value.key | b64encode }}
cert.pem: {{ hec_tls.value.cert | b64encode }}
ca_cert.pem: {{ hec_tls.value.ca | b64encode }}
EOF
when:
- hec_tls is defined
- ('secret' in hec_tls) and ('value' in hec_tls)
Empty file.
14 changes: 14 additions & 0 deletions charts/splunk-connect-for-syslog/templates/statefulset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ spec:
- name: SC4S_DEST_SPLUNK_HEC_DEFAULT_DISKBUFF_ENABLE
value: "no"
{{- end }}
{{- if .Values.splunk.hec_tls }}
- name: SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT
value: "/etc/syslog-ng/tls/hec"
{{- end }}
{{- if .Values.sc4s.existingCert }}
- name: SC4S_SOURCE_TLS_ENABLE
value: "yes"
Expand Down Expand Up @@ -186,6 +190,11 @@ spec:
- name: data
mountPath: /var/lib/syslog-ng/
{{- end }}
{{- if .Values.splunk.hec_tls }}
- name: hec-tls
mountPath: /etc/syslog-ng/tls/hec/
readOnly: true
{{- end }}
{{- if .Values.sc4s.existingCert }}
- name: tls
mountPath: /etc/syslog-ng/tls/
Expand Down Expand Up @@ -224,6 +233,11 @@ spec:
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
{{- if .Values.splunk.hec_tls }}
- name: hec-tls
secret:
secretName: {{ .Values.splunk.hec_tls }}
{{- end }}
{{- if .Values.sc4s.existingCert }}
- name: tls
secret:
Expand Down
113 changes: 113 additions & 0 deletions docs/edge_processor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Edge Processor integration guide (Experimental)

## Intro

You can use the `Edge Processor` to:

* Enrich log messages with extra data, such as adding a new field or overriding an index using `SPL2`.
* Filter log messages using `SPL2`.
* Send log messages to alternative destinations, for example, `AWS S3` or `Apache Kafka`.

## How it works

```mermaid
stateDiagram
direction LR
SC4S: SC4S
EP: Edge Processor
Dest: Another destination
Device: Your device
S3: AWS S3
Instance: Instance
Pipeline: Pipeline with SPL2
Device --> SC4S: Syslog protocol
SC4S --> EP: HEC
state EP {
direction LR
Instance --> Pipeline
}
EP --> Splunk
EP --> S3
EP --> Dest
```

## Set up the Edge Processor for SC4S

### Set up on Docker / Podman

1. On the `env_file`, configure the HEC URL as IP of *managed instance*, that you registered on Edge Processor.
2. Add your HEC token. You can find your token in the Edge Processor "global settings" page.

```
SC4S_DEST_SPLUNK_HEC_DEFAULT_URL=http://x.x.x.x:8088
SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
```

### Kubernetes

1. Set up the Edge Processor on your `values.yaml` HEC URL using the IP of *managed instance*, that you registered on Edge Processor.

2. Provide the hec_token. You can find this token on the Edge Processor's "global settings" page.

```
splunk:
hec_url: "http://x.x.x.x:8088"
hec_token: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
```

## mTLS encryption

### Prepare your certificates

Before setup, [generate mTLS certificates](https://docs.splunk.com/Documentation/SplunkCloud/9.1.2308/EdgeProcessor/SecureForwarders). Server mTLS certificates should be uploaded to `Edge Processor` and client certifcates should be used with `SC4S`.

Rename the certificate files. SC4S requires the following names:

* `key.pem` - client certificate key
* `cert.pem` - client certificate
* `ca_cert.pem` - certificate authority

### Docker / Podman

1. Use HTTPS in HEC url: `SC4S_DEST_SPLUNK_HEC_DEFAULT_URL=https://x.x.x.x:8088`.
2. Move your clients mTLS certificates to `/opt/sc4s/tls/hec`.
3. Mount `/opt/sc4s/tls/hec` to `/etc/syslog-ng/tls/hec` using docker/podman volumes.
4. Define mounting mTLS point for HEC: `SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT=/etc/syslog-ng/tls/hec`.
5. Start or restart SC4S.

### Kubernetes

1. Add the secret name of the mTLS certificates to the `values.yaml` file:

```
splunk:
hec_url: "https://x.x.x.x:8088"
hec_token: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
hec_tls: "hec-tls-secret"
```

2. Add your mTLS certificates to the `charts/splunk-connect-for-syslog/secrets.yaml` file:

```
hec_tls:
secret: "hec-tls-secret"
value:
key: |
-----BEGIN PRIVATE KEY-----
Exmaple key
-----END PRIVATE KEY-----
cert: |
-----BEGIN CERTIFICATE-----
Exmaple cert
-----END CERTIFICATE-----
ca: |
-----BEGIN CERTIFICATE-----
Example ca
-----END CERTIFICATE-----
```

3. Encrypt your `secrets.yaml` using `ansible-vault encrypt charts/splunk-connect-for-syslog/secrets.yaml`.
4. Add the IP address for your cluster nodes to the inventory file `ansible/inventory/inventory_microk8s_ha.yaml`.
5. Deploy the Ansible playbook `ansible-playbook -i ansible/inventory/inventory_microk8s_ha.yaml ansible/playbooks/microk8s_ha.yml --ask-vault-pass`
6 changes: 6 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ markdown_extensions:
- sane_lists
- codehilite
- pymdownx.snippets
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format


theme:
Expand Down Expand Up @@ -57,6 +62,7 @@ nav:
- SC4S Lite (Experimental):
- Intro: "lite.md"
- Pluggable modules: "pluggable_modules.md"
- Edge Processor (Experimental): "edge_processor.md"
- Troubleshooting:
- SC4S Startup and Validation: "troubleshooting/troubleshoot_SC4S_server.md"
- SC4S Logging and Troubleshooting Resources: "troubleshooting/troubleshoot_resources.md"
Expand Down
2 changes: 1 addition & 1 deletion package/etc/conf.d/conflib/_common/t_templates.conf
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ template t_JSON_5424_SDATA {

template t_splunk_hec {
template('$(format-json
time=$(if ("${.netsource.sc4s_use_recv_time}" eq "yes") "$R_UNIXTIME" "$S_UNIXTIME")
time=$(if ("${.netsource.sc4s_use_recv_time}" eq "yes") ${R_UNIXTIME} ${S_UNIXTIME})
host=$(lowercase ${HOST})
source=${.splunk.source:-SC4S}
sourcetype=${.splunk.sourcetype:-sc4s:fallback}
Expand Down
5 changes: 5 additions & 0 deletions package/etc/conf.d/destinations/dest_hec/plugin.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ destination d_hec{{ dest_mode }}{{ altname }}{
{%- endif %}
tls(
peer-verify({{ peer_verify }})
{% if tls_mount %}
key-file("{{ tls_mount }}/key.pem")
cert-file("{{ tls_mount }}/cert.pem")
ca-dir("{{ tls_mount }}")
{% endif %}
{%- if cipher_suite %}
cipher-suite("{{ cipher_suite }}")
{%- endif %}
Expand Down
1 change: 1 addition & 0 deletions package/etc/conf.d/destinations/dest_hec/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def hec_endpoint_collector(hec_path, url_hec):
f"SC4S_DEST_SPLUNK_HEC_{group}_DISKBUFF_DISKBUFSIZE",
int(disk_space / workers),
),
tls_mount=os.getenv(f"SC4S_DEST_SPLUNK_HEC_{group}_TLS_MOUNT"),
peer_verify=os.getenv(f"SC4S_DEST_SPLUNK_HEC_{group}_TLS_VERIFY", "yes"),
cipher_suite=os.getenv(f"SC4S_DEST_SPLUNK_HEC_{group}_CIPHER_SUITE"),
ssl_version=os.getenv(f"SC4S_DEST_SPLUNK_HEC_{group}_SSL_VERSION"),
Expand Down
11 changes: 9 additions & 2 deletions package/sbin/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,25 @@ if [ "$SC4S_DEST_SPLUNK_HEC_GLOBAL" != "no" ]
then
HEC=$(echo $SC4S_DEST_SPLUNK_HEC_DEFAULT_URL | cut -d' ' -f 1)
if [ "${SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_VERIFY}" == "no" ]; then export NO_VERIFY=-k ; fi

if [ -n "${SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT}" ]; then
export HEC_TLS_OPTS="--cert ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT}/cert.pem --key ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT}/key.pem --cacert ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TLS_MOUNT}/ca_cert.pem";
else
export HEC_TLS_OPTS="";
fi

SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX=$(grep -Po '(?<=^splunk_sc4s_fallback,index,).*' -m1 $SC4S_ETC/conf.d/local/context/splunk_metadata.csv )
export SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX=${SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX:=main}
SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX=$(cat $SC4S_ETC/conf.d/local/context/splunk_metadata.csv | grep ',index,' | grep sc4s_events | cut -d, -f 3)
export SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX=${SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX:=main}

if curl -s -S ${NO_VERIFY} "${HEC}" -H "Authorization: Splunk ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN}" -d "{\"event\": \"HEC TEST EVENT\", \"sourcetype\": \"sc4s:probe\", \"index\": \"${SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX}\"}" 2>&1 | grep -v '{"text":"Success"'
if curl -s -S ${NO_VERIFY} "${HEC}" -H "Authorization: Splunk ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN}" -d "{\"event\": \"HEC TEST EVENT\", \"sourcetype\": \"sc4s:probe\", \"index\": \"${SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX}\"}" ${HEC_TLS_OPTS} 2>&1 | grep -v -e '{"text":"Success"' -e '{"text": "Success"'
then
echo -e "SC4S_ENV_CHECK_HEC: Invalid Splunk HEC URL, invalid token, or other HEC connectivity issue index=${SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX}. sourcetype=sc4s:fallback\nStartup will continue to prevent data loss if this is a transient failure."
echo ""
else
echo -e "SC4S_ENV_CHECK_HEC: Splunk HEC connection test successful to index=${SC4S_DEST_SPLUNK_HEC_FALLBACK_INDEX} for sourcetype=sc4s:fallback..."
if curl -s -S ${NO_VERIFY} "${HEC}" -H "Authorization: Splunk ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN}" -d "{\"event\": \"HEC TEST EVENT\", \"sourcetype\": \"sc4s:probe\", \"index\": \"${SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX}\"}" 2>&1 | grep -v '{"text":"Success"'
if curl -s -S ${NO_VERIFY} "${HEC}" -H "Authorization: Splunk ${SC4S_DEST_SPLUNK_HEC_DEFAULT_TOKEN}" -d "{\"event\": \"HEC TEST EVENT\", \"sourcetype\": \"sc4s:probe\", \"index\": \"${SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX}\"}" ${HEC_TLS_OPTS} 2>&1 | grep -v -e '{"text":"Success"' -e '{"text": "Success"'
then
echo -e "SC4S_ENV_CHECK_HEC: Invalid Splunk HEC URL, invalid token, or other HEC connectivity issue for index=${SC4S_DEST_SPLUNK_HEC_EVENTS_INDEX}. sourcetype=sc4s:events \nStartup will continue to prevent data loss if this is a transient failure."
echo ""
Expand Down

0 comments on commit d4e4e79

Please sign in to comment.