As with many little Linux projects, what was intended to be a 2 minute activity turned into a 20 minute activity, this time in thanks to our friend SELinux.
In the past, I've always just disabled SELinux- what's the need, after all, as I'm usually just setting up projects out of my home lab and SELinux seems like a bit of overkill. What's more, even in the Red Hat Certified System Admin course, they have you turn it off, as managing SELinux is more of a RHCE task.
Well, as it so happens, I'm currently studying for my RHCE and figured now is as good a time as any to get some practice in, if only inadvertently.
# $OpenBSD: sshd_config,v 1.80 2008/07/02 02:24:18 djm Exp $
# This is the sshd server system-wide configuration file. See
# sshd_config(5) for more information.
# This sshd was compiled with PATH=/usr/local/bin:/bin:/usr/bin
# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented. Uncommented options change a
# default value.
#Port 22
Port 443
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::
I add a rule in iptables to allow 443:
[username@localhost ~]$ sudo iptables -I INPUT 4 -p tcp --dport https -j ACCEPT
Then I restart sshd:
[username@localhost ~]$ sudo service sshd restart
and attempt to SSH via 443 from my laptop:
[username@laptop ~]$ ssh usernam@centos01 -p 443
ssh: connect to host centos01 port 443: Connection refused
... WTF? I try telnet:
[username@localhost ~]$ telnet centos01 443
Trying 10.21.4.10...
telnet: connect to address 10.21.4.10: Connection refused telnet: Unable to connect to remote host
Ah, so we're either blocking or not listening on 443. Let's try locally on the box:
[username@centos01 ~]$ ssh username@localhost -p 443
ssh: connect to host localhost port 443: Connection refused
So we're not listening. Weird. Perhaps this has something to do with SELinux:
[username@localhost ~]$ cat /selinux/enforced
1
Yep, we're enabled. So I temporarily disable SELinux:
[username@localhost ~]$ sudo echo 0> /selinux/enforce
And let's try that again:
[username@localhost ~]$ ssh username@localhost -p 443
[username@localhost ~]$ The authenticity of host 'centos01 (10.5.10.10)' can't be established.
RSA key fingerprint is 94:21:69:84:1a:87:a7:94:98:64:95:f5:9e:ab:97:c4.
Are you sure you want to continue connecting (yes/no)?
Hooraw! Sure enough, it looks like SELinux is gumming up the works. So how do we allow SSH to listen on port 443? Well a bit of Googling tells us we need a tool called semanage, but it's not installed. Right then:
[username@localhost ~]$ sudo yum provides /usr/sbin/semanage
Loaded plugins: rhnplugin
policycoreutils-python-2.0.83-19.8.el6_0.x86_64 : SELinux policy core python utilities
Repo : rhel-x86_64-server-6
Matched from:
Filename : /usr/sbin/semanage
policycoreutils-python-2.0.83-19.1.el6.x86_64 : SELinux policy core python utilities
Repo : rhel-x86_64-server-6
Matched from:
Filename : /usr/sbin/semanage
[username@localhost ~]$ sudo yum install policycoreutils-python
Alright, so we have semanage installed, no it's time to append port 443 to the ssh_port_t:
[username@localhost ~]$ sudo semanage port -l | grep ssh
[username@localhost ~]$ ssh_port_t tcp 22
[username@localhost ~]$ sudo semanage port -a -t ssh_port_t -p tcp 443
[username@localhost ~]$ /usr/sbin/semanage: Port tcp/443 already defined
Balls. Okay, so apparently you can only define a TCP port in one SELinux policy. Makes sense. Where is 443 defined?
[username@localhost ~]$ sudo semanage port -l | grep 443
[username@localhost ~]$ http_port_t tcp 80, 443, 488, 8008, 8009, 8443
Ah, of course. It's defined for HTTP. Now then, let's just remove it from HTTP and add it to SSH:
[username@localhost ~]$ sudo semanage port -d -t http_port_t -p tcp 443
[username@localhost ~]$ /usr/sbin/semanage: Port tcp/443 is defined in policy, cannot be deleted
Double balls. Alright, so we apparently have to modify the port to be included in ssh_port_t:
[username@localhost ~]$ sudo semanage port -m -t ssh_port_t -p tcp 443
[username@localhost ~]$ sudo semanage port -l | grep 443
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pki_ca_port_t tcp 829, 9180, 9701, 9443-9447
pki_kra_port_t tcp 10180, 10701, 10443-10446
pki_ocsp_port_t tcp 11180, 11701, 11443-11446
pki_tks_port_t tcp 13180, 13701, 13443-13446
ssh_port_t tcp 443, 1255, 22
Sweet! Done and done. Now we can re-enable SELinux enforcement and ssh to our host! Hat tip to m4ccum4ccu for his
helpful blog post which I've borrowed from heavily for this one.