mirror of
https://github.com/Security-Onion-Solutions/securityonion.git
synced 2026-10-23 22:53:03 +02:00
Compare commits
88
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c584675259 | ||
|
|
84b2b19698 | ||
|
|
2eab084358 | ||
|
|
f4b301d71c | ||
|
|
f7dbfba178 | ||
|
|
0a628bb7e7 | ||
|
|
bd6647e775 | ||
|
|
da2c19188a | ||
|
|
90b3d37be6 | ||
|
|
fcd2f67076 | ||
|
|
a9cdd17694 | ||
|
|
b32aaac290 | ||
|
|
1aee3f28dc | ||
|
|
678cb0d5b2 | ||
|
|
31c5190a1f | ||
|
|
4ce7a06abe | ||
|
|
ba95b9bbc2 | ||
|
|
43475452b3 | ||
|
|
99322cf26a | ||
|
|
117548757f | ||
|
|
22bda63847 | ||
|
|
2a4611df45 | ||
|
|
89f8bcd19f | ||
|
|
563269cbac | ||
|
|
523c39d4f2 | ||
|
|
b4557e973c | ||
|
|
0f53a7e0bc | ||
|
|
8de8ba811a | ||
|
|
d122ee7fea | ||
|
|
9732e1c639 | ||
|
|
53f9ebcd46 | ||
|
|
47d74f1ae1 | ||
|
|
855716846a | ||
|
|
8e35d70595 | ||
|
|
e4625cfcae | ||
|
|
eb803dce0e | ||
|
|
a06f08217a | ||
|
|
29d27cf255 | ||
|
|
235a60e587 | ||
|
|
a8f7c46b0d | ||
|
|
26d895ccb7 | ||
|
|
b43efc458f | ||
|
|
21222ff119 | ||
|
|
88fa7e7fb4 | ||
|
|
efe0581892 | ||
|
|
72f60fcaa9 | ||
|
|
2684a5ca95 | ||
|
|
bcee63bde5 | ||
|
|
6ce89eb323 | ||
|
|
ebab4b0d90 | ||
|
|
db60c27da2 | ||
|
|
f4defdfde0 | ||
|
|
36652e8f23 | ||
|
|
7bef194540 | ||
|
|
e2bf2837fe | ||
|
|
06704dad22 | ||
|
|
47fe0758d0 | ||
|
|
b71fd93f9d | ||
|
|
d9eff9aa9e | ||
|
|
d8884dbd99 | ||
|
|
6c0d4c15e8 | ||
|
|
2e2f62f265 | ||
|
|
b7a11a525c | ||
|
|
8eef95ea3e | ||
|
|
65e261475d | ||
|
|
bbc28c88b7 | ||
|
|
edaacf79a7 | ||
|
|
ecc643cd33 | ||
|
|
08aaf7948e | ||
|
|
bb57545d08 | ||
|
|
0f7adbbecc | ||
|
|
aeb4fe8f50 | ||
|
|
f3aa39c5a4 | ||
|
|
24077ba974 | ||
|
|
b3567405f9 | ||
|
|
1fc5bb7afa | ||
|
|
1f1d3ded41 | ||
|
|
1e86be11b2 | ||
|
|
f4518e2620 | ||
|
|
a9f7ffc3fe | ||
|
|
b018277d68 | ||
|
|
3be603e203 | ||
|
|
84cd966736 | ||
|
|
fee401a912 | ||
|
|
496b61966f | ||
|
|
56e3e44d04 | ||
|
|
9652a2053b | ||
|
|
cf3a4ebc27 |
No files matched your search
@@ -6,6 +6,9 @@ on:
|
|||||||
- "salt/sensoroni/files/analyzers/**"
|
- "salt/sensoroni/files/analyzers/**"
|
||||||
- "salt/manager/tools/sbin/**"
|
- "salt/manager/tools/sbin/**"
|
||||||
- "salt/_beacons/**"
|
- "salt/_beacons/**"
|
||||||
|
- "salt/telegraf/tools/sbin_jinja/**"
|
||||||
|
- "salt/telegraf/defaults.yaml"
|
||||||
|
- "salt/telegraf/soc_telegraf.yaml"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -34,3 +37,25 @@ jobs:
|
|||||||
- name: Test with pytest
|
- name: Test with pytest
|
||||||
run: |
|
run: |
|
||||||
PYTHONPATH=${{ matrix.python-code-path }} pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=pytest.ini
|
PYTHONPATH=${{ matrix.python-code-path }} pytest ${{ matrix.python-code-path }} --cov=${{ matrix.python-code-path }} --doctest-modules --cov-report=term --cov-fail-under=100 --cov-config=pytest.ini
|
||||||
|
|
||||||
|
telegraf-collector:
|
||||||
|
# so-container-stats is a jinja template rather than an importable module, so it gets its
|
||||||
|
# own job: the test renders it the way salt does, then drives it with a faked docker engine
|
||||||
|
# and cgroup tree. No container runtime is needed.
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v3
|
||||||
|
with:
|
||||||
|
python-version: "3.14"
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
python -m pip install flake8 pytest jinja2 pyyaml
|
||||||
|
- name: Lint with flake8
|
||||||
|
run: |
|
||||||
|
flake8 salt/telegraf/tools/sbin_jinja/so-container-stats_test.py --config=pytest.ini
|
||||||
|
- name: Test with pytest
|
||||||
|
run: |
|
||||||
|
pytest salt/telegraf/tools/sbin_jinja/so-container-stats_test.py -v
|
||||||
+20
-5
@@ -117,14 +117,25 @@ elastic_curl_config:
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
|
# A non-root owner here can chmod the directory and replace any script in it, including
|
||||||
|
# the root-owned ones. 555 is the mode the filesystem RPM ships; root ignores it anyway.
|
||||||
|
usr_sbin_perms:
|
||||||
|
file.directory:
|
||||||
|
- name: /usr/sbin
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 555
|
||||||
|
|
||||||
common_sbin:
|
common_sbin:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://common/tools/sbin
|
- source: salt://common/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
- require:
|
||||||
|
- file: usr_sbin_perms
|
||||||
{% if GLOBALS.role == 'so-heavynode' %}
|
{% if GLOBALS.role == 'so-heavynode' %}
|
||||||
- exclude_pat:
|
- exclude_pat:
|
||||||
- so-pcap-import
|
- so-pcap-import
|
||||||
@@ -159,8 +170,8 @@ common_sbin_jinja:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://common/tools/sbin_jinja
|
- source: salt://common/tools/sbin_jinja
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
@@ -173,6 +184,8 @@ so-status_script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-status
|
- name: /usr/sbin/so-status
|
||||||
- source: salt://common/tools/sbin/so-status
|
- source: salt://common/tools/sbin/so-status
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
|
|
||||||
{% if GLOBALS.is_sensor %}
|
{% if GLOBALS.is_sensor %}
|
||||||
@@ -204,9 +217,11 @@ sostatus_log:
|
|||||||
- replace: False
|
- replace: False
|
||||||
|
|
||||||
# Install sostatus check cron. This is used to populate Grid.
|
# Install sostatus check cron. This is used to populate Grid.
|
||||||
|
# telegraf reads status.log on the same minute boundary this runs, so write aside and rename
|
||||||
|
# rather than truncating the file it is reading
|
||||||
so-status_check_cron:
|
so-status_check_cron:
|
||||||
cron.present:
|
cron.present:
|
||||||
- name: '/usr/sbin/so-status -j > /opt/so/log/sostatus/status.log 2>&1'
|
- name: '/usr/sbin/so-status -j > /opt/so/log/sostatus/status.log.tmp 2>&1; mv -f /opt/so/log/sostatus/status.log.tmp /opt/so/log/sostatus/status.log'
|
||||||
- identifier: so-status_check_cron
|
- identifier: so-status_check_cron
|
||||||
- user: root
|
- user: root
|
||||||
- minute: '*/1'
|
- minute: '*/1'
|
||||||
|
|||||||
@@ -18,47 +18,61 @@ copy_so-common_common_tools_sbin:
|
|||||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-common
|
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-common
|
||||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-image-common_common_tools_sbin:
|
copy_so-image-common_common_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-image-common
|
- name: /opt/so/saltstack/default/salt/common/tools/sbin/so-image-common
|
||||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_soup_manager_tools_sbin:
|
copy_soup_manager_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/soup
|
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/soup
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-firewall_manager_tools_sbin:
|
copy_so-firewall_manager_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-firewall
|
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-firewall
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-yaml_manager_tools_sbin:
|
copy_so-yaml_manager_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-yaml.py
|
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-yaml.py
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-repo-sync_manager_tools_sbin:
|
copy_so-repo-sync_manager_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-repo-sync
|
- name: /opt/so/saltstack/default/salt/manager/tools/sbin/so-repo-sync
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_bootstrap-salt_manager_tools_sbin:
|
copy_bootstrap-salt_manager_tools_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /opt/so/saltstack/default/salt/salt/scripts/bootstrap-salt.sh
|
- name: /opt/so/saltstack/default/salt/salt/scripts/bootstrap-salt.sh
|
||||||
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 644
|
||||||
|
|
||||||
# This section is used to put the new script in place so that it can be called during soup.
|
# This section is used to put the new script in place so that it can be called during soup.
|
||||||
# It is faster than calling the states that normally manage them to put them in place.
|
# It is faster than calling the states that normally manage them to put them in place.
|
||||||
@@ -67,46 +81,60 @@ copy_so-common_sbin:
|
|||||||
- name: /usr/sbin/so-common
|
- name: /usr/sbin/so-common
|
||||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-common
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-image-common_sbin:
|
copy_so-image-common_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/so-image-common
|
- name: /usr/sbin/so-image-common
|
||||||
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
- source: {{UPDATE_DIR}}/salt/common/tools/sbin/so-image-common
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_soup_sbin:
|
copy_soup_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/soup
|
- name: /usr/sbin/soup
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/soup
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-firewall_sbin:
|
copy_so-firewall_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/so-firewall
|
- name: /usr/sbin/so-firewall
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-firewall
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-yaml_sbin:
|
copy_so-yaml_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/so-yaml.py
|
- name: /usr/sbin/so-yaml.py
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-yaml.py
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_so-repo-sync_sbin:
|
copy_so-repo-sync_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/so-repo-sync
|
- name: /usr/sbin/so-repo-sync
|
||||||
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
- source: {{UPDATE_DIR}}/salt/manager/tools/sbin/so-repo-sync
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
|
|
||||||
copy_bootstrap-salt_sbin:
|
copy_bootstrap-salt_sbin:
|
||||||
file.copy:
|
file.copy:
|
||||||
- name: /usr/sbin/bootstrap-salt.sh
|
- name: /usr/sbin/bootstrap-salt.sh
|
||||||
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
- source: {{UPDATE_DIR}}/salt/salt/scripts/bootstrap-salt.sh
|
||||||
- force: True
|
- force: True
|
||||||
- preserve: True
|
- user: root
|
||||||
|
- group: root
|
||||||
|
- mode: 755
|
||||||
@@ -240,7 +240,8 @@ copy_new_files() {
|
|||||||
cd $UPDATE_DIR
|
cd $UPDATE_DIR
|
||||||
rsync -a salt $DEFAULT_SALT_DIR/ --delete "${EXCLUDE_ARGS[@]}"
|
rsync -a salt $DEFAULT_SALT_DIR/ --delete "${EXCLUDE_ARGS[@]}"
|
||||||
rsync -a pillar $DEFAULT_SALT_DIR/ --delete "${EXCLUDE_ARGS[@]}"
|
rsync -a pillar $DEFAULT_SALT_DIR/ --delete "${EXCLUDE_ARGS[@]}"
|
||||||
chown -R socore:socore $DEFAULT_SALT_DIR/
|
# Root-executed code; SOC only needs to read it. Local dirs stay socore-owned.
|
||||||
|
chown -R root:root $DEFAULT_SALT_DIR/
|
||||||
cd /tmp
|
cd /tmp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import sys
|
|||||||
import subprocess
|
import subprocess
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
import tempfile
|
||||||
|
|
||||||
sys.path.append('/opt/saltstack/salt/lib/python3.10/site-packages/')
|
sys.path.append('/opt/saltstack/salt/lib/python3.10/site-packages/')
|
||||||
import salt.config
|
import salt.config
|
||||||
@@ -17,6 +18,21 @@ import salt.loader
|
|||||||
__opts__ = salt.config.minion_config('/etc/salt/minion')
|
__opts__ = salt.config.minion_config('/etc/salt/minion')
|
||||||
__grains__ = salt.loader.grains(__opts__)
|
__grains__ = salt.loader.grains(__opts__)
|
||||||
|
|
||||||
|
def write_atomic(path, value):
|
||||||
|
# telegraf reads these files on its own schedule; replacing them by rename means it never
|
||||||
|
# reads a truncated file and reports an empty value as if it were real
|
||||||
|
directory = os.path.dirname(path)
|
||||||
|
handle, temp = tempfile.mkstemp(dir=directory)
|
||||||
|
try:
|
||||||
|
with os.fdopen(handle, 'w') as f:
|
||||||
|
f.write(str(value))
|
||||||
|
os.chmod(temp, 0o644)
|
||||||
|
os.replace(temp, path)
|
||||||
|
except Exception:
|
||||||
|
os.path.exists(temp) and os.unlink(temp)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def check_needs_restarted():
|
def check_needs_restarted():
|
||||||
osfam = __grains__['os_family']
|
osfam = __grains__['os_family']
|
||||||
val = '0'
|
val = '0'
|
||||||
@@ -34,8 +50,7 @@ def check_needs_restarted():
|
|||||||
else:
|
else:
|
||||||
fail("Unsupported OS")
|
fail("Unsupported OS")
|
||||||
|
|
||||||
with open(outfile, 'w') as f:
|
write_atomic(outfile, val)
|
||||||
f.write(val)
|
|
||||||
|
|
||||||
def check_for_fps():
|
def check_for_fps():
|
||||||
feat = 'fps'
|
feat = 'fps'
|
||||||
@@ -56,8 +71,7 @@ def check_for_fps():
|
|||||||
# Unknown, so assume 0
|
# Unknown, so assume 0
|
||||||
fps = 0
|
fps = 0
|
||||||
|
|
||||||
with open('/opt/so/log/sostatus/fps_enabled', 'w') as f:
|
write_atomic('/opt/so/log/sostatus/fps_enabled', fps)
|
||||||
f.write(str(fps))
|
|
||||||
|
|
||||||
def check_for_lks():
|
def check_for_lks():
|
||||||
feat = 'Lks'
|
feat = 'Lks'
|
||||||
@@ -80,8 +94,7 @@ def check_for_lks():
|
|||||||
lks = 1
|
lks = 1
|
||||||
if lks:
|
if lks:
|
||||||
break
|
break
|
||||||
with open('/opt/so/log/sostatus/lks_enabled', 'w') as f:
|
write_atomic('/opt/so/log/sostatus/lks_enabled', lks)
|
||||||
f.write(str(lks))
|
|
||||||
|
|
||||||
def fail(msg):
|
def fail(msg):
|
||||||
print(msg, file=sys.stderr)
|
print(msg, file=sys.stderr)
|
||||||
|
|||||||
@@ -177,6 +177,8 @@ if [[ $EXCLUDE_FALSE_POSITIVE_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unexpected authorization header" # expected WARN log lines indicating invalid auth header
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Unexpected authorization header" # expected WARN log lines indicating invalid auth header
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Missing ory_kratos_session cookie" # expected WARN log lines indicating invalid auth header
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Missing ory_kratos_session cookie" # expected WARN log lines indicating invalid auth header
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Static assets preprocessor only supports GET and HEAD requests" # expected WARN log lines indicating invalid auth header
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Static assets preprocessor only supports GET and HEAD requests" # expected WARN log lines indicating invalid auth header
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|respondError" # respondError is a function name, output via http middleware as standard request logging
|
||||||
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|GET /kibana/" # Ignore Kibana queries with triggered words
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
||||||
@@ -240,7 +242,7 @@ if [[ $EXCLUDE_KNOWN_ERRORS == 'Y' ]]; then
|
|||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|marked for removal" # docker container getting recycled
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|marked for removal" # docker container getting recycled
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tcp 127.0.0.1:6791: bind: address already in use" # so-elastic-fleet agent restarting. Seen starting w/ 8.18.8 https://github.com/elastic/kibana/issues/201459
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|tcp 127.0.0.1:6791: bind: address already in use" # so-elastic-fleet agent restarting. Seen starting w/ 8.18.8 https://github.com/elastic/kibana/issues/201459
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|TransformTask\] \[logs-.*user so_kibana lacks the required permissions" # Known issue with integrations starting transform jobs that are explicitly not allowed to start as a system user
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|TransformTask\] \[logs-.*user so_kibana lacks the required permissions" # Known issue with integrations starting transform jobs that are explicitly not allowed to start as a system user
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|manifest unknown" # appears in so-dockerregistry log for so-tcpreplay following docker upgrade to 29.2.1-1
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|manifest unknown" # so-dockerregistry logs a tag lookup miss during image copy; not tied to one docker version
|
||||||
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Could not index event to Elasticsearch.*\"version\" => \"9.0.8\"" # Expected during Elastic upgrade temporarily, as policies referencing older pipelines are updated
|
EXCLUDED_ERRORS="$EXCLUDED_ERRORS|Could not index event to Elasticsearch.*\"version\" => \"9.0.8\"" # Expected during Elastic upgrade temporarily, as policies referencing older pipelines are updated
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -8,21 +8,37 @@
|
|||||||
# Elastic License 2.0.
|
# Elastic License 2.0.
|
||||||
|
|
||||||
|
|
||||||
SENSOR_DIR='/nsm'
|
SENSOR_DIR="${SENSOR_DIR:-/nsm}"
|
||||||
CRIT_DISK_USAGE=90
|
CRIT_DISK_USAGE=90
|
||||||
CUR_USAGE=$(df -P $SENSOR_DIR | tail -1 | awk '{print $5}' | tr -d %)
|
LOG="${LOG:-/opt/so/log/sensor_clean.log}"
|
||||||
LOG="/opt/so/log/sensor_clean.log"
|
LOCK="${LOCK:-/var/tmp/so-sensor-clean.lock}"
|
||||||
TODAY=$(date -u "+%Y-%m-%d")
|
MAX_PASSES=100
|
||||||
|
|
||||||
|
ZEEK_LOGS="$SENSOR_DIR/zeek/logs"
|
||||||
|
STRELKA_FILES="$SENSOR_DIR/strelka/processed"
|
||||||
|
SURICATA_LOGS="$SENSOR_DIR/suricata"
|
||||||
|
PCAPS="$SENSOR_DIR/pcapout"
|
||||||
|
|
||||||
|
log() {
|
||||||
|
echo "$(date) - $*" >>"$LOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_usage() {
|
||||||
|
df -P "$SENSOR_DIR" | tail -1 | awk '{print $5}' | tr -d %
|
||||||
|
}
|
||||||
|
|
||||||
|
disk_avail() {
|
||||||
|
df -P "$SENSOR_DIR" | tail -1 | awk '{print $4}'
|
||||||
|
}
|
||||||
|
|
||||||
|
# sets REMOVED=1 if anything was actually deleted
|
||||||
clean() {
|
clean() {
|
||||||
## find the oldest Zeek logs directory
|
## find the oldest Zeek logs directory
|
||||||
OLDEST_DIR=$(ls /nsm/zeek/logs/ | grep -v "current" | grep -v "stats" | grep -v "packetloss" | grep -v "zeek_clean" | sort | head -n 1)
|
OLDEST_DIR=$(ls "$ZEEK_LOGS" 2>/dev/null | grep -v "current" | grep -v "stats" | grep -v "packetloss" | grep -v "zeek_clean" | sort | head -n 1)
|
||||||
if [ -z "$OLDEST_DIR" -o "$OLDEST_DIR" == ".." -o "$OLDEST_DIR" == "." ]; then
|
if [ -n "$OLDEST_DIR" ]; then
|
||||||
echo "$(date) - No old Zeek logs available to clean up in /nsm/zeek/logs/" >>$LOG
|
log "Removing directory: $ZEEK_LOGS/$OLDEST_DIR"
|
||||||
#exit 0
|
rm -rf "$ZEEK_LOGS/$OLDEST_DIR"
|
||||||
else
|
REMOVED=1
|
||||||
echo "$(date) - Removing directory: /nsm/zeek/logs/$OLDEST_DIR" >>$LOG
|
|
||||||
rm -rf /nsm/zeek/logs/"$OLDEST_DIR"
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## Remarking for now, as we are moving extracted files to /nsm/strelka/processed
|
## Remarking for now, as we are moving extracted files to /nsm/strelka/processed
|
||||||
@@ -43,58 +59,73 @@ clean() {
|
|||||||
#fi
|
#fi
|
||||||
|
|
||||||
## Clean up Zeek extracted files processed by Strelka
|
## Clean up Zeek extracted files processed by Strelka
|
||||||
STRELKA_FILES='/nsm/strelka/processed'
|
OLDEST_STRELKA=$(find "$STRELKA_FILES" -type f -printf '%T+ %p\n' 2>/dev/null | sort -n | head -n 1)
|
||||||
OLDEST_STRELKA=$(find $STRELKA_FILES -type f -printf '%T+ %p\n' | sort -n | head -n 1)
|
if [ -n "$OLDEST_STRELKA" ]; then
|
||||||
if [ -z "$OLDEST_STRELKA" -o "$OLDEST_STRELKA" == ".." -o "$OLDEST_STRELKA" == "." ]; then
|
|
||||||
echo "$(date) - No old files available to clean up in $STRELKA_FILES" >>$LOG
|
|
||||||
else
|
|
||||||
OLDEST_STRELKA_DATE=$(echo $OLDEST_STRELKA | awk '{print $1}' | cut -d+ -f1)
|
OLDEST_STRELKA_DATE=$(echo $OLDEST_STRELKA | awk '{print $1}' | cut -d+ -f1)
|
||||||
OLDEST_STRELKA_FILE=$(echo $OLDEST_STRELKA | awk '{print $2}')
|
log "Removing extracted files for $OLDEST_STRELKA_DATE"
|
||||||
echo "$(date) - Removing extracted files for $OLDEST_STRELKA_DATE" >>$LOG
|
REMOVED=1
|
||||||
find $STRELKA_FILES -type f -printf '%T+ %p\n' | grep $OLDEST_STRELKA_DATE | awk '{print $2}' | while read FILE; do
|
find "$STRELKA_FILES" -type f -printf '%T+ %p\n' 2>/dev/null | grep $OLDEST_STRELKA_DATE | awk '{print $2}' | while read FILE; do
|
||||||
echo "$(date) - Removing file: $FILE" >>$LOG
|
log "Removing file: $FILE"
|
||||||
rm -f "$FILE"
|
rm -f "$FILE"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## Clean up Suricata log files
|
## Clean up Suricata log files
|
||||||
SURICATA_LOGS='/nsm/suricata'
|
OLDEST_SURICATA=$(find "$SURICATA_LOGS" -type f -printf '%T+ %p\n' 2>/dev/null | sort -n | head -n 1)
|
||||||
OLDEST_SURICATA=$(find $SURICATA_LOGS -type f -printf '%T+ %p\n' | sort -n | head -n 1)
|
if [ -n "$OLDEST_SURICATA" ]; then
|
||||||
if [[ -z "$OLDEST_SURICATA" ]] || [[ "$OLDEST_SURICATA" == ".." ]] || [[ "$OLDEST_SURICATA" == "." ]]; then
|
|
||||||
echo "$(date) - No old files available to clean up in $SURICATA_LOGS" >>$LOG
|
|
||||||
else
|
|
||||||
OLDEST_SURICATA_DATE=$(echo $OLDEST_SURICATA | awk '{print $1}' | cut -d+ -f1)
|
OLDEST_SURICATA_DATE=$(echo $OLDEST_SURICATA | awk '{print $1}' | cut -d+ -f1)
|
||||||
OLDEST_SURICATA_FILE=$(echo $OLDEST_SURICATA | awk '{print $2}')
|
log "Removing logs for $OLDEST_SURICATA_DATE"
|
||||||
echo "$(date) - Removing logs for $OLDEST_SURICATA_DATE" >>$LOG
|
REMOVED=1
|
||||||
find $SURICATA_LOGS -type f -printf '%T+ %p\n' | grep $OLDEST_SURICATA_DATE | awk '{print $2}' | while read FILE; do
|
find "$SURICATA_LOGS" -type f -printf '%T+ %p\n' 2>/dev/null | grep $OLDEST_SURICATA_DATE | awk '{print $2}' | while read FILE; do
|
||||||
echo "$(date) - Removing file: $FILE" >>$LOG
|
log "Removing file: $FILE"
|
||||||
rm -f "$FILE"
|
rm -f "$FILE"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
## Clean up extracted pcaps
|
## Clean up extracted pcaps
|
||||||
PCAPS='/nsm/pcapout'
|
OLDEST_PCAP=$(find "$PCAPS" -type f -printf '%T+ %p\n' 2>/dev/null | sort -n | head -n 1)
|
||||||
OLDEST_PCAP=$(find $PCAPS -type f -printf '%T+ %p\n' | sort -n | head -n 1)
|
if [ -n "$OLDEST_PCAP" ]; then
|
||||||
if [ -z "$OLDEST_PCAP" -o "$OLDEST_PCAP" == ".." -o "$OLDEST_PCAP" == "." ]; then
|
|
||||||
echo "$(date) - No old files available to clean up in $PCAPS" >>$LOG
|
|
||||||
else
|
|
||||||
OLDEST_PCAP_DATE=$(echo $OLDEST_PCAP | awk '{print $1}' | cut -d+ -f1)
|
OLDEST_PCAP_DATE=$(echo $OLDEST_PCAP | awk '{print $1}' | cut -d+ -f1)
|
||||||
OLDEST_PCAP_FILE=$(echo $OLDEST_PCAP | awk '{print $2}')
|
log "Removing extracted files for $OLDEST_PCAP_DATE"
|
||||||
echo "$(date) - Removing extracted files for $OLDEST_PCAP_DATE" >>$LOG
|
REMOVED=1
|
||||||
find $PCAPS -type f -printf '%T+ %p\n' | grep $OLDEST_PCAP_DATE | awk '{print $2}' | while read FILE; do
|
find "$PCAPS" -type f -printf '%T+ %p\n' 2>/dev/null | grep $OLDEST_PCAP_DATE | awk '{print $2}' | while read FILE; do
|
||||||
echo "$(date) - Removing file: $FILE" >>$LOG
|
log "Removing file: $FILE"
|
||||||
rm -f "$FILE"
|
rm -f "$FILE"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check to see if we are already running
|
# Only one instance at a time; the lock is the fd, so it releases on any exit
|
||||||
NUM_RUNNING=$(pgrep -cf "/bin/bash /usr/sbin/so-sensor-clean")
|
exec 9>"$LOCK" || exit 1
|
||||||
[ "$NUM_RUNNING" -gt 1 ] && echo "$(date) - $NUM_RUNNING sensor clean script processes running...exiting." >>$LOG && exit 0
|
if ! flock -n 9; then
|
||||||
|
log "another so-sensor-clean is already running (lock $LOCK held); exiting"
|
||||||
if [ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ]; then
|
exit 0
|
||||||
while [ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ]; do
|
|
||||||
clean
|
|
||||||
CUR_USAGE=$(df -P $SENSOR_DIR | tail -1 | awk '{print $5}' | tr -d %)
|
|
||||||
done
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
CUR_USAGE=$(disk_usage)
|
||||||
|
[ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ] || exit 0
|
||||||
|
|
||||||
|
log "$SENSOR_DIR at ${CUR_USAGE}% (threshold ${CRIT_DISK_USAGE}%); starting cleanup"
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
while [ "$CUR_USAGE" -gt "$CRIT_DISK_USAGE" ]; do
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
if [ "$PASS" -gt "$MAX_PASSES" ]; then
|
||||||
|
log "stopping after $MAX_PASSES passes; $SENSOR_DIR still at ${CUR_USAGE}%"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
|
||||||
|
REMOVED=0
|
||||||
|
BEFORE=$(disk_avail)
|
||||||
|
clean
|
||||||
|
CUR_USAGE=$(disk_usage)
|
||||||
|
|
||||||
|
if [ "$REMOVED" -eq 0 ]; then
|
||||||
|
log "nothing left to remove in $ZEEK_LOGS, $STRELKA_FILES, $SURICATA_LOGS, $PCAPS; $SENSOR_DIR still at ${CUR_USAGE}% - space is consumed outside of NSM cleanup scope"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ "$(disk_avail)" -le "$BEFORE" ]; then
|
||||||
|
log "pass $PASS freed no space; $SENSOR_DIR still at ${CUR_USAGE}% - stopping until next run"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
@@ -125,4 +125,6 @@ else
|
|||||||
RAIDSTATUS=1
|
RAIDSTATUS=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "nsmraid=$RAIDSTATUS" > /opt/so/log/raid/status.log
|
# telegraf reads this file; write aside and rename so it never sees a half-written file
|
||||||
|
echo "nsmraid=$RAIDSTATUS" > /opt/so/log/raid/status.log.tmp
|
||||||
|
mv -f /opt/so/log/raid/status.log.tmp /opt/so/log/raid/status.log
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
docker:
|
docker:
|
||||||
range: '172.17.1.0/24'
|
range: '172.17.1.0/24'
|
||||||
gateway: '172.17.1.1'
|
gateway: '172.17.1.1'
|
||||||
|
networks:
|
||||||
|
sobridge: {}
|
||||||
|
soauth:
|
||||||
|
range: '172.17.2.0/24'
|
||||||
|
gateway: '172.17.2.1'
|
||||||
|
manager_only: True
|
||||||
ulimits:
|
ulimits:
|
||||||
- name: nofile
|
- name: nofile
|
||||||
soft: 1048576
|
soft: 1048576
|
||||||
@@ -58,18 +64,18 @@ docker:
|
|||||||
ulimits: []
|
ulimits: []
|
||||||
'so-kratos':
|
'so-kratos':
|
||||||
final_octet: 28
|
final_octet: 28
|
||||||
|
networks: ['soauth']
|
||||||
port_bindings:
|
port_bindings:
|
||||||
- 0.0.0.0:4433:4433
|
- 0.0.0.0:4433:4433
|
||||||
- 0.0.0.0:4434:4434
|
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
ulimits: []
|
ulimits: []
|
||||||
'so-hydra':
|
'so-hydra':
|
||||||
final_octet: 30
|
final_octet: 30
|
||||||
|
networks: ['soauth']
|
||||||
port_bindings:
|
port_bindings:
|
||||||
- 0.0.0.0:4444:4444
|
- 0.0.0.0:4444:4444
|
||||||
- 0.0.0.0:4445:4445
|
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
extra_hosts: []
|
extra_hosts: []
|
||||||
extra_env: []
|
extra_env: []
|
||||||
@@ -128,6 +134,7 @@ docker:
|
|||||||
ulimits: []
|
ulimits: []
|
||||||
'so-soc':
|
'so-soc':
|
||||||
final_octet: 34
|
final_octet: 34
|
||||||
|
networks: ['sobridge', 'soauth']
|
||||||
port_bindings:
|
port_bindings:
|
||||||
- 0.0.0.0:9822:9822
|
- 0.0.0.0:9822:9822
|
||||||
custom_bind_mounts: []
|
custom_bind_mounts: []
|
||||||
|
|||||||
@@ -1,8 +1,26 @@
|
|||||||
{% import_yaml 'docker/defaults.yaml' as DOCKERDEFAULTS %}
|
{% import_yaml 'docker/defaults.yaml' as DOCKERDEFAULTS %}
|
||||||
{% set DOCKERMERGED = salt['pillar.get']('docker', DOCKERDEFAULTS.docker, merge=True) %}
|
{% set DOCKERMERGED = salt['pillar.get']('docker', DOCKERDEFAULTS.docker, merge=True) %}
|
||||||
{% set RANGESPLIT = DOCKERMERGED.range.split('.') %}
|
|
||||||
{% set FIRSTTHREE = RANGESPLIT[0] ~ '.' ~ RANGESPLIT[1] ~ '.' ~ RANGESPLIT[2] ~ '.' %}
|
{% if DOCKERMERGED.networks.sobridge is not mapping %}
|
||||||
|
{% do DOCKERMERGED.networks.update({'sobridge': {}}) %}
|
||||||
|
{% endif %}
|
||||||
|
{% do DOCKERMERGED.networks['sobridge'].update({'range': DOCKERMERGED.range, 'gateway': DOCKERMERGED.gateway}) %}
|
||||||
|
|
||||||
|
{% for netname, net in DOCKERMERGED.networks.items() %}
|
||||||
|
{% set RANGESPLIT = net.range.split('.') %}
|
||||||
|
{% do net.update({'prefix': RANGESPLIT[0] ~ '.' ~ RANGESPLIT[1] ~ '.' ~ RANGESPLIT[2] ~ '.'}) %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% for container, vals in DOCKERMERGED.containers.items() %}
|
{% for container, vals in DOCKERMERGED.containers.items() %}
|
||||||
{% do DOCKERMERGED.containers[container].update({'ip': FIRSTTHREE ~ DOCKERMERGED.containers[container].final_octet}) %}
|
{% set CONTAINER_NETS = vals.get('networks', ['sobridge']) %}
|
||||||
|
{% set IPS = {} %}
|
||||||
|
{% for netname in CONTAINER_NETS %}
|
||||||
|
{% do IPS.update({netname: DOCKERMERGED.networks[netname].prefix ~ vals.final_octet}) %}
|
||||||
|
{% endfor %}
|
||||||
|
{% do DOCKERMERGED.containers[container].update({
|
||||||
|
'networks': CONTAINER_NETS,
|
||||||
|
'ips': IPS,
|
||||||
|
'network': CONTAINER_NETS[0],
|
||||||
|
'ip': IPS[CONTAINER_NETS[0]]
|
||||||
|
}) %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
+14
-10
@@ -18,10 +18,10 @@ dockergroup:
|
|||||||
dockerheldpackages:
|
dockerheldpackages:
|
||||||
pkg.installed:
|
pkg.installed:
|
||||||
- pkgs:
|
- pkgs:
|
||||||
- containerd.io: 2.2.1-1.el9
|
- containerd.io: 2.3.6-1.el9
|
||||||
- docker-ce: 3:29.2.1-1.el9
|
- docker-ce: 3:29.8.1-1.el9
|
||||||
- docker-ce-cli: 1:29.2.1-1.el9
|
- docker-ce-cli: 1:29.8.1-1.el9
|
||||||
- docker-ce-rootless-extras: 29.2.1-1.el9
|
- docker-ce-rootless-extras: 29.8.1-1.el9
|
||||||
- hold: True
|
- hold: True
|
||||||
- update_holds: True
|
- update_holds: True
|
||||||
|
|
||||||
@@ -71,15 +71,19 @@ dockerreserveports:
|
|||||||
- source: salt://common/files/99-reserved-ports.conf
|
- source: salt://common/files/99-reserved-ports.conf
|
||||||
- name: /etc/sysctl.d/99-reserved-ports.conf
|
- name: /etc/sysctl.d/99-reserved-ports.conf
|
||||||
|
|
||||||
sos_docker_net:
|
{% for NETNAME, NETWORK in DOCKERMERGED.networks.items() %}
|
||||||
|
{% if not NETWORK.get('manager_only') or GLOBALS.get('is_manager', False) %}
|
||||||
|
sos_docker_net_{{ NETNAME }}:
|
||||||
docker_network.present:
|
docker_network.present:
|
||||||
- name: sobridge
|
- name: {{ NETNAME }}
|
||||||
- subnet: {{ DOCKERMERGED.range }}
|
- subnet: {{ NETWORK.range }}
|
||||||
- gateway: {{ DOCKERMERGED.gateway }}
|
- gateway: {{ NETWORK.gateway }}
|
||||||
- options:
|
- options:
|
||||||
com.docker.network.bridge.name: 'sobridge'
|
com.docker.network.bridge.name: '{{ NETNAME }}'
|
||||||
com.docker.network.driver.mtu: '1500'
|
com.docker.network.driver.mtu: '1500'
|
||||||
com.docker.network.bridge.enable_ip_masquerade: 'true'
|
com.docker.network.bridge.enable_ip_masquerade: 'true'
|
||||||
com.docker.network.bridge.enable_icc: 'true'
|
com.docker.network.bridge.enable_icc: 'true'
|
||||||
com.docker.network.bridge.host_binding_ipv4: '0.0.0.0'
|
com.docker.network.bridge.host_binding_ipv4: '0.0.0.0'
|
||||||
- unless: ip l | grep sobridge
|
- unless: ip l | grep {{ NETNAME }}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
@@ -7,6 +7,40 @@ docker:
|
|||||||
description: Default docker IP range for containers.
|
description: Default docker IP range for containers.
|
||||||
helpLink: docker
|
helpLink: docker
|
||||||
advanced: True
|
advanced: True
|
||||||
|
networks:
|
||||||
|
sobridge:
|
||||||
|
description: |
|
||||||
|
The default docker network, carrying most containers. Its range and gateway are taken
|
||||||
|
from the docker.range and docker.gateway settings above rather than set here.
|
||||||
|
helpLink: docker
|
||||||
|
readonly: True
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
soauth:
|
||||||
|
range:
|
||||||
|
description: |
|
||||||
|
IP range for the soauth docker network, an isolated network for the authentication
|
||||||
|
services, so that the Kratos and Hydra admin APIs are only reachable from the
|
||||||
|
containers placed on it.
|
||||||
|
helpLink: docker
|
||||||
|
readonly: True
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
gateway:
|
||||||
|
description: Gateway for the soauth docker network.
|
||||||
|
helpLink: docker
|
||||||
|
readonly: True
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
manager_only:
|
||||||
|
description: |
|
||||||
|
Limits the soauth network to grid members running the authentication containers,
|
||||||
|
instead of creating it on every node.
|
||||||
|
helpLink: docker
|
||||||
|
readonly: True
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
forcedType: bool
|
||||||
ulimits:
|
ulimits:
|
||||||
description: |
|
description: |
|
||||||
Default ulimit settings applied to all containers via the Docker daemon. Each entry specifies a resource name (e.g. nofile, memlock, core, nproc) with soft and hard limits. Individual container ulimits override these defaults. Valid resource names include: cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime.
|
Default ulimit settings applied to all containers via the Docker daemon. Each entry specifies a resource name (e.g. nofile, memlock, core, nproc) with soft and hard limits. Individual container ulimits override these defaults. Valid resource names include: cpu, fsize, data, stack, core, rss, nproc, nofile, memlock, as, locks, sigpending, msgqueue, nice, rtprio, rttime.
|
||||||
@@ -34,6 +68,16 @@ docker:
|
|||||||
readonly: True
|
readonly: True
|
||||||
advanced: True
|
advanced: True
|
||||||
global: True
|
global: True
|
||||||
|
networks:
|
||||||
|
description: |
|
||||||
|
Docker networks this container is attached to. The first entry is the container's
|
||||||
|
primary network and determines the address its published ports are forwarded to.
|
||||||
|
Defaults to sobridge when unset.
|
||||||
|
helpLink: docker
|
||||||
|
readonly: True
|
||||||
|
advanced: True
|
||||||
|
global: True
|
||||||
|
forcedType: "[]string"
|
||||||
port_bindings:
|
port_bindings:
|
||||||
description: List of port bindings for the container.
|
description: List of port bindings for the container.
|
||||||
helpLink: docker
|
helpLink: docker
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ elastalert:
|
|||||||
- gid: 933
|
- gid: 933
|
||||||
- home: /opt/so/conf/elastalert
|
- home: /opt/so/conf/elastalert
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
elastalogdir:
|
elastalogdir:
|
||||||
file.directory:
|
file.directory:
|
||||||
@@ -33,8 +34,8 @@ elastalert_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elastalert/tools/sbin
|
- source: salt://elastalert/tools/sbin
|
||||||
- user: 933
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#elastalert_sbin_jinja:
|
#elastalert_sbin_jinja:
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ elastic-agent-pr:
|
|||||||
- gid: 948
|
- gid: 948
|
||||||
- home: /opt/so/conf/elastic-fleet-pr
|
- home: /opt/so/conf/elastic-fleet-pr
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ elastic-agent:
|
|||||||
- gid: 949
|
- gid: 949
|
||||||
- home: /opt/so/conf/elastic-agent
|
- home: /opt/so/conf/elastic-agent
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
elasticagentconfdir:
|
elasticagentconfdir:
|
||||||
file.directory:
|
file.directory:
|
||||||
@@ -39,8 +40,8 @@ elasticagent_sbin_jinja:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elasticagent/tools/sbin_jinja
|
- source: salt://elasticagent/tools/sbin_jinja
|
||||||
- user: 949
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|
||||||
|
|||||||
@@ -26,13 +26,14 @@ elastic-fleet:
|
|||||||
- gid: 947
|
- gid: 947
|
||||||
- home: /opt/so/conf/elastic-fleet
|
- home: /opt/so/conf/elastic-fleet
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
elasticfleet_sbin:
|
elasticfleet_sbin:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elasticfleet/tools/sbin
|
- source: salt://elasticfleet/tools/sbin
|
||||||
- user: 947
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
|
||||||
@@ -40,8 +41,8 @@ elasticfleet_sbin_jinja:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elasticfleet/tools/sbin_jinja
|
- source: salt://elasticfleet/tools/sbin_jinja
|
||||||
- user: 947
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- exclude_pat:
|
- exclude_pat:
|
||||||
@@ -81,8 +82,8 @@ eapackageupgrade:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-elastic-fleet-package-upgrade
|
- name: /usr/sbin/so-elastic-fleet-package-upgrade
|
||||||
- source: salt://elasticfleet/tools/sbin_jinja/so-elastic-fleet-package-upgrade
|
- source: salt://elasticfleet/tools/sbin_jinja/so-elastic-fleet-package-upgrade
|
||||||
- user: 947
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
"\\.gz$"
|
"\\.gz$"
|
||||||
],
|
],
|
||||||
"include_files": [],
|
"include_files": [],
|
||||||
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- drop_fields:\n fields: [\"host\"]\n ignore_missing: true\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: system.security\n- add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.security-2.22.3\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.sysmon_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.sysmon_operational-3.9.0\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.application\n - add_fields:\n target: event\n fields:\n dataset: system.application\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.application-2.22.3\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: system.system\n - add_fields:\n target: event\n fields:\n dataset: system.system\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-system.system-2.22.3\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: data_stream\n fields:\n dataset: windows.powershell_operational\n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n - add_fields:\n target: \"@metadata\"\n fields:\n pipeline: logs-windows.powershell_operational-3.9.0\n- add_fields:\n target: data_stream\n fields:\n dataset: import",
|
"processors": "- dissect:\n tokenizer: \"/nsm/import/%{import.id}/evtx/%{import.file}\"\n field: \"log.file.path\"\n target_prefix: \"\"\n- decode_json_fields:\n fields: [\"message\"]\n target: \"\"\n- add_fields:\n target: event\n fields:\n dataset: windows.forwarded\n module: windows\n imported: true\n- add_fields:\n target: \"@metadata\"\n fields:\n pipeline: import.evtx\n- if:\n equals:\n winlog.channel: 'Security'\n then: \n - add_fields:\n target: event\n fields:\n dataset: system.security\n module: system\n- if:\n equals:\n winlog.channel: 'Windows PowerShell'\n then: \n - add_fields:\n target: event\n fields:\n dataset: windows.powershell\n module: windows\n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-Sysmon/Operational'\n then: \n - add_fields:\n target: event\n fields:\n dataset: windows.sysmon_operational\n module: windows\n imported: true\n- if:\n equals:\n winlog.channel: 'Application'\n then: \n - add_fields:\n target: event\n fields:\n dataset: system.application\n module: system\n- if:\n equals:\n winlog.channel: 'System'\n then: \n - add_fields:\n target: event\n fields:\n dataset: system.system\n module: system\n \n- if:\n equals:\n winlog.channel: 'Microsoft-Windows-PowerShell/Operational'\n then: \n - add_fields:\n target: event\n fields:\n dataset: windows.powershell_operational\n module: windows\n- add_fields:\n target: data_stream\n fields:\n type: logs\n dataset: import",
|
||||||
"tags": [
|
"tags": [
|
||||||
"import"
|
"import"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ so-elastic-agent-install:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-elastic-agent-install
|
- name: /usr/sbin/so-elastic-agent-install
|
||||||
- source: salt://elasticfleet/tools/sbin/so-elastic-agent-install
|
- source: salt://elasticfleet/tools/sbin/so-elastic-agent-install
|
||||||
- user: 947
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
|
||||||
|
|||||||
@@ -30,17 +30,14 @@
|
|||||||
'azure_metrics.monitor': 'azure.monitor',
|
'azure_metrics.monitor': 'azure.monitor',
|
||||||
'azure_metrics.storage_account': 'azure.storage_account',
|
'azure_metrics.storage_account': 'azure.storage_account',
|
||||||
'azure_openai.metrics': 'azure.open_ai',
|
'azure_openai.metrics': 'azure.open_ai',
|
||||||
'beat.state': 'beats.stack_monitoring.state',
|
|
||||||
'beat.stats': 'beats.stack_monitoring.stats',
|
|
||||||
'enterprisesearch.health': 'enterprisesearch.stack_monitoring.health',
|
|
||||||
'enterprisesearch.stats': 'enterprisesearch.stack_monitoring.stats',
|
|
||||||
'kibana.cluster_actions': 'kibana.stack_monitoring.cluster_actions',
|
'kibana.cluster_actions': 'kibana.stack_monitoring.cluster_actions',
|
||||||
'kibana.cluster_rules': 'kibana.stack_monitoring.cluster_rules',
|
'kibana.cluster_rules': 'kibana.stack_monitoring.cluster_rules',
|
||||||
'kibana.node_actions': 'kibana.stack_monitoring.node_actions',
|
'kibana.node_actions': 'kibana.stack_monitoring.node_actions',
|
||||||
'kibana.node_rules': 'kibana.stack_monitoring.node_rules',
|
'kibana.node_rules': 'kibana.stack_monitoring.node_rules',
|
||||||
'kibana.stats': 'kibana.stack_monitoring.stats',
|
'kibana.stats': 'kibana.stack_monitoring.stats',
|
||||||
'kibana.status': 'kibana.stack_monitoring.status',
|
'kibana.status': 'kibana.stack_monitoring.status',
|
||||||
'logstash.node_cel': 'logstash.stack_monitoring.node',
|
'logstash.node': 'logstash.stack_monitoring.node',
|
||||||
|
'logstash.node_cel': 'logstash.node',
|
||||||
'logstash.node_stats': 'logstash.stack_monitoring.node_stats',
|
'logstash.node_stats': 'logstash.stack_monitoring.node_stats',
|
||||||
'synthetics.browser': 'synthetics-browser',
|
'synthetics.browser': 'synthetics-browser',
|
||||||
'synthetics.browser_network': 'synthetics-browser.network',
|
'synthetics.browser_network': 'synthetics-browser.network',
|
||||||
|
|||||||
@@ -30,6 +30,56 @@ fleet_api() {
|
|||||||
curl -sK /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/${QUERYPATH}" "$@" --retry 3 --retry-delay 10 --fail 2>/dev/null
|
curl -sK /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/${QUERYPATH}" "$@" --retry 3 --retry-delay 10 --fail 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
elastic_fleet_require_agent_policy() {
|
||||||
|
local AGENT_POLICY=$1
|
||||||
|
local POLICY_JSON
|
||||||
|
|
||||||
|
if ! POLICY_JSON=$(fleet_api "agent_policies/$AGENT_POLICY") || [ -z "$POLICY_JSON" ]; then
|
||||||
|
echo "Error: Agent policy '$AGENT_POLICY' was not found or is not visible in the current Kibana space." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.item.package_policies | type == "array"' <<<"$POLICY_JSON" >/dev/null 2>&1; then
|
||||||
|
echo "Error: Agent policy '$AGENT_POLICY' was not found or is not visible in the current Kibana space." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "$POLICY_JSON"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Print the single active enrollment token for POLICY_ID.
|
||||||
|
# Exit 1: retryable (API failure, invalid response, no active token)
|
||||||
|
# Exit 2: multiple active tokens - Shouldn't get into this state without manual intervention
|
||||||
|
elastic_fleet_active_enrollment_token() {
|
||||||
|
local POLICY_ID=$1
|
||||||
|
local RESP TOKEN_COUNT API_KEY
|
||||||
|
|
||||||
|
if ! RESP=$(fleet_api "enrollment_api_keys?perPage=100" -H 'kbn-xsrf: true' -H 'Content-Type: application/json'); then
|
||||||
|
echo "Error: Failed to retrieve enrollment tokens for agent policy '$POLICY_ID'." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.list' <<<"$RESP" >/dev/null 2>&1; then
|
||||||
|
echo "Error: Invalid enrollment token response for agent policy '$POLICY_ID'." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
TOKEN_COUNT=$(jq --arg pid "$POLICY_ID" '[.list[] | select(.policy_id == $pid and .active == true)] | length' <<<"$RESP")
|
||||||
|
|
||||||
|
if [ "${TOKEN_COUNT:-0}" -eq 0 ]; then
|
||||||
|
echo "Error: No active enrollment token found for agent policy '$POLICY_ID'." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$TOKEN_COUNT" -gt 1 ]; then
|
||||||
|
echo "Error: Found $TOKEN_COUNT active enrollment tokens for agent policy '$POLICY_ID'; expected exactly one." >&2
|
||||||
|
return 2
|
||||||
|
fi
|
||||||
|
|
||||||
|
API_KEY=$(jq -r --arg pid "$POLICY_ID" '.list[] | select(.policy_id == $pid and .active == true) | .api_key' <<<"$RESP")
|
||||||
|
echo "$API_KEY"
|
||||||
|
}
|
||||||
|
|
||||||
# Max number of concurrent Fleet write jobs (create/update). Override via env if needed.
|
# Max number of concurrent Fleet write jobs (create/update). Override via env if needed.
|
||||||
MAX_FLEET_JOBS=${MAX_FLEET_JOBS:-10}
|
MAX_FLEET_JOBS=${MAX_FLEET_JOBS:-10}
|
||||||
|
|
||||||
@@ -62,15 +112,7 @@ elastic_fleet_load_integrations_dir() {
|
|||||||
i=0
|
i=0
|
||||||
|
|
||||||
# Fetch the agent policy a single time; we look up integration ids locally below.
|
# Fetch the agent policy a single time; we look up integration ids locally below.
|
||||||
if ! POLICY_JSON=$(fleet_api "agent_policies/$AGENT_POLICY"); then
|
if ! POLICY_JSON=$(elastic_fleet_require_agent_policy "$AGENT_POLICY"); then
|
||||||
echo "Error: Failed to retrieve agent policy '$AGENT_POLICY'."
|
|
||||||
rm -f "$FAIL_FILE"
|
|
||||||
rm -rf "$OUT_DIR"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! jq -e '.item.package_policies' <<<"$POLICY_JSON" >/dev/null 2>&1; then
|
|
||||||
echo "Error: Invalid agent policy response for '$AGENT_POLICY'."
|
|
||||||
rm -f "$FAIL_FILE"
|
rm -f "$FAIL_FILE"
|
||||||
rm -rf "$OUT_DIR"
|
rm -rf "$OUT_DIR"
|
||||||
return 1
|
return 1
|
||||||
@@ -124,9 +166,15 @@ elastic_fleet_integration_check() {
|
|||||||
|
|
||||||
JSON_STRING=$2
|
JSON_STRING=$2
|
||||||
|
|
||||||
NAME=$(jq -r .name $JSON_STRING)
|
NAME=$(jq -r .name "$JSON_STRING")
|
||||||
|
INTEGRATION_ID=""
|
||||||
|
|
||||||
INTEGRATION_ID=$(/usr/sbin/so-elastic-fleet-agent-policy-view "$AGENT_POLICY" | jq -r '.item.package_policies[] | select(.name=="'"$NAME"'") | .id')
|
local POLICY_JSON
|
||||||
|
if ! POLICY_JSON=$(elastic_fleet_require_agent_policy "$AGENT_POLICY"); then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INTEGRATION_ID=$(jq -r --arg n "$NAME" '.item.package_policies[]? | select(.name==$n) | .id' <<<"$POLICY_JSON")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,7 +196,16 @@ elastic_fleet_integration_remove() {
|
|||||||
|
|
||||||
NAME=$2
|
NAME=$2
|
||||||
|
|
||||||
INTEGRATION_ID=$(/usr/sbin/so-elastic-fleet-agent-policy-view "$AGENT_POLICY" | jq -r '.item.package_policies[] | select(.name=="'"$NAME"'") | .id')
|
local POLICY_JSON
|
||||||
|
if ! POLICY_JSON=$(elastic_fleet_require_agent_policy "$AGENT_POLICY"); then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INTEGRATION_ID=$(jq -r --arg n "$NAME" '.item.package_policies[]? | select(.name==$n) | .id' <<<"$POLICY_JSON")
|
||||||
|
if [ -z "$INTEGRATION_ID" ]; then
|
||||||
|
echo "Error: Integration '$NAME' was not found in agent policy '$AGENT_POLICY'." >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
JSON_STRING=$( jq -n \
|
JSON_STRING=$( jq -n \
|
||||||
--arg INTEGRATIONID "$INTEGRATION_ID" \
|
--arg INTEGRATIONID "$INTEGRATION_ID" \
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ ERROR=false
|
|||||||
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations/elastic-defend/*.json
|
for INTEGRATION in /opt/so/conf/elastic-fleet/integrations/elastic-defend/*.json
|
||||||
do
|
do
|
||||||
printf "\n\nInitial Endpoints Policy - Loading $INTEGRATION\n"
|
printf "\n\nInitial Endpoints Policy - Loading $INTEGRATION\n"
|
||||||
elastic_fleet_integration_check "endpoints-initial" "$INTEGRATION"
|
if ! elastic_fleet_integration_check "endpoints-initial" "$INTEGRATION"; then
|
||||||
|
ERROR=true
|
||||||
|
continue
|
||||||
|
fi
|
||||||
if [ -n "$INTEGRATION_ID" ]; then
|
if [ -n "$INTEGRATION_ID" ]; then
|
||||||
printf "\n\nIntegration $NAME exists - Upgrading integration policy\n"
|
printf "\n\nIntegration $NAME exists - Upgrading integration policy\n"
|
||||||
if ! elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID"; then
|
if ! elastic_fleet_integration_policy_upgrade "$INTEGRATION_ID"; then
|
||||||
|
|||||||
+20
-5
@@ -7,20 +7,35 @@
|
|||||||
. /usr/sbin/so-elastic-fleet-common
|
. /usr/sbin/so-elastic-fleet-common
|
||||||
|
|
||||||
# Get all the fleet policies
|
# Get all the fleet policies
|
||||||
json_output=$(curl -s -K /opt/so/conf/elasticsearch/curl.config -L -X GET "localhost:5601/api/fleet/agent_policies" -H 'kbn-xsrf: true')
|
if ! json_output=$(fleet_api "agent_policies" -H 'kbn-xsrf: true'); then
|
||||||
|
echo "Error: Failed to retrieve Fleet agent policies." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! jq -e '.items' <<<"$json_output" >/dev/null 2>&1; then
|
||||||
|
echo "Error: Invalid Fleet agent policies response." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Extract the IDs that start with "FleetServer_"
|
# Extract the IDs that start with "FleetServer_"
|
||||||
POLICY=$(echo "$json_output" | jq -r '.items[] | select(.id | startswith("FleetServer_")) | .id')
|
POLICY=$(jq -r '.items[] | select(.id | startswith("FleetServer_")) | .id' <<<"$json_output")
|
||||||
|
|
||||||
# Iterate over each ID in the POLICY variable
|
# Iterate over each ID in the POLICY variable
|
||||||
for POLICYNAME in $POLICY; do
|
for POLICYNAME in $POLICY; do
|
||||||
printf "\nUpdating Policy: $POLICYNAME\n"
|
printf "\nUpdating Policy: $POLICYNAME\n"
|
||||||
|
|
||||||
# First get the Integration ID
|
if ! POLICY_JSON=$(elastic_fleet_require_agent_policy "$POLICYNAME"); then
|
||||||
INTEGRATION_ID=$(/usr/sbin/so-elastic-fleet-agent-policy-view "$POLICYNAME" | jq -r '.item.package_policies[] | select(.package.name == "fleet_server") | .id')
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
INTEGRATION_ID=$(jq -r '.item.package_policies[]? | select(.package.name == "fleet_server") | .id' <<<"$POLICY_JSON")
|
||||||
|
if [ -z "$INTEGRATION_ID" ]; then
|
||||||
|
echo "Error: fleet_server integration was not found in agent policy '$POLICYNAME'." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Modify the default integration policy to update the policy_id and an with the correct naming
|
# Modify the default integration policy to update the policy_id and an with the correct naming
|
||||||
UPDATED_INTEGRATION_POLICY=$(jq --arg policy_id "$POLICYNAME" --arg name "fleet_server-$POLICYNAME" '
|
UPDATED_INTEGRATION_POLICY=$(jq --arg policy_id "$POLICYNAME" --arg name "fleet_server-$POLICYNAME" '
|
||||||
.policy_id = $policy_id |
|
.policy_id = $policy_id |
|
||||||
.name = $name' /opt/so/conf/elastic-fleet/integrations/fleet-server/fleet-server.json)
|
.name = $name' /opt/so/conf/elastic-fleet/integrations/fleet-server/fleet-server.json)
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,19 @@ NUM_RUNNING=$(pgrep -cf "/bin/bash /sbin/so-elastic-agent-gen-installers")
|
|||||||
|
|
||||||
for i in {1..30}
|
for i in {1..30}
|
||||||
do
|
do
|
||||||
ENROLLMENTOKEN=$(curl -K /opt/so/conf/elasticsearch/curl.config -L "localhost:5601/api/fleet/enrollment_api_keys?perPage=100" -H 'kbn-xsrf: true' -H 'Content-Type: application/json' | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key')
|
ENROLLMENTOKEN=$(elastic_fleet_active_enrollment_token "endpoints-initial")
|
||||||
|
TOKEN_RC=$?
|
||||||
|
if [ "$TOKEN_RC" -eq 2 ]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
FLEETHOST=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/fleet_server_hosts/grid-default' | jq -r '.item.host_urls[]' | paste -sd ',')
|
FLEETHOST=$(curl -K /opt/so/conf/elasticsearch/curl.config 'http://localhost:5601/api/fleet/fleet_server_hosts/grid-default' | jq -r '.item.host_urls[]' | paste -sd ',')
|
||||||
if [[ $FLEETHOST ]] && [[ $ENROLLMENTOKEN ]]; then break; else sleep 10; fi
|
if [[ -n "$FLEETHOST" ]] && [[ -n "$ENROLLMENTOKEN" ]]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 10
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ -z $FLEETHOST ]] || [[ -z $ENROLLMENTOKEN ]]; then
|
if [[ -z "$FLEETHOST" ]] || [[ -z "$ENROLLMENTOKEN" ]]; then
|
||||||
printf "\nFleet Host URL, Enrollment Token or Elastic Version empty - exiting..."
|
printf "\nFleet Host URL, Enrollment Token or Elastic Version empty - exiting..."
|
||||||
printf "\nFleet Host: $FLEETHOST, Enrollment Token: $ENROLLMENTOKEN\n"
|
printf "\nFleet Host: $FLEETHOST, Enrollment Token: $ENROLLMENTOKEN\n"
|
||||||
exit 1
|
exit 1
|
||||||
@@ -67,19 +74,25 @@ for GOOS in "${GOTARGETOS[@]}"; do
|
|||||||
GOARCH="amd64"
|
GOARCH="amd64"
|
||||||
if [[ $GOOS == 'darwin/arm64' ]]; then GOOS="darwin" && GOARCH="arm64"; fi
|
if [[ $GOOS == 'darwin/arm64' ]]; then GOOS="darwin" && GOARCH="arm64"; fi
|
||||||
printf "\n\n### Generating $GOOS/$GOARCH Installer...\n"
|
printf "\n\n### Generating $GOOS/$GOARCH Installer...\n"
|
||||||
docker run -e CGO_ENABLED=0 -e GOOS=$GOOS -e GOARCH=$GOARCH \
|
if ! docker run -e CGO_ENABLED=0 -e GOOS=$GOOS -e GOARCH=$GOARCH \
|
||||||
--mount type=bind,source=/etc/pki/tls/certs/,target=/workspace/files/cert/ \
|
--mount type=bind,source=/etc/pki/tls/certs/,target=/workspace/files/cert/ \
|
||||||
--mount type=bind,source=/nsm/elastic-agent-workspace/,target=/workspace/files/elastic-agent/ \
|
--mount type=bind,source=/nsm/elastic-agent-workspace/,target=/workspace/files/elastic-agent/ \
|
||||||
--mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/,target=/output/ \
|
--mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/,target=/output/ \
|
||||||
{{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} go build -ldflags "-X main.fleetHostURLsList=$FLEETHOST -X main.enrollmentToken=$ENROLLMENTOKEN" -o /output/so-elastic-agent_${GOOS}_${GOARCH}
|
{{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} go build -ldflags "-X main.fleetHostURLsList=$FLEETHOST -X main.enrollmentToken=$ENROLLMENTOKEN" -o /output/so-elastic-agent_${GOOS}_${GOARCH}; then
|
||||||
|
printf "\n### ERROR: Failed to generate $GOOS/$GOARCH installer. Exiting...\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
printf "\n### $GOOS/$GOARCH Installer Generated...\n"
|
printf "\n### $GOOS/$GOARCH Installer Generated...\n"
|
||||||
done
|
done
|
||||||
|
|
||||||
printf "\n\n### Generating MSI...\n"
|
printf "\n\n### Generating MSI...\n"
|
||||||
cp /opt/so/saltstack/local/salt/elasticfleet/files/so-elastic-agent_windows_amd64 /opt/so/saltstack/local/salt/elasticfleet/files/so-elastic-agent_windows_amd64.exe
|
cp /opt/so/saltstack/local/salt/elasticfleet/files/so-elastic-agent_windows_amd64 /opt/so/saltstack/local/salt/elasticfleet/files/so-elastic-agent_windows_amd64.exe
|
||||||
docker run \
|
if ! docker run \
|
||||||
--mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/,target=/output/ -w /output \
|
--mount type=bind,source=/opt/so/saltstack/local/salt/elasticfleet/files/,target=/output/ -w /output \
|
||||||
{{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} wixl -o so-elastic-agent_windows_amd64_msi --arch x64 /workspace/so-elastic-agent.wxs
|
{{ GLOBALS.registry_host }}:5000/{{ GLOBALS.image_repo }}/so-elastic-agent-builder:{{ GLOBALS.so_version }} wixl -o so-elastic-agent_windows_amd64_msi --arch x64 /workspace/so-elastic-agent.wxs; then
|
||||||
|
printf "\n### ERROR: Failed to generate MSI. Exiting...\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
printf "\n### MSI Generated...\n"
|
printf "\n### MSI Generated...\n"
|
||||||
|
|
||||||
# Verify installers were created
|
# Verify installers were created
|
||||||
|
|||||||
@@ -202,26 +202,9 @@ fi
|
|||||||
### Finalization ###
|
### Finalization ###
|
||||||
|
|
||||||
# Query for Enrollment Tokens for default policies
|
# Query for Enrollment Tokens for default policies
|
||||||
if ENDPOINTSENROLLMENTOKEN_RAW=$(fleet_api "enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json'); then
|
ENDPOINTSENROLLMENTOKEN=$(elastic_fleet_active_enrollment_token "endpoints-initial") || exit 1
|
||||||
ENDPOINTSENROLLMENTOKEN=$(echo "$ENDPOINTSENROLLMENTOKEN_RAW" | jq .list | jq -r -c '.[] | select(.policy_id | contains("endpoints-initial")) | .api_key')
|
GRIDNODESENROLLMENTOKENGENERAL=$(elastic_fleet_active_enrollment_token "so-grid-nodes_general") || exit 1
|
||||||
else
|
GRIDNODESENROLLMENTOKENHEAVY=$(elastic_fleet_active_enrollment_token "so-grid-nodes_heavy") || exit 1
|
||||||
echo -e "\nFailed to query for Endpoints enrollment token"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if GRIDNODESENROLLMENTOKENGENERAL_RAW=$(fleet_api "enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json'); then
|
|
||||||
GRIDNODESENROLLMENTOKENGENERAL=$(echo "$GRIDNODESENROLLMENTOKENGENERAL_RAW" | jq .list | jq -r -c '.[] | select(.policy_id | contains("so-grid-nodes_general")) | .api_key')
|
|
||||||
else
|
|
||||||
echo -e "\nFailed to query for Grid nodes - General enrollment token"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if GRIDNODESENROLLMENTOKENHEAVY_RAW=$(fleet_api "enrollment_api_keys" -H 'kbn-xsrf: true' -H 'Content-Type: application/json'); then
|
|
||||||
GRIDNODESENROLLMENTOKENHEAVY=$(echo "$GRIDNODESENROLLMENTOKENHEAVY_RAW" | jq .list | jq -r -c '.[] | select(.policy_id | contains("so-grid-nodes_heavy")) | .api_key')
|
|
||||||
else
|
|
||||||
echo -e "\nFailed to query for Grid nodes - Heavy enrollment token"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Store needed data in minion pillar
|
# Store needed data in minion pillar
|
||||||
pillar_file=/opt/so/saltstack/local/pillar/minions/{{ GLOBALS.minion_id }}.sls
|
pillar_file=/opt/so/saltstack/local/pillar/minions/{{ GLOBALS.minion_id }}.sls
|
||||||
|
|||||||
@@ -32,13 +32,14 @@ elasticsearch:
|
|||||||
- gid: 930
|
- gid: 930
|
||||||
- home: /opt/so/conf/elasticsearch
|
- home: /opt/so/conf/elasticsearch
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
elasticsearch_sbin:
|
elasticsearch_sbin:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elasticsearch/tools/sbin
|
- source: salt://elasticsearch/tools/sbin
|
||||||
- user: 930
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- exclude_pat:
|
- exclude_pat:
|
||||||
- so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state
|
- so-elasticsearch-pipelines # exclude this because we need to watch it for changes, we sync it in another state
|
||||||
@@ -49,8 +50,8 @@ so-elasticsearch-system-indices-patch-script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-elasticsearch-system-indices-patch
|
- name: /usr/sbin/so-elasticsearch-system-indices-patch
|
||||||
- source: salt://elasticsearch/tools/sbin/so-elasticsearch-system-indices-patch
|
- source: salt://elasticsearch/tools/sbin/so-elasticsearch-system-indices-patch
|
||||||
- user: 930
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
|
||||||
@@ -58,8 +59,8 @@ elasticsearch_sbin_jinja:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://elasticsearch/tools/sbin_jinja
|
- source: salt://elasticsearch/tools/sbin_jinja
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- exclude_pat:
|
- exclude_pat:
|
||||||
@@ -72,8 +73,8 @@ so-elasticsearch-ilm-policy-load-script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-elasticsearch-ilm-policy-load
|
- name: /usr/sbin/so-elasticsearch-ilm-policy-load
|
||||||
- source: salt://elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load
|
- source: salt://elasticsearch/tools/sbin_jinja/so-elasticsearch-ilm-policy-load
|
||||||
- user: 930
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- mode: 754
|
- mode: 754
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- defaults:
|
- defaults:
|
||||||
@@ -84,8 +85,8 @@ so-elasticsearch-pipelines-script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-elasticsearch-pipelines
|
- name: /usr/sbin/so-elasticsearch-pipelines
|
||||||
- source: salt://elasticsearch/tools/sbin/so-elasticsearch-pipelines
|
- source: salt://elasticsearch/tools/sbin/so-elasticsearch-pipelines
|
||||||
- user: 930
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- mode: 754
|
- mode: 754
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
|
||||||
|
|||||||
@@ -3309,6 +3309,7 @@ elasticsearch:
|
|||||||
composed_of:
|
composed_of:
|
||||||
- event-mappings
|
- event-mappings
|
||||||
- logs-system.security@package
|
- logs-system.security@package
|
||||||
|
- so-fleet_system.security_caseless-1
|
||||||
- logs-system.security@custom
|
- logs-system.security@custom
|
||||||
- so-fleet_integrations.ip_mappings-1
|
- so-fleet_integrations.ip_mappings-1
|
||||||
- so-fleet_globals-1
|
- so-fleet_globals-1
|
||||||
@@ -4175,6 +4176,7 @@ elasticsearch:
|
|||||||
index_template:
|
index_template:
|
||||||
composed_of:
|
composed_of:
|
||||||
- logs-windows.forwarded@package
|
- logs-windows.forwarded@package
|
||||||
|
- so-fleet_process_caseless-1
|
||||||
- logs-windows.forwarded@custom
|
- logs-windows.forwarded@custom
|
||||||
- so-fleet_integrations.ip_mappings-1
|
- so-fleet_integrations.ip_mappings-1
|
||||||
- so-fleet_globals-1
|
- so-fleet_globals-1
|
||||||
@@ -4224,6 +4226,7 @@ elasticsearch:
|
|||||||
index_template:
|
index_template:
|
||||||
composed_of:
|
composed_of:
|
||||||
- logs-windows.powershell@package
|
- logs-windows.powershell@package
|
||||||
|
- so-fleet_process_caseless-1
|
||||||
- logs-windows.powershell@custom
|
- logs-windows.powershell@custom
|
||||||
- so-fleet_integrations.ip_mappings-1
|
- so-fleet_integrations.ip_mappings-1
|
||||||
- so-fleet_globals-1
|
- so-fleet_globals-1
|
||||||
@@ -4273,6 +4276,7 @@ elasticsearch:
|
|||||||
index_template:
|
index_template:
|
||||||
composed_of:
|
composed_of:
|
||||||
- logs-windows.powershell_operational@package
|
- logs-windows.powershell_operational@package
|
||||||
|
- so-fleet_process_caseless-1
|
||||||
- logs-windows.powershell_operational@custom
|
- logs-windows.powershell_operational@custom
|
||||||
- so-fleet_integrations.ip_mappings-1
|
- so-fleet_integrations.ip_mappings-1
|
||||||
- so-fleet_globals-1
|
- so-fleet_globals-1
|
||||||
@@ -4322,6 +4326,7 @@ elasticsearch:
|
|||||||
index_template:
|
index_template:
|
||||||
composed_of:
|
composed_of:
|
||||||
- logs-windows.sysmon_operational@package
|
- logs-windows.sysmon_operational@package
|
||||||
|
- so-fleet_process_caseless-1
|
||||||
- logs-windows.sysmon_operational@custom
|
- logs-windows.sysmon_operational@custom
|
||||||
- so-fleet_integrations.ip_mappings-1
|
- so-fleet_integrations.ip_mappings-1
|
||||||
- so-fleet_globals-1
|
- so-fleet_globals-1
|
||||||
|
|||||||
@@ -99,7 +99,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"set": {
|
"set": {
|
||||||
"if": "ctx.tags != null && ctx.tags.contains('import')",
|
"if": "ctx.tags != null && ctx.tags.contains('import') && ctx._index != null && ctx._index.startsWith('logs-import-')",
|
||||||
"override": true,
|
"override": true,
|
||||||
"field": "data_stream.dataset",
|
"field": "data_stream.dataset",
|
||||||
"value": "import"
|
"value": "import"
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"set": {
|
"set": {
|
||||||
"if": "ctx.tags != null && ctx.tags.contains('import')",
|
"if": "ctx.tags != null && ctx.tags.contains('import') && ctx._index != null && ctx._index.startsWith('logs-import-')",
|
||||||
"override": true,
|
"override": true,
|
||||||
"field": "data_stream.namespace",
|
"field": "data_stream.namespace",
|
||||||
"value": "so"
|
"value": "so"
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"description" : "import.evtx: normalize imported EVTX and reroute to logs-<dataset>-import",
|
||||||
|
"processors" : [
|
||||||
|
{ "script": {
|
||||||
|
"description": "Host from the event, not the importing node",
|
||||||
|
"lang": "painless",
|
||||||
|
"source": "Map host = ['os': ['type': 'windows', 'family': 'windows', 'platform': 'windows']]; def cn = ctx.winlog?.computer_name; if (cn != null && cn.toString().length() > 0) { String name = cn.toString(); int dot = name.indexOf('.'); if (dot > 0) { name = name.substring(0, dot); } host.put('hostname', name); host.put('name', name.toLowerCase()); } ctx.host = host;"
|
||||||
|
} },
|
||||||
|
{ "script": {
|
||||||
|
"description": "String event IDs, as Winlogbeat sends",
|
||||||
|
"lang": "painless",
|
||||||
|
"source": "if (ctx.winlog?.event_id != null) { ctx.winlog.event_id = ctx.winlog.event_id.toString(); } if (ctx.event?.code != null) { ctx.event.code = ctx.event.code.toString(); }"
|
||||||
|
} },
|
||||||
|
{ "script": {
|
||||||
|
"description": "Unnamed <Data> to param1..N, as Winlogbeat",
|
||||||
|
"lang": "painless",
|
||||||
|
"if": "ctx.winlog?.event_data?.Data instanceof Map && ctx.winlog.event_data.Data['#text'] != null",
|
||||||
|
"source": "def t = ctx.winlog.event_data.Data['#text']; List vals = t instanceof List ? t : [t]; for (int i = 0; i < vals.size(); i++) { ctx.winlog.event_data['param' + (i + 1)] = vals.get(i); } ctx.winlog.event_data.remove('Data');"
|
||||||
|
} },
|
||||||
|
{ "script": {
|
||||||
|
"description": "String values and LF line endings, as Winlogbeat",
|
||||||
|
"lang": "painless",
|
||||||
|
"if": "ctx.winlog?.event_data instanceof Map || ctx.winlog?.user_data instanceof Map",
|
||||||
|
"source": "String lf = String.valueOf((char) 10); String crlf = String.valueOf((char) 13) + lf; for (def key : ['event_data', 'user_data']) { def m = ctx.winlog[key]; if (!(m instanceof Map)) { continue; } for (def e : m.entrySet()) { def v = e.getValue(); if (v instanceof String) { e.setValue(v.replace(crlf, lf)); } else if (v instanceof Number || v instanceof Boolean) { e.setValue(v.toString()); } } }"
|
||||||
|
} },
|
||||||
|
{ "set": { "description": "event.kind, as Winlogbeat", "field": "event.kind", "value": "event", "override": false } },
|
||||||
|
{ "set": { "field": "data_stream.dataset", "copy_from": "event.dataset", "override": true, "ignore_empty_value": true } },
|
||||||
|
{ "set": { "field": "data_stream.namespace", "value": "import", "override": true } },
|
||||||
|
{ "reroute": { "dataset": "{{data_stream.dataset}}", "namespace": "{{data_stream.namespace}}" } }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -5,7 +5,8 @@
|
|||||||
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } },
|
{ "rename": { "field": "message2.proto", "target_field": "network.transport", "ignore_missing": true } },
|
||||||
{ "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } },
|
{ "rename": { "field": "message2.app_proto", "target_field": "network.protocol", "ignore_missing": true } },
|
||||||
{ "rename": { "field": "message2.fileinfo.filename", "target_field": "file.name", "ignore_missing": true } },
|
{ "rename": { "field": "message2.fileinfo.filename", "target_field": "file.name", "ignore_missing": true } },
|
||||||
{ "rename": { "field": "message2.fileinfo.gaps", "target_field": "file.bytes.missing", "ignore_missing": true } },
|
{ "rename": { "field": "message2.fileinfo.gaps", "target_field": "suricata.fileinfo.gaps", "ignore_missing": true } },
|
||||||
|
{ "set": { "if": "ctx.suricata?.fileinfo?.gaps == false", "field": "file.bytes.missing", "value": 0 } },
|
||||||
{ "rename": { "field": "message2.fileinfo.magic", "target_field": "file.mime_type", "ignore_missing": true } },
|
{ "rename": { "field": "message2.fileinfo.magic", "target_field": "file.mime_type", "ignore_missing": true } },
|
||||||
{ "rename": { "field": "message2.fileinfo.md5", "target_field": "hash.md5", "ignore_missing": true } },
|
{ "rename": { "field": "message2.fileinfo.md5", "target_field": "hash.md5", "ignore_missing": true } },
|
||||||
{ "rename": { "field": "message2.fileinfo.sha1", "target_field": "hash.sha1", "ignore_missing": true } },
|
{ "rename": { "field": "message2.fileinfo.sha1", "target_field": "hash.sha1", "ignore_missing": true } },
|
||||||
|
|||||||
+123
@@ -0,0 +1,123 @@
|
|||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"managed_by": "security_onion",
|
||||||
|
"managed": true,
|
||||||
|
"description": "Adds .caseless for Lucene queries. Restates each field's package type and .text."
|
||||||
|
},
|
||||||
|
"template": {
|
||||||
|
"mappings": {
|
||||||
|
"properties": {
|
||||||
|
"process": {
|
||||||
|
"properties": {
|
||||||
|
"executable": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"command_line": {
|
||||||
|
"type": "wildcard",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parent": {
|
||||||
|
"properties": {
|
||||||
|
"executable": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"command_line": {
|
||||||
|
"type": "wildcard",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
"type": "match_only_text"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"_meta": {
|
||||||
|
"managed_by": "security_onion",
|
||||||
|
"managed": true,
|
||||||
|
"description": "Adds .caseless for Lucene queries. Keeps each field's existing keyword type."
|
||||||
|
},
|
||||||
|
"template": {
|
||||||
|
"mappings": {
|
||||||
|
"properties": {
|
||||||
|
"process": {
|
||||||
|
"properties": {
|
||||||
|
"command_line": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parent": {
|
||||||
|
"properties": {
|
||||||
|
"executable": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"command_line": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"file": {
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"fields": {
|
||||||
|
"caseless": {
|
||||||
|
"type": "keyword",
|
||||||
|
"ignore_above": 1024,
|
||||||
|
"normalizer": "lowercase"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,11 +4,19 @@
|
|||||||
{%- set role = GLOBALS.role.split('-')[1] %}
|
{%- set role = GLOBALS.role.split('-')[1] %}
|
||||||
{%- from 'firewall/containers.map.jinja' import NODE_CONTAINERS %}
|
{%- from 'firewall/containers.map.jinja' import NODE_CONTAINERS %}
|
||||||
|
|
||||||
|
{%- set NODE_NETWORKS = [] %}
|
||||||
|
{%- for NETNAME, NETWORK in DOCKERMERGED.networks.items() %}
|
||||||
|
{%- if not NETWORK.get('manager_only') or GLOBALS.get('is_manager', False) %}
|
||||||
|
{%- do NODE_NETWORKS.append(NETNAME) %}
|
||||||
|
{%- endif %}
|
||||||
|
{%- endfor %}
|
||||||
|
|
||||||
{%- set PR = [] %}
|
{%- set PR = [] %}
|
||||||
{%- set D1 = [] %}
|
{%- set D1 = [] %}
|
||||||
{%- set D2 = [] %}
|
{%- set D2 = [] %}
|
||||||
{%- for container in NODE_CONTAINERS %}
|
{%- for container in NODE_CONTAINERS %}
|
||||||
{%- set IP = DOCKERMERGED.containers[container].ip %}
|
{%- set IP = DOCKERMERGED.containers[container].ip %}
|
||||||
|
{%- set BRIDGE = DOCKERMERGED.containers[container].network %}
|
||||||
{%- if DOCKERMERGED.containers[container].port_bindings is defined %}
|
{%- if DOCKERMERGED.containers[container].port_bindings is defined %}
|
||||||
{%- for binding in DOCKERMERGED.containers[container].port_bindings %}
|
{%- for binding in DOCKERMERGED.containers[container].port_bindings %}
|
||||||
{#- cant split int so we convert to string #}
|
{#- cant split int so we convert to string #}
|
||||||
@@ -35,11 +43,11 @@
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- do PR.append("-A POSTROUTING -s " ~ DOCKERMERGED.containers[container].ip ~ "/32 -d " ~ DOCKERMERGED.containers[container].ip ~ "/32 -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ containerPort ~ " -j MASQUERADE") %}
|
{%- do PR.append("-A POSTROUTING -s " ~ DOCKERMERGED.containers[container].ip ~ "/32 -d " ~ DOCKERMERGED.containers[container].ip ~ "/32 -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ containerPort ~ " -j MASQUERADE") %}
|
||||||
{%- if bindip | length and bindip != '0.0.0.0' %}
|
{%- if bindip | length and bindip != '0.0.0.0' %}
|
||||||
{%- do D1.append("-A DOCKER -d " ~ bindip ~ "/32 ! -i sobridge -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ hostPort ~ " -j DNAT --to-destination " ~ DOCKERMERGED.containers[container].ip ~ ":" ~ containerPort) %}
|
{%- do D1.append("-A DOCKER -d " ~ bindip ~ "/32 ! -i " ~ BRIDGE ~ " -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ hostPort ~ " -j DNAT --to-destination " ~ DOCKERMERGED.containers[container].ip ~ ":" ~ containerPort) %}
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{%- do D1.append("-A DOCKER ! -i sobridge -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ hostPort ~ " -j DNAT --to-destination " ~ DOCKERMERGED.containers[container].ip ~ ":" ~ containerPort) %}
|
{%- do D1.append("-A DOCKER ! -i " ~ BRIDGE ~ " -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ hostPort ~ " -j DNAT --to-destination " ~ DOCKERMERGED.containers[container].ip ~ ":" ~ containerPort) %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- do D2.append("-A DOCKER -d " ~ DOCKERMERGED.containers[container].ip ~ "/32 ! -i sobridge -o sobridge -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ containerPort ~ " -j ACCEPT") %}
|
{%- do D2.append("-A DOCKER -d " ~ DOCKERMERGED.containers[container].ip ~ "/32 ! -i " ~ BRIDGE ~ " -o " ~ BRIDGE ~ " -p " ~ proto ~ " -m " ~ proto ~ " --dport " ~ containerPort ~ " -j ACCEPT") %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
@@ -52,11 +60,15 @@
|
|||||||
:DOCKER - [0:0]
|
:DOCKER - [0:0]
|
||||||
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
|
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
|
||||||
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
|
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
|
||||||
-A POSTROUTING -s {{DOCKERMERGED.range}} ! -o sobridge -j MASQUERADE
|
{%- for NETNAME in NODE_NETWORKS %}
|
||||||
|
-A POSTROUTING -s {{ DOCKERMERGED.networks[NETNAME].range }} ! -o {{ NETNAME }} -j MASQUERADE
|
||||||
|
{%- endfor %}
|
||||||
{%- for rule in PR %}
|
{%- for rule in PR %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
-A DOCKER -i sobridge -j RETURN
|
{%- for NETNAME in NODE_NETWORKS %}
|
||||||
|
-A DOCKER -i {{ NETNAME }} -j RETURN
|
||||||
|
{%- endfor %}
|
||||||
{%- for rule in D1 %}
|
{%- for rule in D1 %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
@@ -97,10 +109,12 @@ COMMIT
|
|||||||
{%- endif %}
|
{%- endif %}
|
||||||
-A FORWARD -j DOCKER-USER
|
-A FORWARD -j DOCKER-USER
|
||||||
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
|
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
|
||||||
-A FORWARD -o sobridge -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
{%- for NETNAME in NODE_NETWORKS %}
|
||||||
-A FORWARD -o sobridge -j DOCKER
|
-A FORWARD -o {{ NETNAME }} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
-A FORWARD -i sobridge ! -o sobridge -j ACCEPT
|
-A FORWARD -o {{ NETNAME }} -j DOCKER
|
||||||
-A FORWARD -i sobridge -o sobridge -j ACCEPT
|
-A FORWARD -i {{ NETNAME }} ! -o {{ NETNAME }} -j ACCEPT
|
||||||
|
-A FORWARD -i {{ NETNAME }} -o {{ NETNAME }} -j ACCEPT
|
||||||
|
{%- endfor %}
|
||||||
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
-A FORWARD -i lo -j ACCEPT
|
-A FORWARD -i lo -j ACCEPT
|
||||||
-A FORWARD -m conntrack --ctstate INVALID -j DROP
|
-A FORWARD -m conntrack --ctstate INVALID -j DROP
|
||||||
@@ -112,13 +126,18 @@ COMMIT
|
|||||||
{%- for rule in D2 %}
|
{%- for rule in D2 %}
|
||||||
{{ rule }}
|
{{ rule }}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
{% for NETNAME in NODE_NETWORKS %}
|
||||||
-A DOCKER-ISOLATION-STAGE-1 -i sobridge ! -o sobridge -j DOCKER-ISOLATION-STAGE-2
|
-A DOCKER-ISOLATION-STAGE-1 -i {{ NETNAME }} ! -o {{ NETNAME }} -j DOCKER-ISOLATION-STAGE-2
|
||||||
|
{%- endfor %}
|
||||||
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
|
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
|
||||||
-A DOCKER-ISOLATION-STAGE-2 -o sobridge -j DROP
|
{%- for NETNAME in NODE_NETWORKS %}
|
||||||
|
-A DOCKER-ISOLATION-STAGE-2 -o {{ NETNAME }} -j DROP
|
||||||
|
{%- endfor %}
|
||||||
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
|
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
|
||||||
-A DOCKER-USER ! -i sobridge -o sobridge -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
{%- for NETNAME in NODE_NETWORKS %}
|
||||||
-A DOCKER-USER ! -i sobridge -o sobridge -j LOGGING
|
-A DOCKER-USER ! -i {{ NETNAME }} -o {{ NETNAME }} -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||||
|
-A DOCKER-USER ! -i {{ NETNAME }} -o {{ NETNAME }} -j LOGGING
|
||||||
|
{%- endfor %}
|
||||||
-A DOCKER-USER -j RETURN
|
-A DOCKER-USER -j RETURN
|
||||||
-A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-dropped: "
|
-A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-dropped: "
|
||||||
-A LOGGING -j DROP
|
-A LOGGING -j DROP
|
||||||
|
|||||||
@@ -4,8 +4,12 @@
|
|||||||
|
|
||||||
{# add our ip to self #}
|
{# add our ip to self #}
|
||||||
{% do FIREWALL_DEFAULT.firewall.hostgroups.self.append(GLOBALS.node_ip) %}
|
{% do FIREWALL_DEFAULT.firewall.hostgroups.self.append(GLOBALS.node_ip) %}
|
||||||
{# add dockernet range #}
|
{# add dockernet ranges #}
|
||||||
{% do FIREWALL_DEFAULT.firewall.hostgroups.dockernet.append(DOCKERMERGED.range) %}
|
{% for NETNAME, NETWORK in DOCKERMERGED.networks.items() %}
|
||||||
|
{% if not NETWORK.get('manager_only') or GLOBALS.get('is_manager', False) %}
|
||||||
|
{% do FIREWALL_DEFAULT.firewall.hostgroups.dockernet.append(NETWORK.range) %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
{% if GLOBALS.role == 'so-idh' %}
|
{% if GLOBALS.role == 'so-idh' %}
|
||||||
{% from 'idh/opencanary_config.map.jinja' import IDH_PORTGROUPS %}
|
{% from 'idh/opencanary_config.map.jinja' import IDH_PORTGROUPS %}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ so-hydra:
|
|||||||
- hostname: hydra
|
- hostname: hydra
|
||||||
- name: so-hydra
|
- name: so-hydra
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- soauth:
|
||||||
- ipv4_address: {{ DOCKERMERGED.containers['so-hydra'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-hydra'].ips['soauth'] }}
|
||||||
- binds:
|
- binds:
|
||||||
- /opt/so/conf/hydra/:/hydra-conf:ro
|
- /opt/so/conf/hydra/:/hydra-conf:ro
|
||||||
- /opt/so/log/hydra/:/hydra-log:rw
|
- /opt/so/log/hydra/:/hydra-log:rw
|
||||||
@@ -73,7 +73,7 @@ delete_so-hydra_so-status.disabled:
|
|||||||
|
|
||||||
wait_for_hydra:
|
wait_for_hydra:
|
||||||
http.wait_for_successful_query:
|
http.wait_for_successful_query:
|
||||||
- name: 'http://{{ GLOBALS.manager }}:4444/health/alive'
|
- name: 'http://{{ DOCKERMERGED.containers['so-hydra'].ips['soauth'] }}:4444/health/alive'
|
||||||
- ssl: True
|
- ssl: True
|
||||||
- verify_ssl: False
|
- verify_ssl: False
|
||||||
- status:
|
- status:
|
||||||
|
|||||||
@@ -21,12 +21,16 @@ hypervisor_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://hypervisor/tools/sbin
|
- source: salt://hypervisor/tools/sbin
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- file_mode: 744
|
- file_mode: 744
|
||||||
|
|
||||||
hypervisor_sbin_jinja:
|
hypervisor_sbin_jinja:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://hypervisor/tools/sbin_jinja
|
- source: salt://hypervisor/tools/sbin_jinja
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- file_mode: 744
|
- file_mode: 744
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -86,8 +86,8 @@ idh_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://idh/tools/sbin
|
- source: salt://idh/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#idh_sbin_jinja:
|
#idh_sbin_jinja:
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ influxdb_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://influxdb/tools/sbin
|
- source: salt://influxdb/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#influxdb_sbin_jinja:
|
#influxdb_sbin_jinja:
|
||||||
|
|||||||
@@ -94,9 +94,11 @@ metrics_link_file:
|
|||||||
- docker_container: so-influxdb
|
- docker_container: so-influxdb
|
||||||
|
|
||||||
# Install cron job to determine size of influxdb for telegraf
|
# Install cron job to determine size of influxdb for telegraf
|
||||||
|
# telegraf reads this while the cron rewrites it, so write aside and rename rather than
|
||||||
|
# truncating in place. tgraflogdir recurses ownership, so the temp file is chowned to match
|
||||||
get_influxdb_size:
|
get_influxdb_size:
|
||||||
cron.present:
|
cron.present:
|
||||||
- name: 'du -s -k /nsm/influxdb | cut -f1 > /opt/so/log/telegraf/influxdb_size.log 2>&1'
|
- name: 'du -s -k /nsm/influxdb | cut -f1 > /opt/so/log/telegraf/influxdb_size.log.tmp 2>&1; chown 939:939 /opt/so/log/telegraf/influxdb_size.log.tmp; mv -f /opt/so/log/telegraf/influxdb_size.log.tmp /opt/so/log/telegraf/influxdb_size.log'
|
||||||
- identifier: get_influxdb_size
|
- identifier: get_influxdb_size
|
||||||
- user: root
|
- user: root
|
||||||
- minute: '*/1'
|
- minute: '*/1'
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ kafka_user:
|
|||||||
- gid: 960
|
- gid: 960
|
||||||
- home: /opt/so/conf/kafka
|
- home: /opt/so/conf/kafka
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
kafka_home_dir:
|
kafka_home_dir:
|
||||||
file.absent:
|
file.absent:
|
||||||
@@ -30,16 +31,16 @@ kafka_sbin_tools:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://kafka/tools/sbin
|
- source: salt://kafka/tools/sbin
|
||||||
- user: 960
|
- user: root
|
||||||
- group: 960
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
kafka_sbin_jinja_tools:
|
kafka_sbin_jinja_tools:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://kafka/tools/sbin_jinja
|
- source: salt://kafka/tools/sbin_jinja
|
||||||
- user: 960
|
- user: root
|
||||||
- group: 960
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- defaults:
|
- defaults:
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ kibana:
|
|||||||
- gid: 932
|
- gid: 932
|
||||||
- home: /opt/so/conf/kibana
|
- home: /opt/so/conf/kibana
|
||||||
- createhome: False
|
- createhome: False
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
# Drop the correct nginx config based on role
|
# Drop the correct nginx config based on role
|
||||||
|
|
||||||
@@ -36,16 +37,16 @@ kibana_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://kibana/tools/sbin
|
- source: salt://kibana/tools/sbin
|
||||||
- user: 932
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
kibana_sbin_jinja:
|
kibana_sbin_jinja:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://kibana/tools/sbin_jinja
|
- source: salt://kibana/tools/sbin_jinja
|
||||||
- user: 932
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- defaults:
|
- defaults:
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ kratos:
|
|||||||
- uid: 928
|
- uid: 928
|
||||||
- gid: 928
|
- gid: 928
|
||||||
- home: /opt/so/conf/kratos
|
- home: /opt/so/conf/kratos
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
kratosdir:
|
kratosdir:
|
||||||
file.directory:
|
file.directory:
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ so-kratos:
|
|||||||
- hostname: kratos
|
- hostname: kratos
|
||||||
- name: so-kratos
|
- name: so-kratos
|
||||||
- networks:
|
- networks:
|
||||||
- sobridge:
|
- soauth:
|
||||||
- ipv4_address: {{ DOCKERMERGED.containers['so-kratos'].ip }}
|
- ipv4_address: {{ DOCKERMERGED.containers['so-kratos'].ips['soauth'] }}
|
||||||
- binds:
|
- binds:
|
||||||
- /opt/so/conf/kratos/:/kratos-conf:ro
|
- /opt/so/conf/kratos/:/kratos-conf:ro
|
||||||
- /opt/so/log/kratos/:/kratos-log:rw
|
- /opt/so/log/kratos/:/kratos-log:rw
|
||||||
@@ -71,7 +71,7 @@ delete_so-kratos_so-status.disabled:
|
|||||||
|
|
||||||
wait_for_kratos:
|
wait_for_kratos:
|
||||||
http.wait_for_successful_query:
|
http.wait_for_successful_query:
|
||||||
- name: 'http://{{ GLOBALS.manager }}:4434/'
|
- name: 'http://{{ DOCKERMERGED.containers['so-kratos'].ips['soauth'] }}:4434/'
|
||||||
- ssl: True
|
- ssl: True
|
||||||
- verify_ssl: False
|
- verify_ssl: False
|
||||||
- status:
|
- status:
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ so-fix-salt-ldap_script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-fix-salt-ldap.py
|
- name: /usr/sbin/so-fix-salt-ldap.py
|
||||||
- source: salt://libvirt/64962/scripts/so-fix-salt-ldap.py
|
- source: salt://libvirt/64962/scripts/so-fix-salt-ldap.py
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- mode: 744
|
- mode: 744
|
||||||
|
|
||||||
fix-salt-ldap:
|
fix-salt-ldap:
|
||||||
|
|||||||
@@ -35,13 +35,14 @@ logstash:
|
|||||||
- uid: 931
|
- uid: 931
|
||||||
- gid: 931
|
- gid: 931
|
||||||
- home: /opt/so/conf/logstash
|
- home: /opt/so/conf/logstash
|
||||||
|
- shell: /sbin/nologin
|
||||||
|
|
||||||
logstash_sbin:
|
logstash_sbin:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://logstash/tools/sbin
|
- source: salt://logstash/tools/sbin
|
||||||
- user: 931
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#logstash_sbin_jinja:
|
#logstash_sbin_jinja:
|
||||||
|
|||||||
+12
-8
@@ -113,8 +113,8 @@ manager_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://manager/tools/sbin
|
- source: salt://manager/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- exclude_pat:
|
- exclude_pat:
|
||||||
- "*_test.py"
|
- "*_test.py"
|
||||||
@@ -124,8 +124,8 @@ manager_sbin_jinja:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin/
|
- name: /usr/sbin/
|
||||||
- source: salt://manager/tools/sbin_jinja/
|
- source: salt://manager/tools/sbin_jinja/
|
||||||
- user: socore
|
- user: root
|
||||||
- group: socore
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
@@ -166,7 +166,7 @@ so-repo-sync:
|
|||||||
|
|
||||||
so_fleetagent_status:
|
so_fleetagent_status:
|
||||||
cron.present:
|
cron.present:
|
||||||
- name: /usr/sbin/so-elasticagent-status > /opt/so/log/agents/agentstatus.log 2>&1
|
- name: '/usr/sbin/so-elasticagent-status > /opt/so/log/agents/agentstatus.log.tmp 2>&1; mv -f /opt/so/log/agents/agentstatus.log.tmp /opt/so/log/agents/agentstatus.log'
|
||||||
- identifier: so_fleetagent_status
|
- identifier: so_fleetagent_status
|
||||||
- user: root
|
- user: root
|
||||||
- minute: '*/5'
|
- minute: '*/5'
|
||||||
@@ -190,11 +190,15 @@ so_fleetagent_monitor:
|
|||||||
- month: '*'
|
- month: '*'
|
||||||
- dayweek: '*'
|
- dayweek: '*'
|
||||||
|
|
||||||
socore_own_saltstack_default:
|
# This tree is the source of every root-executed script (/usr/sbin, reactors, _runners,
|
||||||
|
# engines, salt-relay.sh). SOC mounts /opt/so/saltstack rw as uid 939 but only writes
|
||||||
|
# under local/. Do not add dir_mode/file_mode here -- SOC reads default/ and 750/640
|
||||||
|
# would break its config load.
|
||||||
|
root_own_saltstack_default:
|
||||||
file.directory:
|
file.directory:
|
||||||
- name: /opt/so/saltstack/default
|
- name: /opt/so/saltstack/default
|
||||||
- user: socore
|
- user: root
|
||||||
- group: socore
|
- group: root
|
||||||
- recurse:
|
- recurse:
|
||||||
- user
|
- user
|
||||||
- group
|
- group
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
hydraUrl=${HYDRA_URL:-http://127.0.0.1:4445}
|
hydraContainer=${HYDRA_CONTAINER:-so-hydra}
|
||||||
|
hydraUrl=${HYDRA_URL:-http://localhost:4445}
|
||||||
socRolesFile=${SOC_ROLES_FILE:-/opt/so/conf/soc/soc_clients_roles}
|
socRolesFile=${SOC_ROLES_FILE:-/opt/so/conf/soc/soc_clients_roles}
|
||||||
soUID=${SOCORE_UID:-939}
|
soUID=${SOCORE_UID:-939}
|
||||||
soGID=${SOCORE_GID:-939}
|
soGID=${SOCORE_GID:-939}
|
||||||
@@ -124,6 +125,10 @@ function fail() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hydraCurl() {
|
||||||
|
docker exec "$hydraContainer" curl "$@"
|
||||||
|
}
|
||||||
|
|
||||||
function require() {
|
function require() {
|
||||||
cmd=$1
|
cmd=$1
|
||||||
which "$1" 2>&1 > /dev/null
|
which "$1" 2>&1 > /dev/null
|
||||||
@@ -133,8 +138,8 @@ function require() {
|
|||||||
# Verify this environment is capable of running this script
|
# Verify this environment is capable of running this script
|
||||||
function verifyEnvironment() {
|
function verifyEnvironment() {
|
||||||
require "jq"
|
require "jq"
|
||||||
require "curl"
|
require "docker"
|
||||||
response=$(curl -Ss -L ${hydraUrl}/health/alive)
|
response=$(hydraCurl -Ss -L ${hydraUrl}/health/alive)
|
||||||
[[ "$response" != '{"status":"ok"}' ]] && fail "Unable to communicate with Hydra; specify URL via HYDRA_URL environment variable"
|
[[ "$response" != '{"status":"ok"}' ]] && fail "Unable to communicate with Hydra; specify URL via HYDRA_URL environment variable"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,7 +169,7 @@ function ensureRoleFileExists() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listClients() {
|
function listClients() {
|
||||||
response=$(curl -Ss -L -f ${hydraUrl}/admin/clients)
|
response=$(hydraCurl -Ss -L -f ${hydraUrl}/admin/clients)
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Hydra"
|
[[ $? != 0 ]] && fail "Unable to communicate with Hydra"
|
||||||
|
|
||||||
clientIds=$(echo "${response}" | jq -r ".[] | .client_id" | sort)
|
clientIds=$(echo "${response}" | jq -r ".[] | .client_id" | sort)
|
||||||
@@ -251,7 +256,7 @@ function createClient() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl -Ss -L --fail-with-body -X POST ${hydraUrl}/admin/clients -d "$body")
|
response=$(hydraCurl -Ss -L --fail-with-body -X POST ${hydraUrl}/admin/clients -d "$body")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
error=$(echo $response | jq .error)
|
error=$(echo $response | jq .error)
|
||||||
fail "Failed to submit request to Hydra: $error"
|
fail "Failed to submit request to Hydra: $error"
|
||||||
@@ -283,7 +288,7 @@ function update() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl -Ss -L --fail-with-body -X PATCH ${hydraUrl}/admin/clients/$id -d "$body")
|
response=$(hydraCurl -Ss -L --fail-with-body -X PATCH ${hydraUrl}/admin/clients/$id -d "$body")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
error=$(echo $response | jq .error)
|
error=$(echo $response | jq .error)
|
||||||
fail "Failed to submit request to Hydra: $error"
|
fail "Failed to submit request to Hydra: $error"
|
||||||
@@ -305,7 +310,7 @@ function generateSecret() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl -Ss -L --fail-with-body -X PATCH ${hydraUrl}/admin/clients/$id -d "$body")
|
response=$(hydraCurl -Ss -L --fail-with-body -X PATCH ${hydraUrl}/admin/clients/$id -d "$body")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
error=$(echo $response | jq .error)
|
error=$(echo $response | jq .error)
|
||||||
fail "Failed to submit request to Hydra: $error"
|
fail "Failed to submit request to Hydra: $error"
|
||||||
@@ -317,7 +322,7 @@ function deleteClient() {
|
|||||||
|
|
||||||
[[ ${identityId} == "" ]] && fail "Client not found"
|
[[ ${identityId} == "" ]] && fail "Client not found"
|
||||||
|
|
||||||
response=$(curl -Ss -XDELETE -L --fail-with-body "${hydraUrl}/admin/clients/$identityId")
|
response=$(hydraCurl -Ss -XDELETE -L --fail-with-body "${hydraUrl}/admin/clients/$identityId")
|
||||||
if [[ $? != 0 ]]; then
|
if [[ $? != 0 ]]; then
|
||||||
error=$(echo $response | jq .error)
|
error=$(echo $response | jq .error)
|
||||||
fail "Failed to submit request to Hydra: $error"
|
fail "Failed to submit request to Hydra: $error"
|
||||||
|
|||||||
@@ -121,8 +121,14 @@ for i in "$@"; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
PILLARFILE=/opt/so/saltstack/local/pillar/minions/$MINION_ID.sls
|
if [[ -n "$MINION_ID" && ! "$MINION_ID" =~ ^[A-Za-z0-9._-]{1,253}$ ]]; then
|
||||||
ADVPILLARFILE=/opt/so/saltstack/local/pillar/minions/adv_$MINION_ID.sls
|
echo "Invalid minion id: $MINION_ID"
|
||||||
|
log "ERROR" "Invalid minion id: $MINION_ID"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
readonly PILLARFILE=/opt/so/saltstack/local/pillar/minions/$MINION_ID.sls
|
||||||
|
readonly ADVPILLARFILE=/opt/so/saltstack/local/pillar/minions/adv_$MINION_ID.sls
|
||||||
|
|
||||||
function getinstallinfo() {
|
function getinstallinfo() {
|
||||||
log "INFO" "Getting install info for minion $MINION_ID"
|
log "INFO" "Getting install info for minion $MINION_ID"
|
||||||
@@ -133,10 +139,23 @@ function getinstallinfo() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
while read -r var; do export "$var"; done <<< "$INSTALLVARS"
|
# install.txt is controlled by the minion; only accept known keys and never eval or export them
|
||||||
if [ $? -ne 0 ]; then
|
local line key
|
||||||
log "ERROR" "Failed to source install variables"
|
while IFS= read -r line; do
|
||||||
return 1
|
[[ "$line" == *=* ]] || continue
|
||||||
|
key=${line%%=*}
|
||||||
|
case "$key" in
|
||||||
|
MAINIP|MNIC|NODE_DESCRIPTION|ES_HEAP_SIZE|PATCHSCHEDULENAME|INTERFACE|NODETYPE|CORECOUNT|LSHOSTNAME|LSHEAP|CPUCORES|IDH_MGTRESTRICT|IDH_SERVICES)
|
||||||
|
printf -v "$key" '%s' "${line#*=}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
log "WARN" "Ignoring unexpected install var from $MINION_ID: ${key:0:64}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done <<< "$INSTALLVARS"
|
||||||
|
|
||||||
|
if [[ "$NODE_DESCRIPTION" == \'*\' ]]; then
|
||||||
|
NODE_DESCRIPTION=${NODE_DESCRIPTION:1:-1}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
log "INFO" "Fetched install info for $MINION_ID (node type: ${NODETYPE:-unset})"
|
log "INFO" "Fetched install info for $MINION_ID (node type: ${NODETYPE:-unset})"
|
||||||
@@ -176,6 +195,12 @@ function pcapspace() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Must be checked before arithmetic expansion, which evaluates array subscripts
|
||||||
|
if [[ ! "$SPACESIZE" =~ ^[0-9]+$ ]]; then
|
||||||
|
log "ERROR" "Invalid disk size for $MINION_ID: ${SPACESIZE:0:64}"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
local s=$(( $SPACESIZE / 1000000 ))
|
local s=$(( $SPACESIZE / 1000000 ))
|
||||||
local s1=$(( $s / 4 * $PCAP_PERCENTAGE ))
|
local s1=$(( $s / 4 * $PCAP_PERCENTAGE ))
|
||||||
|
|
||||||
@@ -1050,6 +1075,57 @@ function updateMineAndApplyStates() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Values end up in a Jinja-rendered pillar and in bash, and may come from the minion
|
||||||
|
function validate_minion_vars() {
|
||||||
|
local error_msg=""
|
||||||
|
# Inline rather than valid_ip4: so-common is not installed yet when setup runs -o=setup
|
||||||
|
local octet='(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])'
|
||||||
|
local ip4_re="^($octet\.){3}$octet$"
|
||||||
|
|
||||||
|
case "$NODETYPE" in
|
||||||
|
EVAL|STANDALONE|MANAGER|MANAGERSEARCH|MANAGERHYPE|IMPORT)
|
||||||
|
# Manager pillars also rewrite the CA pillar, so never accept them from a remote node
|
||||||
|
[[ "$OPERATION" == "setup" ]] || error_msg="Node type $NODETYPE can only be configured during setup"
|
||||||
|
;;
|
||||||
|
FLEET|IDH|HEAVYNODE|SENSOR|SEARCHNODE|RECEIVER|HYPERVISOR|DESKTOP)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
error_msg="Invalid node type: ${NODETYPE:0:64}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [[ -z "$error_msg" ]]; then
|
||||||
|
if [[ ! "$MAINIP" =~ $ip4_re ]]; then
|
||||||
|
error_msg="Invalid MAINIP: ${MAINIP:0:64}"
|
||||||
|
elif [[ ! "$MNIC" =~ ^[A-Za-z0-9._-]*$ ]]; then
|
||||||
|
error_msg="Invalid MNIC: ${MNIC:0:64}"
|
||||||
|
elif [[ ! "$INTERFACE" =~ ^[A-Za-z0-9._-]*$ ]]; then
|
||||||
|
error_msg="Invalid INTERFACE: ${INTERFACE:0:64}"
|
||||||
|
elif [[ ! "$LSHOSTNAME" =~ ^[A-Za-z0-9._-]*$ ]]; then
|
||||||
|
error_msg="Invalid LSHOSTNAME: ${LSHOSTNAME:0:64}"
|
||||||
|
elif [[ ! "$ES_HEAP_SIZE" =~ ^([0-9]+[kKmMgG]?)?$ ]]; then
|
||||||
|
error_msg="Invalid ES_HEAP_SIZE: ${ES_HEAP_SIZE:0:64}"
|
||||||
|
elif [[ ! "$LSHEAP" =~ ^([0-9]+[kKmMgG]?)?$ ]]; then
|
||||||
|
error_msg="Invalid LSHEAP: ${LSHEAP:0:64}"
|
||||||
|
elif [[ ! "$CORECOUNT" =~ ^[0-9]*$ ]]; then
|
||||||
|
error_msg="Invalid CORECOUNT: ${CORECOUNT:0:64}"
|
||||||
|
elif [[ ! "$CPUCORES" =~ ^[0-9]*$ ]]; then
|
||||||
|
error_msg="Invalid CPUCORES: ${CPUCORES:0:64}"
|
||||||
|
elif [[ ! "$IDH_MGTRESTRICT" =~ ^(True|False)?$ ]]; then
|
||||||
|
error_msg="Invalid IDH_MGTRESTRICT: ${IDH_MGTRESTRICT:0:64}"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$error_msg" ]]; then
|
||||||
|
log "ERROR" "$error_msg"
|
||||||
|
echo "$error_msg"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Free text; removing braces is enough to prevent any Jinja delimiter
|
||||||
|
NODE_DESCRIPTION=${NODE_DESCRIPTION//[\{\}[:cntrl:]]/}
|
||||||
|
}
|
||||||
|
|
||||||
function setupMinionFiles() {
|
function setupMinionFiles() {
|
||||||
log "INFO" "Setting up minion files for $MINION_ID (pillar: $PILLARFILE)"
|
log "INFO" "Setting up minion files for $MINION_ID (pillar: $PILLARFILE)"
|
||||||
|
|
||||||
@@ -1061,6 +1137,8 @@ function setupMinionFiles() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
validate_minion_vars || return 1
|
||||||
|
|
||||||
# Create the base minion files
|
# Create the base minion files
|
||||||
create_minion_files || return 1
|
create_minion_files || return 1
|
||||||
|
|
||||||
|
|||||||
@@ -124,8 +124,8 @@ copy_new_files() {
|
|||||||
|
|
||||||
rsync -a salt $default_salt_dir/
|
rsync -a salt $default_salt_dir/
|
||||||
rsync -a pillar $default_salt_dir/
|
rsync -a pillar $default_salt_dir/
|
||||||
chown -R socore:socore $default_salt_dir/salt
|
chown -R root:root $default_salt_dir/salt
|
||||||
chown -R socore:socore $default_salt_dir/pillar
|
chown -R root:root $default_salt_dir/pillar
|
||||||
chmod 755 $default_salt_dir/pillar/firewall/addfirewall.sh
|
chmod 755 $default_salt_dir/pillar/firewall/addfirewall.sh
|
||||||
|
|
||||||
rm -rf /tmp/sogh
|
rm -rf /tmp/sogh
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
kratosUrl=${KRATOS_URL:-http://127.0.0.1:4434/admin}
|
kratosContainer=${KRATOS_CONTAINER:-so-kratos}
|
||||||
|
kratosUrl=${KRATOS_URL:-http://localhost:4434/admin}
|
||||||
databasePath=${KRATOS_DB_PATH:-/nsm/kratos/db/db.sqlite}
|
databasePath=${KRATOS_DB_PATH:-/nsm/kratos/db/db.sqlite}
|
||||||
databaseTimeout=${KRATOS_DB_TIMEOUT:-5000}
|
databaseTimeout=${KRATOS_DB_TIMEOUT:-5000}
|
||||||
bcryptRounds=${BCRYPT_ROUNDS:-12}
|
bcryptRounds=${BCRYPT_ROUNDS:-12}
|
||||||
@@ -154,6 +155,10 @@ function fail() {
|
|||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function kratosCurl() {
|
||||||
|
docker exec "$kratosContainer" curl "$@"
|
||||||
|
}
|
||||||
|
|
||||||
function require() {
|
function require() {
|
||||||
cmd=$1
|
cmd=$1
|
||||||
which "$1" 2>&1 > /dev/null
|
which "$1" 2>&1 > /dev/null
|
||||||
@@ -164,18 +169,18 @@ function require() {
|
|||||||
function verifyEnvironment() {
|
function verifyEnvironment() {
|
||||||
require "htpasswd"
|
require "htpasswd"
|
||||||
require "jq"
|
require "jq"
|
||||||
require "curl"
|
require "docker"
|
||||||
require "openssl"
|
require "openssl"
|
||||||
require "sqlite3"
|
require "sqlite3"
|
||||||
[[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable"
|
[[ ! -f $databasePath ]] && fail "Unable to find database file; specify path via KRATOS_DB_PATH environment variable"
|
||||||
response=$(curl -Ss -L ${kratosUrl}/)
|
response=$(kratosCurl -Ss -L ${kratosUrl}/)
|
||||||
[[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable"
|
[[ "$response" != "404 page not found" ]] && fail "Unable to communicate with Kratos; specify URL via KRATOS_URL environment variable"
|
||||||
}
|
}
|
||||||
|
|
||||||
function findIdByEmail() {
|
function findIdByEmail() {
|
||||||
email=${1,,}
|
email=${1,,}
|
||||||
|
|
||||||
response=$(curl -Ss -L ${kratosUrl}/identities)
|
response=$(kratosCurl -Ss -L ${kratosUrl}/identities)
|
||||||
identityId=$(echo "${response}" | jq -r ".[] | select(.verifiable_addresses[0].value == \"$email\") | .id")
|
identityId=$(echo "${response}" | jq -r ".[] | select(.verifiable_addresses[0].value == \"$email\") | .id")
|
||||||
echo $identityId
|
echo $identityId
|
||||||
}
|
}
|
||||||
@@ -416,7 +421,7 @@ function syncAll() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function listUsers() {
|
function listUsers() {
|
||||||
response=$(curl -Ss -L ${kratosUrl}/identities)
|
response=$(kratosCurl -Ss -L ${kratosUrl}/identities)
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
||||||
|
|
||||||
users=$(echo "${response}" | jq -r ".[] | .verifiable_addresses[0].value" | sort)
|
users=$(echo "${response}" | jq -r ".[] | .verifiable_addresses[0].value" | sort)
|
||||||
@@ -495,7 +500,7 @@ function createUser() {
|
|||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|
||||||
response=$(curl -Ss -L ${kratosUrl}/identities -d "$addUserJson")
|
response=$(kratosCurl -Ss -L ${kratosUrl}/identities -d "$addUserJson")
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
||||||
|
|
||||||
identityId=$(echo "${response}" | jq -r ".id")
|
identityId=$(echo "${response}" | jq -r ".id")
|
||||||
@@ -518,7 +523,7 @@ function updateStatus() {
|
|||||||
identityId=$(findIdByEmail "$email")
|
identityId=$(findIdByEmail "$email")
|
||||||
[[ ${identityId} == "" ]] && fail "User not found"
|
[[ ${identityId} == "" ]] && fail "User not found"
|
||||||
|
|
||||||
response=$(curl -Ss -L "${kratosUrl}/identities/$identityId")
|
response=$(kratosCurl -Ss -L "${kratosUrl}/identities/$identityId")
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
||||||
|
|
||||||
schemaId=$(echo "$response" | jq -r .schema_id)
|
schemaId=$(echo "$response" | jq -r .schema_id)
|
||||||
@@ -531,7 +536,7 @@ function updateStatus() {
|
|||||||
state="inactive"
|
state="inactive"
|
||||||
fi
|
fi
|
||||||
body="{ \"schema_id\": \"$schemaId\", \"state\": \"$state\", \"traits\": $traitBlock }"
|
body="{ \"schema_id\": \"$schemaId\", \"state\": \"$state\", \"traits\": $traitBlock }"
|
||||||
response=$(curl -fSsL -XPUT -H "Content-Type: application/json" "${kratosUrl}/identities/$identityId" -d "$body")
|
response=$(kratosCurl -fSsL -XPUT -H "Content-Type: application/json" "${kratosUrl}/identities/$identityId" -d "$body")
|
||||||
[[ $? != 0 ]] && fail "Unable to update user"
|
[[ $? != 0 ]] && fail "Unable to update user"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +555,7 @@ function updateUserProfile() {
|
|||||||
identityId=$(findIdByEmail "$email")
|
identityId=$(findIdByEmail "$email")
|
||||||
[[ ${identityId} == "" ]] && fail "User not found"
|
[[ ${identityId} == "" ]] && fail "User not found"
|
||||||
|
|
||||||
response=$(curl -Ss -L "${kratosUrl}/identities/$identityId")
|
response=$(kratosCurl -Ss -L "${kratosUrl}/identities/$identityId")
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
||||||
|
|
||||||
schemaId=$(echo "$response" | jq -r .schema_id)
|
schemaId=$(echo "$response" | jq -r .schema_id)
|
||||||
@@ -559,7 +564,7 @@ function updateUserProfile() {
|
|||||||
traitBlock="{\"email\":\"$email\",\"firstName\":\"$firstName\",\"lastName\":\"$lastName\",\"note\":\"$note\"}"
|
traitBlock="{\"email\":\"$email\",\"firstName\":\"$firstName\",\"lastName\":\"$lastName\",\"note\":\"$note\"}"
|
||||||
|
|
||||||
body="{ \"schema_id\": \"$schemaId\", \"state\": \"$state\", \"traits\": $traitBlock }"
|
body="{ \"schema_id\": \"$schemaId\", \"state\": \"$state\", \"traits\": $traitBlock }"
|
||||||
response=$(curl -fSsL -XPUT -H "Content-Type: application/json" "${kratosUrl}/identities/$identityId" -d "$body")
|
response=$(kratosCurl -fSsL -XPUT -H "Content-Type: application/json" "${kratosUrl}/identities/$identityId" -d "$body")
|
||||||
[[ $? != 0 ]] && fail "Unable to update user"
|
[[ $? != 0 ]] && fail "Unable to update user"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,7 +574,7 @@ function deleteUser() {
|
|||||||
identityId=$(findIdByEmail "$email")
|
identityId=$(findIdByEmail "$email")
|
||||||
[[ ${identityId} == "" ]] && fail "User not found"
|
[[ ${identityId} == "" ]] && fail "User not found"
|
||||||
|
|
||||||
response=$(curl -Ss -XDELETE -L "${kratosUrl}/identities/$identityId")
|
response=$(kratosCurl -Ss -XDELETE -L "${kratosUrl}/identities/$identityId")
|
||||||
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
|
||||||
|
|
||||||
rolesTmpFile="${socRolesFile}.tmp"
|
rolesTmpFile="${socRolesFile}.tmp"
|
||||||
|
|||||||
@@ -42,7 +42,8 @@ def loadYaml(filename):
|
|||||||
try:
|
try:
|
||||||
with open(filename, "r") as file:
|
with open(filename, "r") as file:
|
||||||
content = file.read()
|
content = file.read()
|
||||||
return yaml.safe_load(content)
|
loaded = yaml.safe_load(content)
|
||||||
|
return loaded if loaded is not None else {}
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f"File not found: {filename}", file=sys.stderr)
|
print(f"File not found: {filename}", file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@@ -95,6 +95,20 @@ class TestRemove(unittest.TestCase):
|
|||||||
expected = "key1:\n child1: 123\n child2:\n deep2: ab\nkey2: false\n"
|
expected = "key1:\n child1: 123\n child2:\n deep2: ab\nkey2: false\n"
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_remove_empty_file(self):
|
||||||
|
filename = "/tmp/so-yaml_test-remove-empty.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
code = soyaml.remove([filename, "key1"])
|
||||||
|
self.assertEqual(code, 0)
|
||||||
|
|
||||||
|
file = open(filename, "r")
|
||||||
|
actual = file.read()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
self.assertEqual(actual, "{}\n")
|
||||||
|
|
||||||
def test_remove_missing_args(self):
|
def test_remove_missing_args(self):
|
||||||
with patch('sys.exit', new=MagicMock()) as sysmock:
|
with patch('sys.exit', new=MagicMock()) as sysmock:
|
||||||
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
||||||
@@ -294,6 +308,36 @@ class TestRemove(unittest.TestCase):
|
|||||||
expected = "key1:\n child1: 123\n child2:\n deep1: 45\n deep2: d\nkey2: false\nkey3:\n- e\n- f\n- g\n"
|
expected = "key1:\n child1: 123\n child2:\n deep1: 45\n deep2: d\nkey2: false\nkey3:\n- e\n- f\n- g\n"
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_add_empty_file(self):
|
||||||
|
filename = "/tmp/so-yaml_test-add-empty.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
code = soyaml.add([filename, "telegraf.output", "BOTH"])
|
||||||
|
self.assertEqual(code, 0)
|
||||||
|
|
||||||
|
file = open(filename, "r")
|
||||||
|
actual = file.read()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
expected = "telegraf:\n output: BOTH\n"
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_add_empty_file_simple(self):
|
||||||
|
filename = "/tmp/so-yaml_test-add-empty-simple.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
code = soyaml.add([filename, "telegraf", "BOTH"])
|
||||||
|
self.assertEqual(code, 0)
|
||||||
|
|
||||||
|
file = open(filename, "r")
|
||||||
|
actual = file.read()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
expected = "telegraf: BOTH\n"
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
def test_replace_missing_arg(self):
|
def test_replace_missing_arg(self):
|
||||||
with patch('sys.exit', new=MagicMock()) as sysmock:
|
with patch('sys.exit', new=MagicMock()) as sysmock:
|
||||||
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
||||||
@@ -346,6 +390,21 @@ class TestRemove(unittest.TestCase):
|
|||||||
expected = "key1:\n child1: 123\n child2:\n deep1: 46\nkey2: false\nkey3:\n- e\n- f\n- g\n"
|
expected = "key1:\n child1: 123\n child2:\n deep1: 46\nkey2: false\nkey3:\n- e\n- f\n- g\n"
|
||||||
self.assertEqual(actual, expected)
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
|
def test_replace_empty_file(self):
|
||||||
|
filename = "/tmp/so-yaml_test-replace-empty.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
code = soyaml.replace([filename, "telegraf.output", "BOTH"])
|
||||||
|
self.assertEqual(code, 0)
|
||||||
|
|
||||||
|
file = open(filename, "r")
|
||||||
|
actual = file.read()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
expected = "telegraf:\n output: BOTH\n"
|
||||||
|
self.assertEqual(actual, expected)
|
||||||
|
|
||||||
def test_convert(self):
|
def test_convert(self):
|
||||||
self.assertEqual(soyaml.convertType("foo"), "foo")
|
self.assertEqual(soyaml.convertType("foo"), "foo")
|
||||||
self.assertEqual(soyaml.convertType("foo.bar"), "foo.bar")
|
self.assertEqual(soyaml.convertType("foo.bar"), "foo.bar")
|
||||||
@@ -506,6 +565,18 @@ class TestRemove(unittest.TestCase):
|
|||||||
self.assertEqual(result, 2)
|
self.assertEqual(result, 2)
|
||||||
self.assertEqual("", mock_stdout.getvalue())
|
self.assertEqual("", mock_stdout.getvalue())
|
||||||
|
|
||||||
|
def test_get_empty_file(self):
|
||||||
|
with patch('sys.stdout', new=StringIO()) as mock_stdout:
|
||||||
|
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
||||||
|
filename = "/tmp/so-yaml_test-get-empty.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
result = soyaml.get([filename, "telegraf.output"])
|
||||||
|
self.assertEqual(result, 2)
|
||||||
|
self.assertEqual("", mock_stdout.getvalue())
|
||||||
|
self.assertIn("Key 'telegraf.output' not found by so-yaml.py", mock_stderr.getvalue())
|
||||||
|
|
||||||
def test_get_usage(self):
|
def test_get_usage(self):
|
||||||
with patch('sys.exit', new=MagicMock()) as sysmock:
|
with patch('sys.exit', new=MagicMock()) as sysmock:
|
||||||
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
with patch('sys.stderr', new=StringIO()) as mock_stderr:
|
||||||
@@ -991,3 +1062,29 @@ class TestLoadYaml(unittest.TestCase):
|
|||||||
soyaml.loadYaml("/tmp/so-yaml_test-unreadable.yaml")
|
soyaml.loadYaml("/tmp/so-yaml_test-unreadable.yaml")
|
||||||
sysmock.assert_called_with(1)
|
sysmock.assert_called_with(1)
|
||||||
self.assertIn("Error reading file", mock_stderr.getvalue())
|
self.assertIn("Error reading file", mock_stderr.getvalue())
|
||||||
|
|
||||||
|
def test_load_yaml_empty_file(self):
|
||||||
|
filename = "/tmp/so-yaml_test-load-empty.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
result = soyaml.loadYaml(filename)
|
||||||
|
self.assertEqual(result, {})
|
||||||
|
|
||||||
|
def test_load_yaml_whitespace_only(self):
|
||||||
|
filename = "/tmp/so-yaml_test-load-whitespace.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.write(" \n\n \n")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
result = soyaml.loadYaml(filename)
|
||||||
|
self.assertEqual(result, {})
|
||||||
|
|
||||||
|
def test_load_yaml_comments_only(self):
|
||||||
|
filename = "/tmp/so-yaml_test-load-comments.yaml"
|
||||||
|
file = open(filename, "w")
|
||||||
|
file.write("# Just a comment\n# Another comment\n")
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
result = soyaml.loadYaml(filename)
|
||||||
|
self.assertEqual(result, {})
|
||||||
@@ -28,6 +28,7 @@ INSTALLEDSALTVERSION=$(salt --versions-report | grep Salt: | awk '{print $2}')
|
|||||||
# percentage like "25%"). Empty means so-soup-grid-highstate uses the salt:auto_apply:batch
|
# percentage like "25%"). Empty means so-soup-grid-highstate uses the salt:auto_apply:batch
|
||||||
# pillar default.
|
# pillar default.
|
||||||
BATCHSIZE=
|
BATCHSIZE=
|
||||||
|
DEFAULT_DOCKER_RANGE='172.17.1.0/24'
|
||||||
SOUP_LOG=/root/soup.log
|
SOUP_LOG=/root/soup.log
|
||||||
SOUP_DEBUG_LOG=/root/soup-debug.log
|
SOUP_DEBUG_LOG=/root/soup-debug.log
|
||||||
WHATWOULDYOUSAYYAHDOHERE=soup
|
WHATWOULDYOUSAYYAHDOHERE=soup
|
||||||
@@ -605,6 +606,7 @@ preupgrade_changes() {
|
|||||||
[[ "$INSTALLEDVERSION" == "3.0.0" ]] && up_to_3.1.0
|
[[ "$INSTALLEDVERSION" == "3.0.0" ]] && up_to_3.1.0
|
||||||
[[ "$INSTALLEDVERSION" == "3.1.0" ]] && up_to_3.2.0
|
[[ "$INSTALLEDVERSION" == "3.1.0" ]] && up_to_3.2.0
|
||||||
[[ "$INSTALLEDVERSION" == "3.2.0" ]] && up_to_3.3.0
|
[[ "$INSTALLEDVERSION" == "3.2.0" ]] && up_to_3.3.0
|
||||||
|
[[ "$INSTALLEDVERSION" == "3.3.0" ]] && up_to_3.4.0
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,6 +625,7 @@ postupgrade_changes() {
|
|||||||
[[ "$POSTVERSION" == "3.0.0" ]] && post_to_3.1.0
|
[[ "$POSTVERSION" == "3.0.0" ]] && post_to_3.1.0
|
||||||
[[ "$POSTVERSION" == "3.1.0" ]] && post_to_3.2.0
|
[[ "$POSTVERSION" == "3.1.0" ]] && post_to_3.2.0
|
||||||
[[ "$POSTVERSION" == "3.2.0" ]] && post_to_3.3.0
|
[[ "$POSTVERSION" == "3.2.0" ]] && post_to_3.3.0
|
||||||
|
[[ "$POSTVERSION" == "3.3.0" ]] && post_to_3.4.0
|
||||||
# All applicable post-upgrade steps completed; clear the resume marker.
|
# All applicable post-upgrade steps completed; clear the resume marker.
|
||||||
rm -f "$POSTVERSION_FILE"
|
rm -f "$POSTVERSION_FILE"
|
||||||
true
|
true
|
||||||
@@ -1173,6 +1176,93 @@ post_to_3.3.0() {
|
|||||||
}
|
}
|
||||||
### 3.3.0 End ###
|
### 3.3.0 End ###
|
||||||
|
|
||||||
|
### 3.4.0 Scripts ###
|
||||||
|
up_to_3.4.0() {
|
||||||
|
set_soauth_range
|
||||||
|
|
||||||
|
echo "Removing so-kratos, so-hydra and so-soc so they are recreated on the soauth network."
|
||||||
|
docker rm -f so-kratos so-hydra so-soc >> $SOUP_LOG 2>&1
|
||||||
|
|
||||||
|
for template in so-metrics-logstash.node so-metrics-logstash.stack_monitoring.node; do
|
||||||
|
if ! remove_elasticsearch_index_template "$template" "logstash node and node_cel index patterns reversed"; then
|
||||||
|
FINAL_MESSAGE_QUEUE+=("WARNING: Unable to automatically remove the $template index template. Addon integration templates may fail to load until it is removed:")
|
||||||
|
FINAL_MESSAGE_QUEUE+=(" - sudo so-elasticsearch-query _index_template/$template -XDELETE && so-checkin")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
INSTALLEDVERSION=3.4.0
|
||||||
|
}
|
||||||
|
|
||||||
|
set_soauth_range() {
|
||||||
|
local pillar_file=/opt/so/saltstack/local/pillar/docker/soc_docker.sls
|
||||||
|
local current_range suggested authnet authgw input
|
||||||
|
|
||||||
|
[[ -f "$pillar_file" ]] || return 0
|
||||||
|
|
||||||
|
current_range=$(so-yaml.py get -r "$pillar_file" docker.range 2>/dev/null) || return 0
|
||||||
|
|
||||||
|
# A default range gets the 172.17.2.0/24 from docker/defaults.yaml, same as a fresh
|
||||||
|
# install, so there is nothing to ask about.
|
||||||
|
[[ -n "$current_range" && "$current_range" != "$DEFAULT_DOCKER_RANGE" ]] || return 0
|
||||||
|
|
||||||
|
if so-yaml.py get -r "$pillar_file" docker.networks.soauth.range >/dev/null 2>&1; then
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
suggested=$(echo "${current_range%%/*}" | awk -F'.' '{ printf "%s.%s.%s.%s", $1, $2, ($3 + 1) % 256, $4 }')
|
||||||
|
|
||||||
|
if [[ -z $UNATTENDED ]]; then
|
||||||
|
echo ""
|
||||||
|
echo "This grid uses a custom Docker range ($current_range). The authentication"
|
||||||
|
echo "services are moving to their own isolated network, which needs a second /24"
|
||||||
|
echo "that does not overlap it."
|
||||||
|
echo ""
|
||||||
|
while :; do
|
||||||
|
read -rp "Enter the network without the /24 suffix, or press Enter for ${suggested}: " input
|
||||||
|
[[ -z "$input" ]] && input="$suggested"
|
||||||
|
if valid_soauth_range "$input" "$current_range"; then
|
||||||
|
authnet="$input"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
echo "That range must be a valid IPv4 network, must not be within 172.17.0.0/24, and must not overlap ${current_range}."
|
||||||
|
done
|
||||||
|
else
|
||||||
|
if ! valid_soauth_range "$suggested" "$current_range"; then
|
||||||
|
FINAL_MESSAGE_QUEUE+=("WARNING: Unable to pick a range for the authentication network alongside $current_range. Set it manually before the next highstate:")
|
||||||
|
FINAL_MESSAGE_QUEUE+=(" - so-yaml.py add $pillar_file docker.networks.soauth.range <network>/24")
|
||||||
|
FINAL_MESSAGE_QUEUE+=(" - so-yaml.py add $pillar_file docker.networks.soauth.gateway <gateway>")
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
authnet="$suggested"
|
||||||
|
FINAL_MESSAGE_QUEUE+=("NOTE: The authentication services moved to an isolated Docker network and were assigned ${authnet}/24.")
|
||||||
|
FINAL_MESSAGE_QUEUE+=(" - If that conflicts with your environment, update docker.networks.soauth in $pillar_file and run so-checkin.")
|
||||||
|
fi
|
||||||
|
|
||||||
|
authgw=$(echo "$authnet" | awk -F'.' '{print $1,$2,$3,1}' OFS='.')
|
||||||
|
|
||||||
|
echo "Assigning the authentication network the range ${authnet}/24."
|
||||||
|
so-yaml.py add "$pillar_file" docker.networks.soauth.range "${authnet}/24" >> $SOUP_LOG 2>&1
|
||||||
|
so-yaml.py add "$pillar_file" docker.networks.soauth.gateway "$authgw" >> $SOUP_LOG 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_soauth_range() {
|
||||||
|
local candidate=$1 docker_range=$2
|
||||||
|
|
||||||
|
valid_ip4 "$candidate" || return 1
|
||||||
|
[[ $candidate =~ ^172\.17\.0\. ]] && return 1
|
||||||
|
[[ "${candidate}/24" == "$docker_range" ]] && return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
post_to_3.4.0() {
|
||||||
|
for idx in "metrics-logstash.node-default" "metrics-logstash.stack_monitoring.node-default"; do
|
||||||
|
rollover_index "$idx"
|
||||||
|
done
|
||||||
|
|
||||||
|
set_postversion 3.4.0
|
||||||
|
}
|
||||||
|
### 3.4.0 End ###
|
||||||
|
|
||||||
|
|
||||||
repo_sync() {
|
repo_sync() {
|
||||||
echo "Sync the local repo."
|
echo "Sync the local repo."
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ nginx_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://nginx/tools/sbin
|
- source: salt://nginx/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#nginx_sbin_jinja:
|
#nginx_sbin_jinja:
|
||||||
|
|||||||
@@ -50,16 +50,16 @@ redis_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://redis/tools/sbin
|
- source: salt://redis/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
redis_sbin_jinja:
|
redis_sbin_jinja:
|
||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://redis/tools/sbin_jinja
|
- source: salt://redis/tools/sbin_jinja
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
'epel-testing.repo',
|
'epel-testing.repo',
|
||||||
'saltstack.repo',
|
'saltstack.repo',
|
||||||
'salt-latest.repo',
|
'salt-latest.repo',
|
||||||
'wazuh.repo'
|
'wazuh.repo',
|
||||||
'Rocky-Base.repo',
|
'Rocky-Base.repo',
|
||||||
'Rocky-CR.repo',
|
'Rocky-CR.repo',
|
||||||
'Rocky-Debuginfo.repo',
|
'Rocky-Debuginfo.repo',
|
||||||
|
|||||||
+4
-2
@@ -3,6 +3,8 @@ salt_bootstrap:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/bootstrap-salt.sh
|
- name: /usr/sbin/bootstrap-salt.sh
|
||||||
- source: salt://salt/scripts/bootstrap-salt.sh
|
- source: salt://salt/scripts/bootstrap-salt.sh
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
- show_changes: False
|
- show_changes: False
|
||||||
|
|
||||||
@@ -10,6 +12,6 @@ salt_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://salt/tools/sbin
|
- source: salt://salt/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
@@ -35,6 +35,8 @@ combine_bond_script:
|
|||||||
file.managed:
|
file.managed:
|
||||||
- name: /usr/sbin/so-combine-bond
|
- name: /usr/sbin/so-combine-bond
|
||||||
- source: salt://sensor/tools/sbin_jinja/so-combine-bond
|
- source: salt://sensor/tools/sbin_jinja/so-combine-bond
|
||||||
|
- user: root
|
||||||
|
- group: root
|
||||||
- mode: 755
|
- mode: 755
|
||||||
- template: jinja
|
- template: jinja
|
||||||
- defaults:
|
- defaults:
|
||||||
|
|||||||
@@ -64,8 +64,8 @@ sensoroni_sbin:
|
|||||||
file.recurse:
|
file.recurse:
|
||||||
- name: /usr/sbin
|
- name: /usr/sbin
|
||||||
- source: salt://sensoroni/tools/sbin
|
- source: salt://sensoroni/tools/sbin
|
||||||
- user: 939
|
- user: root
|
||||||
- group: 939
|
- group: root
|
||||||
- file_mode: 755
|
- file_mode: 755
|
||||||
|
|
||||||
#sensoroni_sbin_jinja:
|
#sensoroni_sbin_jinja:
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loaded 100 of 268 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user