Introduction

I’ve recently upgraded all of my servers from Ubuntu 14.04 to CentOS 7. I put the emphasis on upgraded, since Ubuntu comes with a lot of baggage and cost in terms of patching and maintenance. One of the benefits of CentOS is it’s stability and employment of SELinux, a really effective security module. Sometimes though, things break when SELinux is enabled with little indication as to why.

Some of my first steps in spinning up a new box includes both enabling SELinux and hardening SSH, right from the user-data scripts. These scripts get executed when the droplet/instance spins up, which reduces it’s insecure exposure to the world wide web. With hardening SSH, I usually change the default SSH service port from 22 to something unique, honeybot port 22, disable the root users’ login and password-based logins, and roll out Duo 2-Factor Authentication.

When you enable SELinux, there are a few extra steps you need to take to allow SSH to listen to a non-port 22 and for Duo’s PAM module to communicate outbound. Lets explore a few of these fixes.

Enable New SSH Port with SELinux

To change the default SSH port, you have to permit the new port to be permitted through SELinux:sudo semanage port -a -t ssh_port_t -p tcp 27922

Failure to do this will result in your SSH service failing like so:$ sudo service sshd status
Redirecting to /bin/systemctl status  sshd.service
● sshd.service - OpenSSH server daemon
  Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
  Active: activating (auto-restart) (Result: exit-code) since Wed 2016-02-24 17:20:10 UTC; 9s ago
    Docs: man:sshd(8)
          man:sshd_config(5)
 Process: 31653 ExecStart=/usr/sbin/sshd -D $OPTIONS (code=exited, status=255)
Main PID: 31653 (code=exited, status=255)Feb 24 17:20:10 hostname systemd[1]: sshd.service: main process exited, code=exited, status=255/n/a
Feb 24 17:20:10 hostname systemd[1]: Unit sshd.service entered failed state.
Feb 24 17:20:10 hostname systemd[1]: sshd.service failed.

Next steps of course would be to enable the port through the firewall (examples below):

Firewalldfirewall-cmd --permanent --zone=public --add-port=27922/tcp && \
 firewall-cmd --reload

IPTablesiptables -I INPUT 1 -m state --state NEW -m tcp -p tcp --dport 27922 -j ACCEPT

Enable Duo with SELinux

If you are not familiar with Duo as a 2FA authentication medium, you should check them out. If you’re worried there is a cost, don’t, they have free personal plans!

The following assumes you have already installed DuoUnix per their docs which can be found at https://duo.com/docs/duounix.

The Duo PAM module makes outbound HTTPS connections when its step in the chain is being evaluated. This is forbidden by default in SELinux, and must be explicitly enabled.

After you run ./configure, execute:sudo make -C pam_duo semodule semodule-enable

The output should look similar to this:$ sudo make -C pam_duo semodule semodule-enable
make: Entering directory `/home/youwish/duo_unix-1.9.18/pam_duo'
checkmodule -M -m -o authlogin_duo.mod authlogin_duo.te
checkmodule:  loading policy configuration from authlogin_duo.te
checkmodule:  policy configuration loaded
checkmodule:  writing binary representation (version 17) to authlogin_duo.mod
semodule_package -o authlogin_duo.pp -m authlogin_duo.mod
make: Leaving directory `/home/youwish/duo_unix-1.9.18/pam_duo'
make: Entering directory `/home/youwish/duo_unix-1.9.18/pam_duo'
semodule -i authlogin_duo.pp

Conclusion

Just taking a few extra minutes to harden your server can go a log way and make a big impact in your security posture. You don’t need to resort to the noob instinct of disabling SELinux, while supporting your secure configuration.

Share this post