Tools Discussed in this Chapter


squid: http://www.squid-cache.org/

From the squid website

squid is

  • a full-featured web proxy cache

  • designed to run on Unix systems

  • free, open source software

  • the result of many contributions by unpaid (and paid) volunteers

squid supports

  • proxying and caching of HTTP, FTP, and other URLs

  • proxying for SSL

  • cache hierarchies

  • ICP, HTCP, CARP, Cache Digests

  • transparent caching

  • WCCP (Squid v2.3 and above)

  • extensive access controls

  • HTTP server acceleration

  • SNMP

  • caching of DNS lookups

Inbound: Running a Local Web Server (Basic Rules)

In this, the most basic host-based firewall configuration, the system Host-A is running a web server. The only services you want to allow to this system are HTTP (TCP Port 80), HTTPS (TCP Port 443), and potentially SSH (TCP Port 22).

The first example ruleset shows how to configure your firewall rules with a very strict default policy:

 # where $DNSSERVER is the IP address of your DNS server $IPTABLES -P INPUT DROP $IPTABLES -P OUTPUT DROP $IPTABLES -P FORWARD DROP $IPTABLES -A OUTPUT -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A INPUT -p tcp --dport 22 -j ACCEPT $IPTABLES -A INPUT -p tcp --dport 80 -j ACCEPT $IPTABLES -A INPUT -p tcp --dport 443 -j ACCEPT # this rule allows the server to perform DNS lookups $IPTABLES -A INPUT -A INPUT -p udp -m udp \       -s $DNSSERVER --sport 53 -d 0/0 -j ACCEPT 

This next example is right from the Redhat firewall rule generator; it demonstrates a completely different method with the same effect:

 # where $DNSSERVER is the IP address of your DNS server. $IPTABLES -N RH-Lokkit-0-50-INPUT $IPTABLES -A INPUT -j RH-Lokkit-0-50-INPUT $IPTABLES -A FORWARD -j RH-Lokkit-0-50-INPUT $IPTABLES -A RH-Lokkit-0-50-INPUT -p tcp -m tcp \       --dport 22 --syn -j ACCEPT $IPTABLES -A RH-Lokkit-0-50-INPUT -p tcp -m tcp \       --dport 80 --syn -j ACCEPT $IPTABLES -A RH-Lokkit-0-50-INPUT -p tcp -m tcp \       --dport 443 --syn -j ACCEPT $IPTABLES -A RH-Lokkit-0-50-INPUT -i lo -j ACCEPT $IPTABLES -A RH-Lokkit-0-50-INPUT -p udp -m udp \       -s $DNSSERVER --sport 53 -d 0/0 -j ACCEPT $IPTABLES -A RH-Lokkit-0-50-INPUT -p tcp -m tcp \       --syn -j REJECT $IPTABLES -A RH-Lokkit-0-50-INPUT -p udp -m udp \    -j REJECT 

Inbound: Filter: Incoming Web to Specific Hosts

This next ruleset shows how to perform the same as the previous set but limiting the hosts that can connect to the web server. In our example, the web server Host-A is using host-based firewall rules to restrict the clients that can connect to it. The following networks are allowed to connect 10.10.10.0/24 and 192.168.1.0/24 to 80 and 443 only. SSH connections are only allowed from the host 172.16.32.32

Our first example is a very short, basic method:

 # where $DNSSERVER is our DNS server. $IPTABLES -P INPUT DROP $IPTABLES -A INPUT -s 10.10.10.0/24 -p tcp \       --dport 80 -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.0/24 -p tcp \       --dport 80 -j ACCEPT $IPTABLES -A INPUT -s 10.10.10.0/24 -p tcp \       --dport 443 -j ACCEPT $IPTABLES -A INPUT -s 192.168.1.0/24 -p tcp \       --dport 443 -j ACCEPT $IPTABLES -A INPUT -s 172.16.32.32 -p tcp \       --dport 22 -j ACCEPT $IPTABLES -A INPUT -A INPUT -p udp -m udp \       -s $DNSSERVER --sport 53 -d 0/0 -j ACCEPT 

