Showing posts with label SELinux. Show all posts
Showing posts with label SELinux. Show all posts

Saturday, 18 January 2014

SELinux and Changing Ports

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.

So the task at hand: change the SSH listening port from 22 to 443 so I can safely browse the interwebs and circumvent those pesky proxies.  So to do so, I log in and edit /etc/ssh/sshd_config:

#       $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.