Bug 1174405
Summary: | sshd can bind to ephemeral ports | ||
---|---|---|---|
Product: | Red Hat Enterprise Linux 7 | Reporter: | John T. Rose <inode0> |
Component: | selinux-policy | Assignee: | Miroslav Grepl <mgrepl> |
Status: | CLOSED NOTABUG | QA Contact: | Milos Malik <mmalik> |
Severity: | medium | Docs Contact: | |
Priority: | high | ||
Version: | 7.0 | CC: | devin, dwalsh, eparis, lvrabec, mgrepl, mmalik, plautrba, pmoore, pvrabec, ssekidde, theophanis_kontogiannis |
Target Milestone: | rc | Keywords: | Reopened |
Target Release: | 7.1 | ||
Hardware: | All | ||
OS: | Linux | ||
Whiteboard: | |||
Fixed In Version: | Doc Type: | Bug Fix | |
Doc Text: | Story Points: | --- | |
Clone Of: | Environment: | ||
Last Closed: | 2015-01-08 14:28:05 UTC | Type: | Bug |
Regression: | --- | Mount Type: | --- |
Documentation: | --- | CRM: | |
Verified Versions: | Category: | --- | |
oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
Cloudforms Team: | --- | Target Upstream Version: | |
Embargoed: | |||
Bug Depends On: | |||
Bug Blocks: | 717785 |
Description
John T. Rose
2014-12-15 19:28:52 UTC
I noticed on RHEL7 that sshd can bind to ephemeral ports and it doesn't appear that it should be allowed to with nis_enabled being off. # sepolicy network -a /usr/sbin/sshd ... sshd_t: tcp name_bind 22 (ssh_port_t) 5900-5983, 5985-5999 (vnc_port_t) 6000-6020 (xserver_port_t) 32768-61000 (ephemeral_port_t) -- Allowed False [ nis_enabled=0 ] all ports > 500 and < 1024 (rpc_port_type) -- Allowed False [ nis_enabled=0 ] all ports with out defined types (port_t) -- Allowed False [ nis_enabled=0 ] ... # sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux SELinux root directory: /etc/selinux Loaded policy name: targeted Current mode: enforcing Mode from config file: enforcing Policy MLS status: enabled Policy deny_unknown status: allowed Max kernel policy version: 28 Regardless of whether nis_enabled is on or off setting the port in /etc/ssh/sshd_config to anything in the ephemeral_port_t range and running systemctl start sshd results in sshd being permitted to bind to the ephemeral port. It appears this same behavior occurs on relatively recent versions of Fedora as well as RHEL6. This is correct if you use NIS. Hi Miroslav, I don't use NIS and sshd happily binds to ephemeral ports. I'm pretty confident this is a bug, perhaps a kernel bug rather than an selinux policy bug. Since the policy isn't being enforced I guessed this was the proper component to open this against. I modified the /etc/ssh/sshd_config file (Port 50022) and the daemon is really able to run and bind to that port. The nis_enabled boolean is off. # seinfo --portcon=50022 portcon tcp 32768-61000 system_u:object_r:ephemeral_port_t:s0 portcon udp 32768-61000 system_u:object_r:ephemeral_port_t:s0 # sesearch -s sshd_t -t ephemeral_port_t -c tcp_socket -p name_bind -A -C Found 2 semantic av rules: DT allow sshd_t ephemeral_port_t : tcp_socket { name_bind name_connect } ; [ nis_enabled ] DT allow nsswitch_domain ephemeral_port_t : tcp_socket { name_bind name_connect } ; [ nis_enabled ] # I can reproduce the problem with nrpe too (original port: 5666, new port: 56666). It seems that kernel does not enforce selinux-policy on ports > 32767. For example sshd cannot name_bind to port 32767 (unreserved_port_t) but it can name_bind to port 32768 (ephemeral_port_t). There are no AVCs even if following policy module was enabled: # cat mypolicy.te policy_module(mypolicy,1.0) require { attribute domain; type ephemeral_port_t; class tcp_socket { name_bind }; } auditallow domain ephemeral_port_t : tcp_socket { name_bind }; # # seinfo --portcon=32767 portcon tcp 1024-32767 system_u:object_r:unreserved_port_t:s0 portcon udp 1024-32767 system_u:object_r:unreserved_port_t:s0 # seinfo --portcon=32768 portcon tcp 32768-61000 system_u:object_r:ephemeral_port_t:s0 portcon udp 32768-61000 system_u:object_r:ephemeral_port_t:s0 # Good catch, John. There is something which respects the ephemeral_port_t definition, because my experiments show that sshd can name_bind to 32767 < port < 61001. Yes, it relates with /proc/sys/net/ipv4/ip_local_port_range When attempting to bind() a socket to a port, the kernel only enforces SELinux access controls when the port number is: #1 In the "reserved" range, 0 through 1024 -or- #2 Not in the "local port" range as defined by /proc/{...}/ip_local_port_range (see comment #9) You could rerun the experiment with sshd bound to a port beyond the top of the local port range and I expect that you will see an AVC denial (assuming the sshd_t domain policy blocks it of course). I appreciate the time you have given to this but I'm still not understanding why this isn't viewed as a bug that needs to be addressed in some fashion. How can it really be the intent to allow binding to all ports in the range 32768-61000? Why bother restricting port binding at all if that is the case? When I ask selinux to show me the policy governing which ports a service can bind to it should not fail to mention the tens of thousands of ports in this range and it should not tell me incorrectly what the effect of setting a boolean variable is. Something still feels very wrong about this being left as it is now to me. Thanks. I dislike the behavior too. Default value in /proc/sys/net/ipv4/ip_local_port_range prevents SELinux subsystem from enforcing the policy on almost half of ports. It also conflicts with the basic SELinux idea that by default everything is denied except for the accesses which are explicitly allowed. Based on my experiments, auditallow rules do not catch the fact that a process binds to an ephemeral port and neverallow rules do not prevent a process from binding to an ephemeral port. This problem should be at least documented and sesearch should show that { name_bind } to tcp_socket:ephemeral_port_t is allowed for all domains. I'm worried that there might be other kinds of access which are allowed even if SELinux policy says otherwise. FWIW, the behavior described in comment #10 has been in place for a quite a while. Granted, this may not make it "right", but it does mean that we can't change the behavior without some discussion and likely some compatibility toggles so we don't break existing systems/policies. If you are concerned about this behavior I would suggest bringing it up on the SELinux developers mail list (not the Fedora SELinux list, but rather the NSA list). |