<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd">
<article id="Shorewall_Squid_Usage">
  <!--$Id$-->

  <articleinfo>
    <title>Using Shorewall with Squid</title>

    <authorgroup>
      <author>
        <firstname>Tom</firstname>

        <surname>Eastep</surname>
      </author>
    </authorgroup>

    <pubdate><?dbtimestamp format="Y/m/d"?></pubdate>

    <copyright>
      <year>2003-2008</year>

      <holder>Thomas M. Eastep</holder>
    </copyright>

    <legalnotice>
      <para>Permission is granted to copy, distribute and/or modify this
      document under the terms of the GNU Free Documentation License, Version
      1.2 or any later version published by the Free Software Foundation; with
      no Invariant Sections, with no Front-Cover, and with no Back-Cover
      Texts. A copy of the license is included in the section entitled <quote>
      <ulink url="GnuCopyright.htm">GNU Free Documentation License</ulink>
      </quote>.</para>
    </legalnotice>
  </articleinfo>

  <para>This page covers Shorewall configuration to use with <ulink
  url="http://www.squid-cache.org">Squid</ulink> running as a Transparent
  Proxy or as a Manual Proxy.</para>

  <caution>
    <para><emphasis role="bold">This article applies to Shorewall 4.0 and
    later. If you are running a version of Shorewall earlier than Shorewall
    4.0.0 then please see the documentation for that
    release.</emphasis></para>
  </caution>

  <section id="Transparent">
    <title>Squid as a Transparent (Interception) Proxy</title>

    <important>
      <para>This section gives instructions for transparent proxying of HTTP.
      HTTPS (normally TCP port 443) <emphasis role="bold">cannot</emphasis> be
      proxied transparently (stop and think about it for a minute; if HTTPS
      could be transparently proxied, then how secure would it be?).</para>
    </important>

    <caution>
      <para>Please observe the following general requirements:</para>

      <itemizedlist>
        <listitem>
          <para>In all cases, Squid should be configured to run as a
          transparent proxy as described at <ulink
          url="http://wiki.squid-cache.org/SquidFaq/InterceptionProxy">http://wiki.squid-cache.org/SquidFaq/InterceptionProxy</ulink>.</para>

          <para>The bottom line of that article is that if you are running
          <emphasis role="bold">Squid 2.6 or later</emphasis>, then you simply
          need to add the word <firstterm>transparent</firstterm> to your
          http_port specification:</para>

          <programlisting>http_port 3128 transparent</programlisting>

          <para>In <emphasis role="bold">earlier Squid versions</emphasis>,
          you need to set several options:</para>

          <programlisting>http_port 3128
