diff --git a/salt/airgap/files/yum.conf b/salt/airgap/files/yum.conf
new file mode 100644
index 000000000..cbab7607d
--- /dev/null
+++ b/salt/airgap/files/yum.conf
@@ -0,0 +1,12 @@
+[main]
+cachedir=/var/cache/yum/$basearch/$releasever
+keepcache=0
+debuglevel=2
+logfile=/var/log/yum.log
+exactarch=1
+obsoletes=1
+gpgcheck=1
+plugins=1
+installonly_limit=2
+bugtracker_url=http://bugs.centos.org/set_project.php?project_id=23&ref=http://bugs.centos.org/bug_report_page.php?category=yum
+distroverpkg=centos-release
\ No newline at end of file
diff --git a/salt/airgap/init.sls b/salt/airgap/init.sls
new file mode 100644
index 000000000..b7ad3da1b
--- /dev/null
+++ b/salt/airgap/init.sls
@@ -0,0 +1,60 @@
+{% set MANAGER = salt['grains.get']('master') %}
+airgapyum:
+ file.managed:
+ - name: /etc/yum/yum.conf
+ - source: salt://airgap/files/yum.conf
+
+airgap_repo:
+ pkgrepo.managed:
+ - humanname: Airgap Repo
+ - baseurl: https://{{ MANAGER }}/repo
+ - gpgcheck: 0
+ - sslverify: 0
+
+agbase:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-Base.repo
+
+agcr:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-CR.repo
+
+agdebug:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-Debuginfo.repo
+
+agfasttrack:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-fasttrack.repo
+
+agmedia:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-Media.repo
+
+agsources:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-Sources.repo
+
+agvault:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-Vault.repo
+
+agkernel:
+ file.absent:
+ - name: /etc/yum.repos.d/CentOS-x86_64-kernel.repo
+
+agepel:
+ file.absent:
+ - name: /etc/yum.repos.d/epel.repo
+
+agtesting:
+ file.absent:
+ - name: /etc/yum.repos.d/epel-testing.repo
+
+agssrepo:
+ file.absent:
+ - name: /etc/yum.repos.d/saltstack.repo
+
+agwazrepo:
+ file.absent:
+ - name: /etc/yum.repos.d/wazuh.repo
\ No newline at end of file
diff --git a/salt/common/maps/so-status.map.jinja b/salt/common/maps/so-status.map.jinja
index 21dd14ec9..fb23e6708 100644
--- a/salt/common/maps/so-status.map.jinja
+++ b/salt/common/maps/so-status.map.jinja
@@ -5,6 +5,9 @@
# to the list predefined by the role / minion id affix
{% macro append_containers(pillar_name, k, compare )%}
{% if salt['pillar.get'](pillar_name~':'~k, {}) != compare %}
+ {% if k == 'enabled' %}
+ {% set k = pillar_name %}
+ {% endif %}
{% from 'common/maps/'~k~'.map.jinja' import docker as d with context %}
{% for li in d['containers'] %}
{{ docker['containers'].append(li) }}
@@ -21,7 +24,7 @@
{% if role in ['eval', 'managersearch', 'manager', 'standalone'] %}
{{ append_containers('manager', 'grafana', 0) }}
{{ append_containers('global', 'fleet_manager', 0) }}
- {{ append_containers('manager', 'wazuh', 0) }}
+ {{ append_containers('global', 'wazuh', 0) }}
{{ append_containers('manager', 'thehive', 0) }}
{{ append_containers('manager', 'playbook', 0) }}
{{ append_containers('manager', 'freq', 0) }}
@@ -29,7 +32,7 @@
{% endif %}
{% if role in ['eval', 'heavynode', 'sensor', 'standalone'] %}
- {{ append_containers('global', 'strelka', 0) }}
+ {{ append_containers('strelka', 'enabled', 0) }}
{% endif %}
{% if role in ['heavynode', 'standalone'] %}
diff --git a/salt/common/tools/sbin/so-cortex-user-add b/salt/common/tools/sbin/so-cortex-user-add
index 43126f709..dbb5b9716 100755
--- a/salt/common/tools/sbin/so-cortex-user-add
+++ b/salt/common/tools/sbin/so-cortex-user-add
@@ -48,6 +48,7 @@ if [[ "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully added user to Cortex."
else
echo "Unable to add user to Cortex; user might already exist."
+ echo $resp
exit 2
fi
\ No newline at end of file
diff --git a/salt/common/tools/sbin/so-cortex-user-enable b/salt/common/tools/sbin/so-cortex-user-enable
index 63cd2f089..cbfdceb25 100755
--- a/salt/common/tools/sbin/so-cortex-user-enable
+++ b/salt/common/tools/sbin/so-cortex-user-enable
@@ -51,6 +51,7 @@ if [[ "$resp" =~ \"status\":\"Locked\" || "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully updated user in Cortex."
else
echo "Failed to update user in Cortex."
+ echo $resp
exit 2
fi
\ No newline at end of file
diff --git a/salt/common/tools/sbin/so-fleet-user-add b/salt/common/tools/sbin/so-fleet-user-add
index 9637aa63c..5560b0522 100755
--- a/salt/common/tools/sbin/so-fleet-user-add
+++ b/salt/common/tools/sbin/so-fleet-user-add
@@ -54,5 +54,6 @@ if [[ $? -eq 0 ]]; then
echo "Successfully added user to Fleet."
else
echo "Unable to add user to Fleet; user might already exist."
+ echo $resp
exit 2
fi
\ No newline at end of file
diff --git a/salt/common/tools/sbin/so-fleet-user-enable b/salt/common/tools/sbin/so-fleet-user-enable
index 0ea826391..a632844bb 100755
--- a/salt/common/tools/sbin/so-fleet-user-enable
+++ b/salt/common/tools/sbin/so-fleet-user-enable
@@ -53,5 +53,6 @@ if [[ $? -eq 0 ]]; then
echo "Successfully updated user in Fleet."
else
echo "Failed to update user in Fleet."
+ echo $resp
exit 2
fi
\ No newline at end of file
diff --git a/salt/common/tools/sbin/so-status b/salt/common/tools/sbin/so-status
index 7a7d6c783..8658f4757 100755
--- a/salt/common/tools/sbin/so-status
+++ b/salt/common/tools/sbin/so-status
@@ -15,7 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
{%- from 'common/maps/so-status.map.jinja' import docker with context %}
-{%- set container_list = docker['containers'] | sort %}
+{%- set container_list = docker['containers'] | sort | unique %}
if ! [ "$(id -u)" = 0 ]; then
echo "This command must be run as root"
@@ -71,9 +71,9 @@ compare_lists() {
# {% endraw %}
create_expected_container_list() {
- {% for item in container_list%}
+ {% for item in container_list -%}
expected_container_list+=("{{ item }}")
- {% endfor %}
+ {% endfor -%}
}
populate_container_lists() {
diff --git a/salt/common/tools/sbin/so-thehive-user-add b/salt/common/tools/sbin/so-thehive-user-add
index 0c9553abc..fc7a56f63 100755
--- a/salt/common/tools/sbin/so-thehive-user-add
+++ b/salt/common/tools/sbin/so-thehive-user-add
@@ -47,5 +47,6 @@ if [[ "$resp" =~ \"status\":\"Ok\" ]]; then
echo "Successfully added user to TheHive."
else
echo "Unable to add user to TheHive; user might already exist."
+ echo $resp
exit 2
fi
diff --git a/salt/common/tools/sbin/so-user b/salt/common/tools/sbin/so-user
index 4616be3f5..e354bcce4 100755
--- a/salt/common/tools/sbin/so-user
+++ b/salt/common/tools/sbin/so-user
@@ -11,12 +11,13 @@
. /usr/sbin/so-common
if [[ $# < 1 || $# > 2 ]]; then
- echo "Usage: $0 [email]"
+ echo "Usage: $0 [email]"
echo ""
echo " list: Lists all user email addresses currently defined in the identity system"
echo " add: Adds a new user to the identity system; requires 'email' parameter"
echo " update: Updates a user's password; requires 'email' parameter"
- echo " delete: Deletes an existing user; requires 'email' parameter"
+ echo " enable: Enables a user; requires 'email' parameter"
+ echo " disable: Disables a user; requires 'email' parameter"
echo " validate: Validates that the given email address and password are acceptable for defining a new user; requires 'email' parameter"
echo " valemail: Validates that the given email address is acceptable for defining a new user; requires 'email' parameter"
echo " valpass: Validates that a password is acceptable for defining a new user"
@@ -63,7 +64,7 @@ function findIdByEmail() {
email=$1
response=$(curl -Ss ${kratosUrl}/identities)
- identityId=$(echo "${response}" | jq ".[] | select(.addresses[0].value == \"$email\") | .id")
+ identityId=$(echo "${response}" | jq ".[] | select(.verifiable_addresses[0].value == \"$email\") | .id")
echo $identityId
}
@@ -113,7 +114,7 @@ function listUsers() {
response=$(curl -Ss ${kratosUrl}/identities)
[[ $? != 0 ]] && fail "Unable to communicate with Kratos"
- echo "${response}" | jq -r ".[] | .addresses[0].value" | sort
+ echo "${response}" | jq -r ".[] | .verifiable_addresses[0].value" | sort
}
function createUser() {
@@ -122,17 +123,8 @@ function createUser() {
now=$(date -u +%FT%TZ)
addUserJson=$(cat <> /etc/yum/pluginconf.d/versionlock.list
+
+# NetworkMiner has a compatibility issue with Mono 6 right now
+0:mono-complete-4.2.1.102-0.xamarin.1.*
+0:mono-core-4.2.1.102-0.xamarin.1.*
+0:mono-data-4.2.1.102-0.xamarin.1.*
+0:mono-data-oracle-4.2.1.102-0.xamarin.1.*
+0:mono-data-sqlite-4.2.1.102-0.xamarin.1.*
+0:mono-devel-4.2.1.102-0.xamarin.1.*
+0:mono-extras-4.2.1.102-0.xamarin.1.*
+0:mono-locale-extras-4.2.1.102-0.xamarin.1.*
+0:mono-mvc-4.2.1.102-0.xamarin.1.*
+0:mono-nunit-4.2.1.102-0.xamarin.1.*
+0:mono-reactive-4.2.1.102-0.xamarin.1.*
+0:mono-wcf-4.2.1.102-0.xamarin.1.*
+0:mono-web-4.2.1.102-0.xamarin.1.*
+0:mono-winforms-4.2.1.102-0.xamarin.1.*
+0:mono-winfxcore-4.2.1.102-0.xamarin.1.*
+EOF
+
+fi
# Install Mono - prereq for NetworkMiner
rpmkeys --import "http://pool.sks-keyservers.net/pks/lookup?op=get&search=0x3fa7e0328081bff6a14da29aa6a19b38d3d831ef";
curl https://download.mono-project.com/repo/centos7-stable.repo | tee /etc/yum.repos.d/mono-centos7-stable.repo;
-yum -y install mono-devel;
+yum -y install mono-core mono-basic mono-winforms expect
# Install NetworkMiner
yum -y install libcanberra-gtk2;
-wget https://www.netresec.com/?download=NetworkMiner -O /tmp/nm.zip;
+wget https://www.netresec.com/?download=NetworkMiner_2-4 -O /tmp/nm.zip;
mkdir -p /opt/networkminer/
unzip /tmp/nm.zip -d /opt/networkminer/;
rm /tmp/nm.zip;
diff --git a/setup/so-functions b/setup/so-functions
index 73828b091..01dc15c78 100755
--- a/setup/so-functions
+++ b/setup/so-functions
@@ -480,72 +480,6 @@ check_requirements() {
fi
}
-copy_salt_master_config() {
-
- # Copy the Salt master config template to the proper directory
- if [ "$setup_type" = 'iso' ]; then
- cp /root/SecurityOnion/files/master /etc/salt/master >> "$setup_log" 2>&1
- else
- cp ../files/master /etc/salt/master >> "$setup_log" 2>&1
- fi
-
- # Restart the service so it picks up the changes
- systemctl restart salt-master >> "$setup_log" 2>&1
-}
-
-copy_minion_tmp_files() {
- case "$install_type" in
- 'MANAGER' | 'EVAL' | 'HELIXSENSOR' | 'MANAGERSEARCH' | 'STANDALONE' | 'IMPORT')
- echo "Copying pillar and salt files in $temp_install_dir to $local_salt_dir"
- cp -Rv "$temp_install_dir"/pillar/ $local_salt_dir/ >> "$setup_log" 2>&1
- if [ -d "$temp_install_dir"/salt ] ; then
- cp -Rv "$temp_install_dir"/salt/ $local_salt_dir/ >> "$setup_log" 2>&1
- fi
- ;;
- *)
- {
- echo "scp pillar and salt files in $temp_install_dir to manager $local_salt_dir";
- ssh -i /root/.ssh/so.key soremote@"$MSRV" mkdir -p /tmp/"$MINION_ID"/pillar;
- ssh -i /root/.ssh/so.key soremote@"$MSRV" mkdir -p /tmp/"$MINION_ID"/schedules;
- scp -prv -i /root/.ssh/so.key "$temp_install_dir"/pillar/minions/* soremote@"$MSRV":/tmp/"$MINION_ID"/pillar/;
- if [ -d $temp_install_dir/salt/patch/os/schedules/ ]; then
- if [ "$(ls -A $temp_install_dir/salt/patch/os/schedules/)" ]; then
- scp -prv -i /root/.ssh/so.key $temp_install_dir/salt/patch/os/schedules/* soremote@$MSRV:/tmp/$MINION_ID/schedules;
- fi
- fi
- ssh -i /root/.ssh/so.key soremote@"$MSRV" sudo $default_salt_dir/salt/manager/files/add_minion.sh "$MINION_ID";
- } >> "$setup_log" 2>&1
- ;;
- esac
-}
-
-copy_ssh_key() {
-
- echo "Generating SSH key"
- # Generate SSH key
- mkdir -p /root/.ssh
- ssh-keygen -f /root/.ssh/so.key -t rsa -q -N "" < /dev/zero
- chown -R "$SUDO_USER":"$SUDO_USER" /root/.ssh
- echo "Copying the SSH key to the manager"
- #Copy the key over to the manager
- ssh-copy-id -f -i /root/.ssh/so.key soremote@"$MSRV"
-}
-
-create_local_directories() {
- echo "Creating local pillar and salt directories"
- PILLARSALTDIR=${SCRIPTDIR::-5}
- for i in "pillar" "salt"; do
- for d in $(find $PILLARSALTDIR/$i -type d); do
- suffixdir=${d//$PILLARSALTDIR/}
- if [ ! -d "$local_salt_dir/$suffixdir" ]; then
- mkdir -v "$local_salt_dir$suffixdir" >> "$setup_log" 2>&1
- fi
- done
- chown -R socore:socore "$local_salt_dir/$i"
- done
-
-}
-
configure_network_sensor() {
echo "Setting up sensor interface" >> "$setup_log" 2>&1
local nic_error=0
@@ -630,6 +564,77 @@ configure_network_sensor() {
fi
}
+copy_salt_master_config() {
+
+ # Copy the Salt master config template to the proper directory
+ if [ "$setup_type" = 'iso' ]; then
+ cp /root/SecurityOnion/files/master /etc/salt/master >> "$setup_log" 2>&1
+ else
+ cp ../files/master /etc/salt/master >> "$setup_log" 2>&1
+ fi
+
+ # Restart the service so it picks up the changes
+ systemctl restart salt-master >> "$setup_log" 2>&1
+}
+
+copy_minion_tmp_files() {
+ case "$install_type" in
+ 'MANAGER' | 'EVAL' | 'HELIXSENSOR' | 'MANAGERSEARCH' | 'STANDALONE' | 'IMPORT')
+ echo "Copying pillar and salt files in $temp_install_dir to $local_salt_dir"
+ cp -Rv "$temp_install_dir"/pillar/ $local_salt_dir/ >> "$setup_log" 2>&1
+ if [ -d "$temp_install_dir"/salt ] ; then
+ cp -Rv "$temp_install_dir"/salt/ $local_salt_dir/ >> "$setup_log" 2>&1
+ fi
+ ;;
+ *)
+ {
+ echo "scp pillar and salt files in $temp_install_dir to manager $local_salt_dir";
+ ssh -i /root/.ssh/so.key soremote@"$MSRV" mkdir -p /tmp/"$MINION_ID"/pillar;
+ ssh -i /root/.ssh/so.key soremote@"$MSRV" mkdir -p /tmp/"$MINION_ID"/schedules;
+ scp -prv -i /root/.ssh/so.key "$temp_install_dir"/pillar/minions/* soremote@"$MSRV":/tmp/"$MINION_ID"/pillar/;
+ if [ -d $temp_install_dir/salt/patch/os/schedules/ ]; then
+ if [ "$(ls -A $temp_install_dir/salt/patch/os/schedules/)" ]; then
+ scp -prv -i /root/.ssh/so.key $temp_install_dir/salt/patch/os/schedules/* soremote@$MSRV:/tmp/$MINION_ID/schedules;
+ fi
+ fi
+ ssh -i /root/.ssh/so.key soremote@"$MSRV" sudo $default_salt_dir/salt/manager/files/add_minion.sh "$MINION_ID";
+ } >> "$setup_log" 2>&1
+ ;;
+ esac
+}
+
+copy_ssh_key() {
+
+ echo "Generating SSH key"
+ # Generate SSH key
+ mkdir -p /root/.ssh
+ ssh-keygen -f /root/.ssh/so.key -t rsa -q -N "" < /dev/zero
+ chown -R "$SUDO_USER":"$SUDO_USER" /root/.ssh
+ echo "Copying the SSH key to the manager"
+ #Copy the key over to the manager
+ ssh-copy-id -f -i /root/.ssh/so.key soremote@"$MSRV"
+}
+
+create_local_directories() {
+ echo "Creating local pillar and salt directories"
+ PILLARSALTDIR=${SCRIPTDIR::-5}
+ for i in "pillar" "salt"; do
+ for d in $(find $PILLARSALTDIR/$i -type d); do
+ suffixdir=${d//$PILLARSALTDIR/}
+ if [ ! -d "$local_salt_dir/$suffixdir" ]; then
+ mkdir -v "$local_salt_dir$suffixdir" >> "$setup_log" 2>&1
+ fi
+ done
+ chown -R socore:socore "$local_salt_dir/$i"
+ done
+
+}
+
+create_repo() {
+ # Create the repo for airgap
+ createrepo /nsm/repo
+}
+
detect_cloud() {
echo "Testing if setup is running on a cloud instance..." >> "$setup_log" 2>&1
if ( curl --fail -s -m 5 http://169.254.169.254/latest/meta-data/instance-id > /dev/null ) || ( dmidecode -s bios-vendor | grep -q Google > /dev/null); then export is_cloud="true"; fi
@@ -1096,6 +1101,14 @@ manager_global() {
" ids: $NIDS"\
" url_base: $REDIRECTIT"\
" managerip: $MAINIP" > "$global_pillar"
+
+ if [[ $is_airgap ]]; then
+ printf '%s\n'\
+ " airgap: True"\ >> "$global_pillar"
+ else
+ printf '%s\n'\
+ " airgap: False"\ >> "$global_pillar"
+ fi
# Check if TheHive is enabled. If so, add creds and other details
if [[ "$THEHIVE" == "1" ]]; then
@@ -1860,8 +1873,10 @@ set_redirect() {
set_updates() {
if [ "$MANAGERUPDATES" = '1' ]; then
if [ "$OS" = 'centos' ]; then
- if ! grep -q "$MSRV" /etc/yum.conf; then
- echo "proxy=http://$MSRV:3142" >> /etc/yum.conf
+ if [[ ! $is_airgap ]]; then
+ if ! grep -q "$MSRV" /etc/yum.conf; then
+ echo "proxy=http://$MSRV:3142" >> /etc/yum.conf
+ fi
fi
else
# Set it up so the updates roll through the manager
diff --git a/setup/so-setup b/setup/so-setup
index 30bc10479..f771d7d57 100755
--- a/setup/so-setup
+++ b/setup/so-setup
@@ -193,16 +193,16 @@ if [[ "$setup_type" == 'iso' ]]; then
is_iso=true
fi
-#Check if this is an airgap install
+# Check if this is an airgap install
-#if [[ $is_manager ]]; then
-# if [[ $is_iso ]]; then
-# whiptail_airgap
-# if [[ "$INTERWEBS" == 'AIRGAP' ]]; then
-# is_airgap=true
-# fi
-# fi
-#fi
+if [[ $is_manager ]]; then
+ if [[ $is_iso ]]; then
+ whiptail_airgap
+ if [[ "$INTERWEBS" == 'AIRGAP' ]]; then
+ is_airgap=true
+ fi
+ fi
+fi
if [[ $is_manager && $is_sensor ]]; then
check_requirements "standalone"
@@ -411,6 +411,8 @@ if [[ $is_manager || $is_import ]]; then whiptail_so_allow; fi
whiptail_make_changes
+# From here on changes will be made.
+
if [[ -n "$TURBO" ]]; then
use_turbo_proxy
fi
@@ -460,6 +462,11 @@ fi
# Set initial percentage to 0
export percentage=0
+ if [[ $is_manager && $is_airgap ]]; then
+ info "Creating airgap repo"
+ create_repo >> $setup_log 2>&1
+ fi
+
if [[ $is_minion ]]; then
set_progress_str 1 'Configuring firewall'
set_initial_firewall_policy >> $setup_log 2>&1
diff --git a/setup/so-whiptail b/setup/so-whiptail
index e590a30d9..2996969fa 100755
--- a/setup/so-whiptail
+++ b/setup/so-whiptail
@@ -97,8 +97,8 @@ whiptail_zeek_version() {
[ -n "$TESTING" ] && return
- ZEEKVERSION=$(whiptail --title "Security Onion Setup" --radiolist "What tool would you like to use to generate meta data?" 20 75 4 "ZEEK" "Install Zeek (aka Bro)" ON \
- "SURICATA" "Use Suricata 5" OFF 3>&1 1>&2 2>&3)
+ ZEEKVERSION=$(whiptail --title "Security Onion Setup" --radiolist "What tool would you like to use to generate metadata?" 20 75 4 "ZEEK" "Zeek (formerly known as Bro)" ON \
+ "SURICATA" "Suricata" OFF 3>&1 1>&2 2>&3)
local exitstatus=$?
whiptail_check_exitstatus $exitstatus
@@ -412,6 +412,13 @@ whiptail_enable_components() {
[ -n "$TESTING" ] && return
+ GRAFANA=0
+ OSQUERY=0
+ WAZUH=0
+ THEHIVE=0
+ PLAYBOOK=0
+ STRELKA=0
+
COMPONENTS=$(whiptail --title "Security Onion Setup" --checklist \
"Select Components to install" 20 75 8 \
GRAFANA "Enable Grafana for system monitoring" ON \
@@ -621,9 +628,8 @@ whiptail_nids() {
[ -n "$TESTING" ] && return
NIDS=$(whiptail --title "Security Onion Setup" --radiolist \
- "Choose which IDS to run. \n
- Snort 3.0 support will be added once it is out of beta:" 25 75 4 \
- "Suricata" "Suricata 4.X" ON \
+ "Choose which IDS to run. \n\n(Snort 3.0 support will be added once it is out of beta.)" 25 75 4 \
+ "Suricata" "Suricata" ON \
"Snort" "Placeholder for Snort 3.0 " OFF 3>&1 1>&2 2>&3 )
local exitstatus=$?