summaryrefslogtreecommitdiff
path: root/evergreen
diff options
context:
space:
mode:
authorsergey.galtsev <sergey.galtsev@mongodb.com>2021-09-28 22:43:09 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-09-28 23:11:18 +0000
commite5d32fc7b6811a659ac36f519bf697d776df4849 (patch)
tree6c2675bad0d3c64daf6c1dea26a738ea242b4921 /evergreen
parent9569a71e456821fe24030f59810f384d4a9b8b02 (diff)
downloadmongo-e5d32fc7b6811a659ac36f519bf697d776df4849.tar.gz
SERVER-56180 SELinux policy tests
Diffstat (limited to 'evergreen')
-rwxr-xr-xevergreen/selinux_run_test.sh78
-rwxr-xr-xevergreen/selinux_test_executor.sh102
-rwxr-xr-xevergreen/selinux_test_setup.sh44
3 files changed, 224 insertions, 0 deletions
diff --git a/evergreen/selinux_run_test.sh b/evergreen/selinux_run_test.sh
new file mode 100755
index 00000000000..318d73adbe2
--- /dev/null
+++ b/evergreen/selinux_run_test.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+# Notes on how to run this manually:
+# - repo must be unpacked into source tree
+#
+# export ssh_key=$HOME/.ssh/id_rsa
+# export hostname=ec2-3-91-230-150.compute-1.amazonaws.com
+# export user=ec2-user
+# export bypass_prelude=yes
+# export workdir="$(dirname $(pwd) | tee /dev/stderr)"
+# export src="$(basename $(pwd) | tee /dev/stderr)"
+# export test_list='jstests/selinux/*.js'
+# export pkg_variant=mongodb-enterprise
+# evergreen/selinux_run_test.sh
+
+set -o errexit
+
+DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)"
+if [ "$bypass_prelude" != "yes" ]; then
+ . "$DIR/prelude.sh"
+ activate_venv
+ src="src"
+fi
+
+set -o xtrace
+
+if [ "$hostname" == "" ]; then
+ hostname="$(tr -d '"[]{}' < "$workdir"/$src/hosts.yml | cut -d , -f 1 | awk -F : '{print $2}')"
+fi
+
+if [ "$user" == "" ]; then
+ user=$USER
+fi
+
+host="${user}@${hostname}"
+python="${python:-python3}"
+
+if [ "$ssh_key" == "" ]; then
+ ssh_key="$workdir/selinux.pem"
+ "$workdir"/$src/buildscripts/yaml_key_value.py --yamlFile="$workdir"/expansions.yml \
+ --yamlKey=__project_aws_ssh_key_value > "$ssh_key"
+ chmod 600 "$ssh_key"
+ result="$(openssl rsa -in "$ssh_key" -check -noout | tee /dev/stderr)"
+ if [ "$result" != "RSA key ok" ]; then
+ exit 1
+ fi
+fi
+
+attempts=0
+connection_attempts=50
+
+# Check for remote connectivity
+set +o errexit
+ssh_options="-i $ssh_key -o IdentitiesOnly=yes -o StrictHostKeyChecking=no"
+while ! ssh $ssh_options -o ConnectTimeout=10 "$host" echo "I am working"; do
+ if [ "$attempts" -ge "$connection_attempts" ]; then exit 1; fi
+ ((attempts++))
+ printf "SSH connection attempt %d/%d failed. Retrying...\n" "$attempts" "$connection_attempts"
+ sleep 10
+done
+
+set -o errexit
+echo "===> Copying sources to target..."
+rsync -ar -e "ssh $ssh_options" \
+ --exclude 'tmp' --exclude 'build' --exclude '.*' \
+ "$workdir"/$src/* "$host":
+
+echo "===> Configuring target machine..."
+ssh $ssh_options "$host" evergreen/selinux_test_setup.sh
+
+echo "===> Executing tests..."
+list="$(
+ cd src
+ for x in $test_list; do echo "$x"; done
+)"
+for test in $list; do
+ ssh $ssh_options "$host" evergreen/selinux_test_executor.sh "$test"
+done
diff --git a/evergreen/selinux_test_executor.sh b/evergreen/selinux_test_executor.sh
new file mode 100755
index 00000000000..1ba889a1c80
--- /dev/null
+++ b/evergreen/selinux_test_executor.sh
@@ -0,0 +1,102 @@
+#!/bin/bash
+
+set -o errexit
+set -o xtrace
+
+function print() {
+ echo "$@" >&2
+}
+
+function monitor_log() {
+ sed "s!^!mongod| $(date '+%F %H-%M-%S') !" <(sudo --non-interactive tail -f /var/log/mongodb/mongod.log)
+}
+
+TEST_PATH="$1"
+if [ ! -f "$TEST_PATH" ]; then
+ print "No test supplied or test file not found. Run:"
+ print " $(basename "${BASH_SOURCE[0]}") <path>"
+ exit 1
+fi
+
+# test file is even good before going on
+if ! mongo --nodb --norc --quiet "$TEST_PATH"; then
+ print "File $TEST_PATH has syntax errors"
+ exit 1
+fi
+
+# stop mongod, zero mongo log, clean up database, set all booleans to off
+sudo --non-interactive bash -c '
+ systemctl stop mongod
+
+ rm -f /var/log/mongodb/mongod.log
+ touch /var/log/mongodb/mongod.log
+ chown mongod /var/log/mongodb/mongod.log
+
+ rm -rf /var/lib/mongo/*
+
+ rm -rf /etc/sysconfig/mongod /etc/mongod
+
+ setsebool mongod_can_connect_snmp off
+ setsebool mongod_can_connect_ldap off
+ setsebool mongod_can_use_kerberos off
+'
+
+# create mongo config
+mongo --nodb --norc --quiet --eval='
+ assert(load("'"$TEST_PATH"'"));
+ const test = new TestDefinition();
+ print(typeof(test.config) === "string" ? test.config : JSON.stringify(test.config, null, 2));
+' | sudo --non-interactive tee /etc/mongod.conf
+
+# setup
+mongo --nodb --norc --quiet --eval='
+ assert(load("'"$TEST_PATH"'"));
+ const test = new TestDefinition();
+ jsTest.log("Running setup()");
+ test.setup();
+'
+
+# start log monitor, also kill it on exit
+monitor_log &
+MONITORPID="$!"
+trap "sudo --non-interactive pkill -P $MONITORPID" SIGINT SIGTERM ERR EXIT
+
+# start mongod and if it won't come up, log SELinux errors
+ts="$(date --utc --date='1 seconds ago' '+%x %H:%M:%S')"
+tsj="$(date --utc --date='1 seconds ago' +'%Y-%m-%d %H:%M:%S')"
+sudo --non-interactive systemctl start mongod \
+ && sudo --non-interactive systemctl status mongod || (
+ set +o errexit
+ echo "=== SELinux errors:"
+ sudo --non-interactive ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts $ts
+ echo "=== journalctl --unit=mongod:"
+ sudo --non-interactive journalctl --no-pager --since="$tsj" --unit=mongod --unit=systemd --catalog
+ echo "=== /var/log/mongodb/mongod.log:"
+ sudo --non-interactive cat /var/log/mongodb/mongod.log
+ echo "==== FAIL: mongod service was not started successfully"
+ exit 1
+)
+
+# run test and teardown
+mongo --norc --gssapiServiceName=mockservice --eval='
+ assert(load("'"$TEST_PATH"'"));
+ // name is such to prevent collisions
+ const test_812de7ce = new TestDefinition();
+ try {
+ jsTest.log("Running test");
+ test_812de7ce.run();
+ } finally {
+ test_812de7ce.teardown();
+ }
+' || (
+ echo "==== FAIL: test returned result: $?"
+ echo "=== SELinux errors:"
+ set +o errexit
+ sudo --non-interactive ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts $ts
+ echo "=== /var/log/mongodb/mongod.log:"
+ sudo --non-interactive cat /var/log/mongodb/mongod.log
+ exit 1
+)
+
+set +o xtrace
+echo "SUCCESS: $TEST_PATH"
diff --git a/evergreen/selinux_test_setup.sh b/evergreen/selinux_test_setup.sh
new file mode 100755
index 00000000000..ef2e70df2a9
--- /dev/null
+++ b/evergreen/selinux_test_setup.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# This script is loaded on the target machine, which is running tests
+# Purpose: install mongod and shell from packages
+
+set -o xtrace
+set -o errexit
+
+function apply_selinux_policy() {
+ echo "==== Applying SELinux policy now"
+ rm -rf mongodb-selinux
+ git clone https://github.com/mongodb/mongodb-selinux
+ cd mongodb-selinux
+ make
+ sudo make install
+}
+
+# on evergreen images /tmp is usually linked to /data/tmp, which interferes
+# with selinux, as it does not recognize it as tmp_t domain
+if [ -L /tmp ]; then
+ sudo --non-interactive rm /tmp
+ sudo --non-interactive mkdir /tmp
+ sudo --non-interactive systemctl start tmp.mount
+fi
+
+# selinux policy should work both when applied before and after install
+# we will randomly apply it before or after installation is completed
+SEORDER="$(($RANDOM % 2))"
+if [ "$SEORDER" == "0" ]; then
+ apply_selinux_policy
+fi
+
+# install shell using yum, so that dependencies are pulled
+pkg="$(find "$HOME"/repo -name 'mongodb-*-shell-*.x86_64.rpm' | tee /dev/stderr)"
+sudo --non-interactive yum install --assumeyes "$pkg" \
+ || if [ "$?" -gt "1" ]; then exit 1; fi # exit code 1 is OK
+
+pkg="$(find "$HOME"/repo -name 'mongodb-*-server-*.x86_64.rpm' | tee /dev/stderr)"
+sudo --non-interactive rpm --install --verbose --verbose --hash --nodeps "$pkg" \
+ || if [ "$?" -gt "1" ]; then exit 1; fi # exit code 1 is OK
+
+if [ "$SEORDER" == "1" ]; then
+ apply_selinux_policy
+fi