httpd_accel_host virtual
httpd_accel_port 80
httpd_accel_with_proxy  on
httpd_accel_uses_host_header on</programlisting>
        </listitem>

        <listitem>
          <para>Depending on your distribution, other Squid configuration
          changes may be required. These changes typically consist of:</para>

          <orderedlist>
            <listitem>
              <para>Adding an ACL that represents the clients on your local
              network.</para>

              <para>Example:</para>

              <programlisting>ACL my_networks src 192.168.1.0/24 192.168.2.0/24</programlisting>
            </listitem>

            <listitem>
              <para>Allowing HTTP access to that ACL.</para>

              <para>Example:</para>

              <programlisting>http_access allow my_networks</programlisting>
            </listitem>
          </orderedlist>

          <para>See your distribution's Squid documentation and <ulink
          url="http://www.squid-cache.org/">http://www.squid-cache.org/</ulink>
          for details.</para>

          <para>It is a good idea to get Squid working as a <link
          linkend="Manual">manual proxy</link> first before you try
          transparent proxying.</para>
        </listitem>

        <listitem>
          <para>The following instructions mention the file
          /etc/shorewall/start - if you don't have that file, simply create
          it.</para>
        </listitem>

        <listitem>
          <para>When the Squid server is in the local zone, that zone must be
          defined ONLY by its interface -- no /etc/shorewall/hosts file
          entries. That is because the packets being routed to the Squid
          server still have their original destination IP addresses.</para>
        </listitem>

        <listitem>
          <para>You must have iptables installed on your Squid server.</para>
        </listitem>
      </itemizedlist>
    </caution>

    <caution>
      <para>In the instructions below, only TCP Port 80 is opened from the
      system running Squid to the Internet. If your users require browsing
      sites that use a port other than 80 (e.g.,
      http://www.domain.tld:<emphasis role="bold">8080</emphasis>) then you
      must open those ports as well.</para>
    </caution>
  </section>

  <section id="Configurations">
    <title>Configurations</title>

    <para>Three different configurations are covered:</para>

    <simplelist>
      <member>Squid (transparent) Running on the Firewall</member>

      <member>Squid (transparent) Running in the local Network</member>

      <member>Squid (transparent) Running in a DMZ</member>
    </simplelist>

    <section id="Firewall">
      <title>Squid (transparent) Running on the Firewall</title>

      <para>You want to redirect all local www connection requests EXCEPT
      those to your own http server (206.124.146.177) to a Squid transparent
      proxy running on the firewall and listening on port 3128. Squid will of
      course require access to remote web servers.</para>

      <para>In <filename>/etc/shorewall/rules</filename>:</para>

      <programlisting>#ACTION   SOURCE     DEST     PROTO    DEST PORT(S)     SOURCE     ORIGINAL
#                                                       PORT(S)    DEST
ACCEPT    $FW        net      tcp      www
REDIRECT  loc        3128     tcp      www              -          !206.124.146.177
</programlisting>

      <para>There may be a requirement to exclude additional destination hosts
      or networks from being redirected. For example, you might also want
      requests destined for 130.252.100.0/24 to not be routed to Squid.</para>

      <para>If needed, you may just add the additional hosts/networks to the
      ORIGINAL DEST column in your REDIRECT rule.</para>

      <para><filename>/etc/shorewall/rules</filename>:<programlisting>#ACTION   SOURCE     DEST     PROTO    DEST PORT(S)     SOURCE     ORIGINAL
#                                                       PORT(S)    DEST
REDIRECT  loc        3128     tcp      www              -          !206.124.146.177,130.252.100.0/24</programlisting></para>

      <para>People frequently ask <emphasis>How can I exclude certain internal
      systems from using the proxy? I want to allow those systems to go
      directly to the net</emphasis>.</para>

      <para>Suppose that you want to exclude 192.168.1.5 and 192.168.1.33 from
      the proxy. Your rules would then be:</para>

      <programlisting>#ACTION   SOURCE     DEST     PROTO    DEST PORT(S)     SOURCE     ORIGINAL
#                                                       PORT(S)    DEST
ACCEPT    $FW        net      tcp      www
REDIRECT  loc:!192.168.1.5,192.168.1.33\
                     3128     tcp      www              -          !206.124.146.177,130.252.100.0/24
ACCEPT    loc        net      tcp      www</programlisting>

      <para>The last rule may be omitted if your loc-&gt;net policy is
      ACCEPT.</para>

      <para>In some cases (when running an LTSP server on the Shorewall
      system), you might want to transparently proxy web connections that
      originate on the firewall itself. This requires care to ensure that
      Squid's own web connections are not proxied.</para>

      <para>First, determine the user id that Squid is running under:</para>

      <programlisting>gateway:/etc/shorewall# <emphasis role="bold">ps aux | fgrep -i squid | fgrep -v fgrep</emphasis>
root     10085  0.0  0.0  23864   700 ?        Ss   Apr22   0:00 /usr/sbin/squid -D -YC
<emphasis role="bold">proxy</emphasis>    10088  0.0  0.9  40512 19192 ?        S    Apr22  10:58 <emphasis
          role="bold">(squid)</emphasis> -D -YC
gateway:/etc/shorewall# </programlisting>

      <para>In this case, the proxy process <emphasis
      role="bold">(squid)</emphasis> is running under the <emphasis
      role="bold">proxy</emphasis> user Id. We add these rules:</para>

      <programlisting>#ACTION   SOURCE     DEST     PROTO    DEST PORT(S)     SOURCE     ORIGINAL          RATE       USER/
#                                                       PORT(S)    DEST              LIMIT      GROUP
ACCEPT    $FW        net      tcp      www
REDIRECT  $FW        3128     tcp      www              -          -                 -         <emphasis
          role="bold"> !proxy</emphasis></programlisting>
    </section>

    <section id="Local">
      <title>Squid (transparent) Running in the local network</title>

      <para>You want to redirect all local www connection requests to a Squid
      transparent proxy running in your local zone at 192.168.1.3 and
      listening on port 3128. Your local interface is eth1. There may also be
      a web server running on 192.168.1.3. It is assumed that web access is
      already enabled from the local zone to the Internet.</para>

      <orderedlist>
        <listitem>
          <para>Add this entry to your /etc/shorewall/providers file.</para>

          <programlisting>#NAME   NUMBER  MARK    DUPLICATE       INTERFACE       GATEWAY         OPTIONS
Squid   1       202     -               eth1            192.168.1.3     loose,notrack</programlisting>
        </listitem>

        <listitem>
          <para>In <filename>/etc/shorewall/tcrules</filename> add:</para>

          <programlisting>#MARK    SOURCE              DEST        PROTO    DEST
#                                                 PORT(S)
202:P    eth1:!192.168.1.3   0.0.0.0/0   tcp      80</programlisting>
        </listitem>

        <listitem>
          <para>In <filename> <filename>/etc/shorewall/interfaces</filename>
          </filename>:</para>

          <programlisting>#ZONE   INTERFACE    BROADCAST    OPTIONS
loc     eth1         detect       <emphasis role="bold">routeback</emphasis>          </programlisting>
        </listitem>

        <listitem>
          <para>On 192.168.1.3, arrange for the following command to be
          executed after networking has come up</para>

          <programlisting><command>iptables -t nat -A PREROUTING -i eth0 ! -d 192.168.1.3 -p tcp --dport 80 -j REDIRECT --to-ports 3128</command>          </programlisting>

          <para>If you are running RedHat on the server, you can simply
          execute the following commands after you have typed the iptables
          command above:</para>

          <programlisting><command>iptables-save &gt; /etc/sysconfig/iptables
 chkconfig --level 35 iptables on</command>         </programlisting>
        </listitem>
      </orderedlist>
    </section>

    <section id="DMZ">
      <title>Squid (transparent) Running in the DMZ</title>

      <para>You have a single system in your DMZ with IP address 192.0.2.177.
      You want to run both a web server and Squid on that system.</para>

      <para>In <filename>/etc/shorewall/rules</filename>:</para>

      <programlisting>#ACTION  SOURCE   DEST                 PROTO    DEST PORT(S)    SOURCE     ORIGINAL
#                                                               PORT(S)    DEST
DNAT     loc      dmz:192.0.2.177:3128 tcp      80              -          !192.0.2.177</programlisting>
    </section>
  </section>

  <section id="Manual">
    <title>Squid as a Manual Proxy</title>

    <para>Assume that Squid is running in zone SZ and listening on port SP;
    all web sites that are to be accessed through Squid are in the
    <quote>net</quote> zone. Then for each zone Z that needs access to the
    Squid server.</para>

    <para><filename>/etc/shorewall/rules</filename>:</para>

    <programlisting>#ACTION   SOURCE   DEST   PROTO   DEST PORT(S)
ACCEPT    Z        SZ     tcp     SP
ACCEPT    SZ       net    tcp     80,443</programlisting>

    <example id="Example1">
      <title>Squid on the firewall listening on port 8080 with access from the
      <quote>loc</quote> zone:</title>

      <para><filename>/etc/shorewall/rules:</filename> <programlisting>#ACTION   SOURCE   DEST   PROTO    DEST PORT(S)
ACCEPT    loc      $FW    tcp      8080
ACCEPT    $FW      net    tcp      80,443</programlisting></para>
    </example>
  </section>

  <section id="TPROXY">
    <title>Transparent with TPROXY</title>

    <para>Shorewall 4.5.4 contains support for TPROXY. TPROXY differs from
    REDIRECT in that it does not modify the IP header and requires Squid 3 or
    later. Because the IP header stays intact, TPROXY requires policy routing
    to direct the packets to the proxy server running on the firewall. This
    approach requires TPROXY support in your kernel and iptables and Squid 3.
    See <ulink
    url="http://wiki.squid-cache.org/Features/Tproxy4">http://wiki.squid-cache.org/Features/Tproxy4</ulink>.</para>

    <note>
      <para>Support for the TPROXY action in shorewall-tcrules(5) and the
      <option>local</option> option in shorewall-providers(5) has been
      available since Shoreall 4.4.7. That support required additional rules
      to be added in the 'start' extention script to make it work
      reliably.</para>
    </note>

    <para>The following configuration works with Squid running on the firewall
    itself (assume that Squid is listening on port 3129 for TPROXY
    connections).</para>

    <para><filename>/etc/shorewall/interfaces:</filename></para>

    <programlisting>#ZONE        INTERFACE        BROADCAST         OPTIONS
-            lo               -                 -</programlisting>

    <para><filename>/etc/shorewall/providers</filename>:</para>

    <programlisting>#NAME   NUMBER   MARK    DUPLICATE  INTERFACE  GATEWAY         OPTIONS               COPY
Tproxy    1        -        -           lo        -            tproxy</programlisting>

    <note>
      <para>Notice that the MARK, DUPLICATE and GATEWAY columns are empty and
      that the only option is <option>tproxy</option>.</para>
    </note>

    <para><filename>/etc/shorewall/tcrules</filename> (assume loc interface is
    eth1 and net interface is eth0):</para>

    <programlisting><emphasis role="bold">FORMAT 2</emphasis>
#MARK           SOURCE      DEST        PROTO      DEST        SOURCE
#                                                  PORT(S)     PORT(S)
DIVERT          eth0        0.0.0.0/0   tcp        -           80
TPROXY(3129)    eth1        0.0.0.0/0   tcp        80</programlisting>

    <para>The DIVERT rules are used to avoid unnecessary invocation of TPROXY
    for request packets after the connection is established and to direct
    response packets back to Squid3.</para>

    <para>/etc/shorewall/rules:</para>

    <programlisting>#ACTION   SOURCE   DEST   PROTO   DEST PORT(S)
ACCEPT    loc      $FW    tcp     80
ACCEPT    $FW      net    tcp     80</programlisting>

    <para><filename>/etc/squid3/squid.conf</filename>:</para>

    <programlisting>...
http_port 3129 tproxy
...</programlisting>
  </section>
</article>