This second example achieves the same effect with a bit more flexibility and overall network friendliness given that the REJECT will return an RST/ACK. The previous rule uses a DROP, which just tosses the packets to the side:

 # where $DNSSERVER is the IP address of your DNS # server. $IPTABLES -N WEBCLIENTS $IPTABLES -A INPUT -N WEBCLIENTS $IPTABLES -A FORWARD -j WEBCLIENTS $IPTABLES -A WEBCLIENTS -p tcp -m tcp --dport 80 \       -s 10.10.10.0/24 --syn -j ACCEPT $IPTABLES -A WEBCLIENTS -p tcp -m tcp --dport 80 \       -s 192.168.1.0/24 --syn -j ACCEPT $IPTABLES -A WEBCLIENTS -p tcp -m tcp --dport 443 \       -s 10.10.10.0/24 --syn -j ACCEPT $IPTABLES -A WEBCLIENTS -p tcp -m tcp --dport 443 \       -s 192.168.1.0/24 --syn -j ACCEPT $IPTABLES -A WEBCLIENTS -p tcp -m tcp --dport 22 \       -s 172.16.32.32 --syn -j ACCEPT $IPTABLES -A WEBCLIENTS -j ACCEPT $IPTABLES -A WEBCLIENTS-p udp -m udp -s $DNSSERVER \       --sport 53 -d 0/0 -j ACCEPT $IPTABLES -A WEBCLIENTS -p tcp -m tcp --syn -j REJECT $IPTABLES -A WEBCLIENTS -p udp -m udp -j REJECT 

Forward: Redirect Local Port 80 to Local Port 8080

In this scenario, our web server Host-A is not running on the standard HTTP port (TCP 80), so we will need to use a host-based firewall rule to forward queries to the port on which we're running the web server. In this case, Host-A is running a web server on port 8080.

This first example assumes that you have a restrictive policy, so our first rules are to allow connections to port 80 and 8080:

 # Where $EXTERNALIP is the external IP Address on this # server $IPTABLES -A INPUT -p tcp --dport 80 -j ACCEPT $IPTABLES -A INPUT -p tcp --dport 8080 -j ACCEPT $IPTABLES -t nat -A PREROUTING -p tcp dport 80 \       -j REDIRECT to-ports 8080 # This final rule ensures that port 80 connections that # originate locally are redirected $IPTABLES -A OUTPUT -t nat -p tcp -d $EXTERNALIP \       --dport 80 -j REDIRECT --to 8080 

Note that this final rule is applied to OUTPUT; this is because it's referring to traffic originating on the system itself.

Forwarding Connections from the Firewall to an Internal Web Server

This configuration assumes that you have a front-end firewall (Host-A) and a web server (Host-B, 192.168.1.80) on a DMZ segment (192.168.1.0/24). Connections to Host-A on ports 80 and 443 (HTTP and HTTPS, respectively) will be forwarded to the web server Host-B on the DMZ segment. Figure 15.1 describes the design.

Figure 15.1. Demonstrating DNAT-ing HTTP and HTTPS traffic to a DMZ web server.


This first configuration demonstrates the rules in Figure 15.1:

 # where eth0 is the external interface (Internet) # where eth1 is the internal interface (10.10.10.0/24) # where eth2 is the DMZ interface (192.168.1.0/24) EXTERNAL=eth0 INTERNAL=eth1 DMZ=eth2 SERVER=192.168.1.80 # HTTP traffic, TCP port 80 $IPTABLES -A FORWARD -i $EXTERNAL -o $DMZ -p tcp \       --dport 80 -m state state \       NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       --dport 80 -j DNAT --to-destination $SERVER # HTTPS traffic, TCP port 443 $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       --dport 443 -j DNAT --to-destination $SERVER $IPTABLES -A FORWARD -i $EXTERNAL -o $DMZ -p tcp \       --dport 443 -m state state\       NEW,ESTABLISHED,RELATED -j ACCEPT 

