Restrict httpd network connections to a specific network interface?

Mark Montague mark at catseye.org
Sun Mar 27 18:31:17 UTC 2011


  On March 27, 2011 12:21 , Mark Montague <mark at catseye.org>  wrote:
> The requirements are:
>
> 1. Allow httpd to serve any requests on ports 80 and 443 from any
> network interface.
> 2. Allow httpd and its scripts (CGIs) to access any resource (databases,
> back-end content web servers, etc.) on the local machine via the
> loopback interface.
> 3. Prohibit any other traffic from httpd.  Specifically, do not allow
> any access by either httpd or its scripts to resources on remote
> (untrusted) machines.
> 4. Do not affect any other service or user running on the machine.
>
> I haven't been able to solve the problem by labeling interfaces, yet --
> requirement 1 keeps getting in my way.
>
> However, I was able to solve the problem by labeling packets.

I was also able to solve the problem another way, using a netfilter 
module:  http://github.com/markmont/xt_selinux   This has the advantage 
of allowing more flexible action than just an AVC denial (for example, 
sending a TCP reset to get a script such as curl to immediately give up 
and exit).  But it is a horrible, hacky solution that brutalizes the 
SELinux LSM, is extremely fragile, and probably should not exist -- I'd 
like to apologize for that right now.  But I thought it would be a 
useful thing to present for the sake of academic discussion.

Here are the commands (no local policy is needed, if you don't count the 
boolean):

setsebool -P httpd_can_network_connect=on

# Allow loopback device traffic to/from all services or users:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Accept incoming web server traffic:
iptables -A INPUT -p tcp -m multiport --dports 80,443 \
     -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Silently block all other incoming traffic:
iptables -A INPUT -j DROP

# httpd is already allowed (by the rules above) to send any traffic
# via the loopback device in order to access various local resources.
# Also allow httpd to respond to incoming web server traffic (for
# which we've already accepted the input, above).  Prohibit httpd
# from sending any other outbound traffic.
iptables -N HTTPD_OUT
iptables -A OUTPUT -m selinux --task-ctx system_u:system_r:httpd_t:s0 \
     -j HTTPD_OUT
iptables -A HTTPD_OUT -m conntrack --ctstate RELATED,ESTABLISHED \
     -j ACCEPT
iptables -A HTTPD_OUT -j REJECT

# Web server scripts (CGIs) are already allowed (by a rule above) to
# send any traffic through the loopback device in order to access
# various local resources.  But prohibit scripts from accessing
# anything else (such as remote machines).
iptables -A OUTPUT \
     -m selinux --task-ctx system_u:system_r:httpd_sys_script_t:s0 \
     -j REJECT

# Permit all other services and users on the machine to send outbound
# traffic without restriction:
iptables -A OUTPUT -j ACCEPT


For the record, I'm not using the above solution myself: I'm using the 
SECMARK-based solution that I described in my previous message:  
http://lists.fedoraproject.org/pipermail/selinux/2011-March/013612.html

The xt_owner netfilter module used to support iptables matching against 
security contexts back in 2.6.13.  I'm assuming that there is no 
interest in devising the "right way" to restore this functionality long 
term, since this would allow "policy" in multiple places.  But if I'm 
wrong, please let me know -- I'd be happy to take a shot at proposing 
and writing new LSM hooks to properly support netfilter-based security 
context matching that worked with all applicable LSMs.

--
   Mark Montague
   mark at catseye.org



More information about the selinux mailing list