Skip to content

Commit 73bd78f

Browse files
KusabiSenseimichaelwittig
authored andcommitted
Support for systemd, SELinux, and SUSE (widdix#99)
* Support Multiple init daemons and service programs (#1) * Add test to determine init system for sshd restart In the install file, I've added a simple test to determine what init system is currently on the system, and to select the correct restart command for sshd that is required. This is tested on the following OSes in EC2: * Amazon Linux 2017.09 (using upstart) * Ubuntu 16.04.3 LTS (using systemd) * SUSE Enterprise Server 12 SP3 (using systemd) * RHEL 7.3 (using systemd) * Hush the stderr message when systemd doesn't exist This is to ensure that the output for a user is the same as it is when using the standard codebase. Message is successfully suppressed on Amazon Linux 2017.09 * Add useradd(1) arg to force user group creation By default on most distros, `USERGROUPS_ENAB` is set to `yes` which causes `useradd(1)` to create a group for a user that is added. There is an implicit dependency on line 179 of the `import_users.sh` script. I've altered the `useradd(1)` argument set to include `-U/--user-group` to force this on systems where `USERGROUPS_ENAB` is set to `no` This is needed to support SUSE Linux Enterprise Server on EC2. * Add check to not spam the sshd_config file The `install.sh` script currently checks if there is a line that reads `AuthorizedKeysCommand none` and then changes it. Old behaviour was to simply append the line on the end of the file is this line didn't exist. There is now a check to see if the correct line that we want already exists, so we don't spam the end of the configuration file. * Add SELinux support to install script If we have the `getenforce` command available to us, and we find that it returns the value `Enforcing` (meaning SELinux will block our access to AWS when called by `sshd`), we enable the `nis_enabled` boolean persistently in SELinux to inform SELinux that it should expect outbound access from sshd and other login programs (like PAM) to remote servers to get user account information. This allows `sshd` to call the script to get the user's public key from IAM. I also cleaned up the `systemd` conditional in the script to use the simpler way to check if commands exist. * Revert the supposedly clever way of command checks Chaining the command check with the return value failed miserably. Reverting this to be normal again. * Allow which(1) to exit and the script to continue We use `which(1)` to determine if a command is available to us. According to the man page, `which(1)` will return a return code `1` if the command is not found. Since the script is run with `-e` as an option in the shebang, this causes the script to exit prematurely. I've wrapped the `which(1)` calls in `set +e/set -e` wrappers so that the script continues gracefully. * Adjust which(1) pipelines to return valid exit codes On systems where `which(1)` doesn't find a given command, it will return exit code `1`. This will cause the script to abort under the `-e` option in the shebang. I've changed the pipeline to capture the return value of which on the other side of a logical OR, which does work correctly, and thus the pipeline gets a 0 return code (making `-e` happy), and I get the return value which tells me whether or not the command exists. Which makes me happy. * Adjust which(1) blocks to account for shortcircuit eval I forgot about shortcircuit evaluation. So I've added the success code in the variable before calling `which(1)`. This means that if the command is found, the 0 retval will get used in the test. The only time that it would change that to a non-zero status would be if something wasn't found. Like before, the whole command pipeline will return success, so `-e` stays happy as a clam.
1 parent 28a6cad commit 73bd78f

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

import_users.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ fi
4242
: ${USERADD_PROGRAM:="/usr/sbin/useradd"}
4343

4444
# Possibility to provide custom useradd arguments
45-
: ${USERADD_ARGS:="--create-home --shell /bin/bash"}
45+
: ${USERADD_ARGS:="--user-group --create-home --shell /bin/bash"}
4646

4747
# Initizalize INSTANCE variable
4848
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)

install.sh

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,17 @@ fi
124124
if grep -q '#AuthorizedKeysCommand none' $SSHD_CONFIG_FILE; then
125125
sed -i "s:#AuthorizedKeysCommand none:AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}:g" $SSHD_CONFIG_FILE
126126
else
127-
echo "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" >> $SSHD_CONFIG_FILE
127+
if ! grep -q "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" $SSHD_CONFIG_FILE; then
128+
echo "AuthorizedKeysCommand ${AUTHORIZED_KEYS_COMMAND_FILE}" >> $SSHD_CONFIG_FILE
129+
fi
128130
fi
129131

130132
if grep -q '#AuthorizedKeysCommandUser nobody' $SSHD_CONFIG_FILE; then
131133
sed -i "s:#AuthorizedKeysCommandUser nobody:AuthorizedKeysCommandUser nobody:g" $SSHD_CONFIG_FILE
132134
else
133-
echo "AuthorizedKeysCommandUser nobody" >> $SSHD_CONFIG_FILE
135+
if ! grep -q 'AuthorizedKeysCommandUser nobody' $SSHD_CONFIG_FILE; then
136+
echo "AuthorizedKeysCommandUser nobody" >> $SSHD_CONFIG_FILE
137+
fi
134138
fi
135139

136140
cat > /etc/cron.d/import_users << EOF
@@ -144,8 +148,53 @@ chmod 0644 /etc/cron.d/import_users
144148

145149
$IMPORT_USERS_SCRIPT_FILE
146150

147-
if [ -f "/etc/init.d/sshd" ]; then
148-
service sshd restart
151+
# In order to support SELinux in Enforcing mode, we need to tell SELinux that it
152+
# should have the nis_enabled boolean turned on (so it should expect login services
153+
# like PAM and sshd to make calls to get public keys from a remote server)
154+
#
155+
# This is observed on CentOS 7 and RHEL 7
156+
157+
# Capture the return code and use that to determine if we have the command available
158+
retval=0
159+
which getenforce > /dev/null 2>&1 || retval=$?
160+
161+
if [[ "$retval" -eq "0" ]]; then
162+
retval=0
163+
selinuxenabled || retval=$?
164+
if [[ "$retval" -eq "0" ]]; then
165+
setsebool -P nis_enabled on
166+
fi
167+
fi
168+
169+
170+
# Restart sshd using an appropriate method based on the currently running init daemon
171+
# Note that systemd can return "running" or "degraded" (If a systemd unit has failed)
172+
# This was observed on the RHEL 7.3 AMI, so it's added for completeness
173+
# systemd is also not standardized in the name of the ssh service, nor in the places
174+
# where the unit files are stored.
175+
176+
# Capture the return code and use that to determine if we have the command available
177+
retval=0
178+
which systemctl > /dev/null 2>&1 || retval=$?
179+
180+
if [[ "$retval" -eq "0" ]]; then
181+
if [[ (`systemctl is-system-running` =~ running) || (`systemctl is-system-running` =~ degraded) ]]; then
182+
if [ -f "/usr/lib/systemd/system/sshd.service" ] || [ -f "/lib/systemd/system/sshd.service" ]; then
183+
systemctl restart sshd.service
184+
else
185+
systemctl restart ssh.service
186+
fi
187+
fi
188+
elif [[ `/sbin/init --version` =~ upstart ]]; then
189+
if [ -f "/etc/init.d/sshd" ]; then
190+
service sshd restart
191+
else
192+
service ssh restart
193+
fi
149194
else
150-
service ssh restart
195+
if [ -f "/etc/init.d/sshd" ]; then
196+
/etc/init.d/sshd restart
197+
else
198+
/etc/init.d/ssh restart
199+
fi
151200
fi

0 commit comments

Comments
 (0)