Forward: To Multiple Internal Servers

This next example demonstrates the previous configuration, but with multiple web servers. The firewall, Host-A in this case, has multiple Internet IPs on its external interface, 11.22.33.44 and 11.22.33.45. These IP addresses are assigned to two separate internal web serversHost-B (192.168.1.80) receives web traffic destined to 11.22.33.44, and Host-C (192.168.1.81) receives web traffic destined to 11.22.33.45.

 # where eth0 is the external interface (Internet) # where eth1 is the internal interface (10.10.10.0/24) # where eth2 is the DMZ interface (192.168.1.0/24) # where $EXTERNALIP is the external IP on your firewall EXTERNAL=eth0 INTERNAL=eth1 DMZ=eth2 EXT_HOSTB=11.22.33.44 EXT_HOSTC=11.22.33.45 HOSTB=192.168.1.80 HOSTC=192.168.1.81 # HTTP traffic, TCP port 80 to HOSTB $IPTABLES -A FORWARD -i $EXTERNAL -o $DMZ -p tcp \       -d $EXT_HOSTB --dport 80 -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       -d $EXT_HOSTB --dport 80 -j DNAT \       --to-destination $HOSTB # HTTP traffic, TCP port 80 to HOSTC $IPTABLES -A FORWARD -i $EXTERNAL -o $DMZ -p tcp \       -d $EXT_HOSTC --dport 80 -m  state \ 

Figure 15.2. Multiple web servers on multiple DNAT-ed IP addresses.


       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       -d $EXT_HOSTC --dport 80 -j DNAT \       --to-destination $HOSTC # HTTPS traffic, TCP port 80 to HOSTC $IPTABLES -A FORWARD -i $EXTERNAL -o $DMZ -p tcp \       -d $EXT_HOSTC --dport 443 -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       -d $EXT_HOSTC --dport 443 -j DNAT \       --to-destination $HOSTC 

Forward: To a Remote Server on the Internet

This particular scenario we see all the time when dealing with systems in the hosting space. It's a fairly migratory business with servers moving frequently between the large hosting providers or between IP space. The idea is to move your content and services to the new system and set up firewall rules on the old system to DNAT traffic from the old server to the new server. This is typically until all the content and users have been moved to the new server and all the DNS and registrar records have been changed to point to the new server. These rules work almost the same as a regular FORWARD rule. The main difference is that our new server is only going to communicate back through the old server when it sends traffic its way. Otherwise, it communicates as its normal IP address, through its normal network, and with no NAT-ing.

In this example, we have two hosts, Host-A (11.22.33.44), which is our old server, and Host-B (22.33.44.55), our new system. We add the following rules to Host-A:

 #!/bin/sh IPTABLES="/sbin/iptables" EXTERNAL=eth0 OLDSERVER=11.22.33.44 NEWSERVER=22.33.44.55 # Enable connection tracking $IPTABLES -A INPUT -m state \       --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -i $EXTERNAL -o $EXTERNAL \       -p tcp --dport 80 -d $OLDSERVER -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -t nat -A PREROUTING -i $EXTERNAL -p tcp \       --dport 80 -d $OLDSERVER -j DNAT \       --to-destination $NEWSERVER $IPTABLES -t nat -A POSTROUTING -p tcp -dport 80 -d $NEWSERVER \                  -j SNAT --to $OLDSERVER # Enable IP Forwarding in the kernel echo 1 > /proc/sys/net/ipv4/ip_forward 

Figure 15.3. DNAT being used to forward web traffic in a hosting environment.


The following script is a functional working example of the previous script, but one that forwards all traffic on the IP address to the remote server. This uses an external file called forwarded to list the source and destination IPs in this format: SOURCE-IP:DESTINATION-IP (i.e., 11.22.33.44:22.33.44.55).

 #!/bin/sh IPTABLES="/sbin/iptables" CONFIG=/etc/rc.d/forwarded EXTERNAL=eth0 # Enable connection tracking $IPTABLES -A INPUT -m state \       --state ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A OUTPUT -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT for i in `cat $CONFIG`; do   SOURCEIP=`echo $i | awk -F: '{print $1}'`   DESTIP=`echo $i | awk -F: '{print $2}'`   echo "Forwarding $SOURCEIP to $DESTIP"   $IPTABLES -A FORWARD -i $EXTERNAL -o $EXTERNAL \         -d $SOURCEIP -m state state \          NEW,ESTABLISHED,RELATED -j ACCEPT   $IPTABLES -t nat -A PREROUTING -i $EXTERNAL \         -d $SOURCEIP -j DNAT --to-destination $DESTIP   $IPTABLES -t nat -A POSTROUTING -d $DESTIP \         -j SNAT --to $SOURCEIP done # Enable IP Forwarding in the kernel echo "1" > /proc/sys/net/ipv4/ip_forward 

In a hosting environment, it's very common to have multiple and sometimes hundreds of IPs on one interface. This method makes it possible to mitigate the outage time generally experienced while moving large numbers of virtual hosts between servers.

Forward: Filtering Access to a Forwarded Server

This next ruleset shows how to limit the hosts that can connect to the forwarded web server. In this example, our firewall, Host-A, forwards connections to the internal server Host-B (192.168.1.80). The following network is allowed to connect, 22.33.44.0/24 (Internet) to TCP ports 80 and 443.

This first configuration demonstrates the rules needed to achieve this type of configuration using DNAT rules:

 # where eth0 is the external interface (Internet) # where eth1 is the internal interface (10.10.10.0/24) # where eth2 is the DMZ interface (192.168.1.0/24) # where $EXTERNALIP is the external IP on your firewall # where 192.168.1.1 is the internal IP address on the # firewalls eth2 interface $IPTABLES -A FORWARD -i eth0 -o eth2 -p tcp \       -s 22.33.44.0/24 --dport 80 -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPTABLES -A FORWARD -i eth0 -o eth2 -p tcp \       -s 22.33.44.0/24 --dport 443 -m state \       --state NEW,ESTABLISHED,RELATED -j ACCEPT # For our internet users from 22.33.44.0/24 $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp \       -s 22.33.44.0/24 --dport 80 -d $EXTERNALIP \       -j DNAT --to-destination 192.168.1.80:80 $IPTABLES -t nat -A PREROUTING -i eth0 -p tcp \       -s 22.33.44.0/24 --dport 443 -d $EXTERNALIP \       -j DNAT --to-destination 192.168.1.80:443 

Outbound: Some Websites are Inaccessible (ECN)

The symptoms of this problem are that in general, you can reach most websites with no performance or other issues; a small portion of websites, however, cannot be reached. This is a fairly common problem with the Explicit Congestion Notification (ECN) feature of the Linux kernel. If you have this compiled into your kernel and cannot connect to a small segment of non-Linux web servers, this is the most likely culprit. The fix is to disable ECN in your kernel.

To turn ECN off, as previously discussed in the book, you simply change the boolean value in

 /proc/sys/net/ipv4/tcp_ecn: echo 0 > /proc/sys/net/ipv4/tcp_ecn 

Outbound: Block Clients from Accessing Websites

In this scenario you are in a position where you need to filter out access to specific websites by internal network systems traversing your firewall. This example really belongs in the NAT section of this book; however, given that this might only be related to a single service (web), we will address how to achieve this goal. In the following example, the firewall Host-A handles traffic for the internal network 10.10.10.0/24. Hosts on this network are only allowed to communicate with the web server at 11.22.33.44:

 $IPTABLES -A PREROUTING -t nat -s 10.10.10.0/24 \       -d 11.22.33.44 dport 80 -j ACCEPT $IPTABLES -A PREROUTING -t nat -s 10.10.10.0/24 \       -d 0/0 -p tcp dport 80 -j REJECT \       reject-with icmp-net-prohibited 

The first rule allows the systems on the network 10.10.10.0/24 to access the web server at 11.22.33.44.

The second rule rejects traffic to any other web server, with the net-prohibited ICMP message. This is to aid in debugging and to cleanly reject the attempted connections to disallowed web servers.

Transparent Proxy Servers (squid) on Outbound Web Traffic

A transparent proxy server is a method of installing an application layer proxy server, such as squid (http://www.squid-cache.org), in such a way that the end users do not even know it is there by using REDIRECT rules on web traffic. This is useful because, amongst other things, traffic is cached on the proxy server, increasing performance and reducing bandwidth usage to oft-used websites.

In addition to the caching, using a transparent proxy server like squid in conjunction with an iptables/nefilter firewall brings other advantages. You can, for example, implement content filtering, ad-blocking, user authenticated web browsing, or provide much more detailed browsing statistics from one of the many squid log analyzers listed at: http://www.squid-cache.org/Scripts/.

In the following example, our firewall, Host-A (10.10.10.1), has an internal network, 10.10.10.0/24. This configuration demonstrates a transparent proxy rule to an instance of squid running on the local firewall:

 # where eth0 is the external (Internet) interface # where eth1 is the internal (10.10.10.0/24) interface $IPTABLES -A INPUT -p tcp --dport 3128 -i ! eth0 \       -j ACCEPT $IPTABLES -t nat -A PREROUTING -i eth1 -p tcp \       --dport 80 -j REDIRECT --to-port 3128 

The first rule allows port 3128 connections on all interfaces except for localhost.

The second rule dictates that all traffic passing through the firewall on port 80 will be REDIRECTED to port 3128 (squid) on the server.

This next rule demonstrates the same configuration as the previous listing with an additional external dedicated squid proxy server system, Host-B, with the IP address of 10.10.10.200:

 $IPTABLES -t nat -A PREROUTING -i eth1 \       -s ! 10.10.10.200 -p tcp --dport 80 -j DNAT \       --to 10.10.10.200:3128 $IPTABLES -t nat -A POSTROUTING -o eth1 \       -s 10.10.10.0/24 -d 10.10.10.200 -j SNAT \       --to 10.10.10.1 

The first rule redirects all www traffic on the internal network that is not from Host-B (10.10.10.200), to Host-B.

The second rule rewrites all traffic passing through the firewall with the destination of 10.10.10.200 to appear to come from 10.10.10.1. This is so our redirected squid traffic knows to come back to the firewall.

Sometimes it is necessary to exclude a host or a network from being cached by the transparent proxy server. Excluding an IP or network from transparent caching can be achieved with a user-defined chain. In the next example, our firewall Host-A runs a local squid-caching server for the network 10.10.10.0/24. The system's Host-B (10.10.10.200), and Host-C (10.10.10.201) will be excluded from caching:

 $IPTABLES -N SQUID $IPTABLES -A PREROUTING -t nat -p tcp --dport 80 \       -j SQUID $IPTABLES -A SQUID -t nat -s 10.10.10.200 -j RETURN $IPTABLES -A SQUID -t nat -s 10.10.10.201 -j RETURN $IPTABLES -A SQUID -t nat -j REDIRECT --to-port 3128 

The main difference here from the previous examples is that we use -j RETURN to match the hosts 10.10.10.200 and 10.10.10.201. This performs an exception when those IP addresses are matched against the rule and returns to the PREROUTING rule, passing the traffic from that host through the firewall without redirecting it to the squid port. All other traffic is not matched against those two exception rules, and will be processed by squid.

Note

The examples do not attempt to handle HTTPS traffic. This is because among other things, squid cannot really cache SSL encrypted traffic. But more importantly, using a transparent proxy with SSL traffic is a great example of a man-in-the-middle attack.




    Troubleshooting Linux Firewalls
    Troubleshooting Linux Firewalls
    ISBN: 321227239
    EAN: N/A
    Year: 2004
    Pages: 169

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net