Fully Transparent + Tproxy + Bridge + Interception

A proxy is a server-like program, receiving requests from clients, forwarding those requests to the real server on behalf of the user, and returning the response as it arrives. Proxies read and parse the application protocol, and reject invalid traffic. So using proxies on a firewall to mediate requests means higher level of security, than packet filtering firewalls.

Simple, non-transparent proxying is somewhat difficult to manage and administer since each client program must be set up to use proxies.

Transparent proxy

To simplify management tasks of clients sitting behind proxy firewalls, the technique ‘transparent proxying’ was invented. Transparent proxying means that the presence of the proxy is invisible to the user. Transparent proxying however requires kernel support.

Packet filters packages lacking

Real transparent proxying requires the following three features from the IP stack of the computer it is running on:

  1. Redirect sessions destined to the outer network to a local process using a packet filter rule.
  2. Make it possible for a process to listen to connections on a foreign address.
  3. Make it possible for a process to initiate a connection with a foreign address as a source.

To increase the efficiency of our internet connection, we use a caching web proxy. A web proxy makes the HTTP request on behalf of the client, and caches the result for later. That way, if multiple users request the same document, the cache can serve its local copy, rather than wasting bandwidth. This has two benefits: users get their content faster (when it’s cached), and the internet connection isn’t bogged down with duplicate requests. Tproxy enable a special feature that allow spoofing request from squidbox to destination , in this way the remote host will see the real ip of the client instead of the ip of the squidbox. We use our Squid box as a bridging interception proxy. This means that the machine acts as a bridge, and is inserted “inline” between other network devices (in our case, just before our firewall). Additionally, Squid is configured as an interception proxy, which means that it will grab requests destined for port 80 (the standard HTTP port) and run them through the caching engine. Connections not bound for port 80 are passed straight through the bridge. This setup is advantageous because it makes the proxy completely invisible to the rest of the network (and the users). If we need to, we can simply take the machine out of the network and everything will continue to work just as before (except that it’s not being cached). No settings on the client machines need to change. However, this setup requires compiling our own Linux kernel, and also our own version of Squid. We’ll walk you through the steps below.

Note: these steps assume Debian Linux (“Etch” is the release we’re using). If you use a different system you may need to compile according to your distribution’s conventions.

TARGET:

First of all showing our target what we will achieve till end of this article.

Workstation: 10.101.88.85
Squidbox : 172.25.12.4
Webserver : 192.168.1.100

You will see in apache logs of Webserver the ip addres of Workstation instead the Squidbox one. Also in access.log you will see all the traffic for http that it cames from Workstation.

Preparing the System

First, set some environment variables so your custom builds will have sane values in the description files:

export DEBFULLNAME="M.Adnan shahzad"

export DEBEMAIL="adnan.shahzad@your_org.edu.pk"

Now we need to download all the components necessary to build packages on our system. Make sure your package repository listing is up-to-date:

apt-get update

Move into the source directory on the machine:

cd /usr/src

Now we need to download a special patch for bridging proxy support in the kernel and iptables, and unpack it.

wget http://www.balabit.hu/downloads/files/tproxy/obsolete/linux-2.6/cttproxy-2.6.18-2.0.6.tar.gz
tar -zxf cttproxy-2.6.18-2.0.6.tar.gz

We are now ready to fetch and build the three other components we need: the kernel, iptables, and squid

Kernel Compilation

First, fetch the kernel package and all of the packages necessary to build a kernel (you can put the following command all on one line):

apt-get install linux-source-2.6.18 kernel-package libncurses5-dev 
fakeroot bzip2 build-essential dpatch devscripts

This will put a tarball of the Linux source in /usr/src. Go there and unpack it:

cd /usr/src
tar -jxf linux-source-2.6.18.tar.bz2

Now move into the Linux source directory:

cd linux-source-2.6.18

You need to apply the patches included with the tproxy download you got earlier:

for patch in ../cttproxy-2.6.18-2.0.6/patch_tree/\*.patch

d> o patch -p1 < $patch

done

Now it’s time for a standard Debian kernel build. I suggest making based on the existing config:

make oldconfig

(You may also use make menuconfig for a graphical interface.)

That will ask you about the new features added by the patch. You want to enable the following:

If you want iptables as a module:

Loadable module support ---> 	
[*] Enable loadable module support  
[ ] ...  
[*] Automatic kernel module loading

NOTE As of kernel 2.6.20 (as of 2.6.19) you Must enable the following

Networking  ----> 	 
Networking options  ----> 	 
[*]   IP: advanced router  
802.1d Ethernet Bridging  

Network packet filtering framework (Netfilter)---> 	 
[*]   Bridged IP/ARP packets filtering (NEW)  
Core Netfilter Configuration ----> 	 
[*] Netfilter connection tracking support---> 	 
["enable"\] Layer 3 Dependent Connection tracking (OBSOLETE)  
[*] Netfilter Xtables support (required for ip_tables)  
[*] "state" match support  
IP: Netfilter Configuration ---> 	 
IP tables support (required for filtering/masq/NAT)  
Full NAT

When you enable full nat then will appear this section

IP: Netfilter Configuration ---> 	 
Transparent proxying  
tproxy match support  
TPROXY target support

Now is time for bridge netfilter:

Network packet filtering framework (Netfilter)---> 	 
Bridge: Netfilter Configuration  ---> 	 
Ethernet Bridge tables (ebtables) support  
ebt: broute table support

You’re now ready to build the kernel:

make-kpkg clean
make-kpkg --rootcmd fakeroot --initrd --append-to-version=-tproxy.1.0 kernel_image

Wait a while for the kernel to compile. When it’s done you’ll have a linux-image package in /usr/src. Go ahead and install it:

cd /usr/src
dpkg -i linux-image-2.6.18\*.deb

If the installation was successful, then we’re almost done (with the kernel, anyway).

We want to load the tproxy modules by default, so add the following lines to the end of your /etc/modules file:

ip_tables
iptable_filter
ipt_TPROXY
ipt_tproxy

Reboot your machine into the new kernel. You can confirm the version by running uname -a. You can confirm that tproxy was installed by running:

dmesg | grep TPROXY

IPTables Compilation:

The new version of the kernel has a patched version of iptables support, which requires that we recompile the iptables binaries to match.

First, move into your source directory:

cd /usr/src

Next, get the source for iptables:

apt-get source iptables
apt-get build-dep iptables

Move into the source directory:

cd iptables-1.3.6.0debian1

Patch the sources:

Note: change of directory to inner iptables dir

cd iptables
patch -p1 < ../../cttproxy-2.6.18-2.0.6/iptables/iptables-1.3-cttproxy.diff
chmod +x extensions/.tproxy-test

Additionally, we need to copy our patched kernel sources into the iptables tree so it can build against them. Change back to the root iptables source tree:

cd /usr/src/iptables-1.3.6.0debian1

Now move the default linux dir out of the way:

mv linux linux-orig
mkdir linux

And copy your linux files in:

for x in COPYING Makefile include net
do cp -a /usr/src/linux-2.6.18/$x linux/$x
done

Now you’re ready to build. Susbstitute your e-mail address in the build command:

dpkg-buildpackage -rfakeroot -us -uc -b –adnan.shahzad@your_org.edu.pk

You’ll end up with an iptables .deb file in your /usr/src directory. You can move into that directory and install the package:

cd /usr/src
dpkg -i iptables_1.3.6.0debian1-5_i386.deb

To confirm that everything is working correctly, try the following command:

iptables -t tproxy -L

If that doesn’t give an error, then all of the modules are installed correctly, and you’re ready to go.

Squid Compilation

For maximum performance, the Squid maintainers recommend that you compile your own version of Squid from scratch. Additionally, our “tproxy” setup is not included in Debian, so we must compile our own anyway.

Change into the source directory:

cd /usr/src

Fetch the source for squid, and the build dependencies:

apt-get source squid
apt-get build-dep squid

./configure –prefix=/usr –exec_prefix=/usr –bindir=/usr/sbin –sbindir=/usr/sbin –libexecdir=/usr/lib/squid –sysconfdir=/etc/squid –localstatedir=/var/spool/squid –datadir=/usr/share/squid –enable-linux-netfilter –enable-storeio=ufs,aufs,diskd,null –enable-arp-acl –enable-removal-policies=lru,heap –enable-snmp –enable-delay-pools –enable-htcp –enable-poll –enable-cache-digests –enable-underscores –enable-referer-log –enable-useragent-log –enable-auth=basic,digest,ntlm –enable-carp –enable-large-files –enable-linux-tproxy –enable-delay-pools –enable-cache-digests –enable-poll –disable-ident-lookups –enable-truncate –enable-removal-policies –enable-delay-pools –enable-cache-digests –enable-poll –enable-arp-acl –disable-ident-lookups –enable-truncate –enable-auth=basic –enable-auth-helpers=NCSA –with-maxfd=8192 –enable-removal-policies=lru,heap –enable-storeio=diskd,ufs,aufs –enable-snmp –enable-icmp –enable-htcp –enable-external-acl-helpers=”wbinfo_group” –enable-basic-auth-helpers=PAM –enable-ssl

We need to make the tproxy headers available to Squid for compilation. You can do this by running the following:

cp /usr/src/linux/include/linux/netfilter_ipv4/ip_tproxy.h 
/usr/include/linux/netfilter_ipv4/

You must also install libcap-dev to get the capabilities file for compiling Squid (if you don’t do this, you’ll see “CAP_NET” errors):

apt-get install openssl ssl-cert 
apt-get install libcap-dev

Also, be sure to add capability to your /etc/modules file (Debian doesn’t load capabilities by default).

You may wish to set certain compiler flags (e.g., CFLAGS=’-O2 -march=pentium4’) before the build to include any processor-specific options.

Note: That these packages may only work for the architecture they’re compiled for!

Now, build the package! Susbstitute your e-mail address in the build command:

dpkg-buildpackage -rfakeroot -us -uc -b -myou@example.com

Once you’ve built the binary installation packages, you’re ready to install them. They’ll appear in the parent directory to your source folder, and there should be 4 Debian package files:

squid_2.6.5-6etch1_i386.deb
squid-cgi_2.6.5-6etch1_i386.deb
squidclient_2.6.5-6etch1_i386.deb
squid-common_2.6.5-6etch1_all.deb

You’ll need to install any dependencies manually. At the moment, this includes lsb-base (for squid) and a web server (for squid-cgi).

To install lsb-base:

sudo apt-get install lsb-base

For a web server, you can go with the tried-and-true apache. However, we want as lightweight a server as possible, so we opt for thttpd:

sudo apt-get install thttpd

You can install the Debian packages using dpkg -i:

sudo dpkg -i /usr/src/squid\*.deb

Once this is done, you should have Squid installed, and ready to configure!

Configuration

At this point, you should have Squid installed on your system. You can confirm this by typing squid -v on the command line. You should get back Squid’s version, along with any compile-time options.

If you don’t have Squid yet, visit the previous section for information on compiling it from scratch, or install a packaged version from your OS vendor. For example, you could say this under Debian:

sudo apt-get install squid squidclient squid-cgi

Now that you’ve got Squid, it’s time to configure it. Squid has a great deal of run-time options, which affect how it caches documents. We’ve tuned our config to work with our particular needs; the descriptions below explain the choices we’ve made. You should make changes as you see fit.

Configure squid.conf to enable tproxy

There are two directive that enable tproxy in squid.conf

http_port 80 tproxy transparent  
tcp_outgoing_address 172.25.12.4

Note:

if tcp_outgoing_address (squidbox ip) is not set you will see error like this
in /var/log/squid/cache.log :


2007/06/16 18:03:48| tproxy ip=172.25.12.4,0x20010ac,port=0 ERROR ASSIGN
2007/06/16 18:03:48| tproxy ip=172.25.12.4,0x20010ac,port=0 ERROR ASSIGN
—————————————————————————–

Remember to enable debug with debug_options ALL,1 in squid.conf to see what’s wrong

Bridge Setup

We configure our system as a network bridge, which means that it sits between two physical devices on our network and relays the packets between them. However, there’s a twist: we intercept certain packets (those destined for port 80) and shunt them to Squid for processing.

You’ll need two ethernet cards in your machine to bridge between (one “in” and one “out”, as it were). You can use another card for a management IP address, or you can actually assign an address to the bridge itself and reach the machine just as you would a “real” interface.

In order to set up the bridge, we need to make a few tweaks to the system. First, we need to install some software that’s necessary for setting up a bridge:

apt-get install bridge-utils

Next, edit /etc/network/interfaces. You should already have a stanza for a statically configured interface (e.g., eth0). Keep the settings for the stanza, but replace the interface name with br0. Also, add the line bridge_ports eth1 eth2 to add them to the bridge. For example:

auto br0
iface br0 inet static
bridge_ports eth1 eth2
address 172.25.12.4
netmask 255.255.255.248
gateway 172.25.12.6

Additionally, if your setup is like ours you’ll need to add some routing to the box so it knows where to send packets. Our Squid box sits just between our firewall/router and LAN. Thus, it needs to be told how to route packets to the LAN and packets to the outside world. We do this by specifying the firewall as the “gateway” in the interfaces file, and adding a static route for our LAN. Thus, you would add the following lines to /etc/network/interfaces in the br0 stanza:

up route add -net 10.0.0.0/8 gw 172.25.12.6

We’ll need to tell the kernel that we’re going to forward packets, so make sure the following are set in /etc/sysctl.conf:

net.ipv4.conf.default.rp_filter=1
net.ipv4.conf.default.forwarding=1
net.ipv4.conf.all.forwarding=1

Once you’re all set, the easiest thing to do is reboot for the bridge config to take effect. The other settings should now be working also. cat /proc/sys/net/ipv4/ip_forward to confirm that the machine is in forwarding mode.

TProxy Interception

To redirect traffic from the brige to squid we need ebtables, which is like iptables. we want manipulate the traffic that is crossing the brige.

Install ebtables program :

Apt-get install ebtables

and use this rule to intercept the traffic for destination port 80

ebtables -t broute -A BROUTING -p IPv4 --ip-protocol 6 --ip-destination-port 80 -j redirect --redirect-target ACCEPT

Now let’s redirect to squid using iptables and tproxy

iptables -t tproxy -A PREROUTING -i br0 -p tcp --dport 80 -j TPROXY --on-port 80

Testing:

Workstation: 10.101.88.85
Squidbox : 172.25.12.4
Webserver : 10.101.88.25

You will see in apache logs of Webserver the ip addres of Workstation instead the Squidbox one. Also in access.log you will see all the traffic for http that it cames from Workstation.

FAQ:

1) How to I find my kernel is patched with Tproxy?

2) When Kernel rebuild it didn’t detect LAN Card.

3) How do I check TPROXY Rules?

4) How can I check IPTABLES patched working?

Source.list

deb http://http.us.debian.org/debian stable main contrib non-free

#deb http://dotdeb.pimpmylinux.org/ stable all

#deb-src http://dotdeb.pimpmylinux.org/ stable all

#deb http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free

#deb http://security.debian.org stable/updates main contrib non-free

#deb http://http.us.debian.org/debian/ etch main contrib non-free

#deb http://security.debian.org/ etch/updates main

#deb http://packages.dotdeb.org stable all

#deb http://rekudos.net/ testing main

deb http://packages.dotdeb.org stable all

deb-src http://ftp.de.debian.org/debian testing main contrib non-free

deb-src http://security.debian.org stable/updates main contrib non-free

# deb cdrom:[Debian GNU/Linux 4.0 r0 Etch - Official i386 NETINST Binary-1 20070407-11:29]/ etch contrib main

#deb cdrom:[Debian GNU/Linux 4.0 r0 Etch - Official i386 NETINST Binary-1 20070407-11:29]/ etch contrib main

#deb http://ftp.egr.msu.edu/debian main

#deb http://people.debian.org/~pvaneynd/cl-sarge-packages ./

#deb http://people.debian.org/~pvaneynd/cl-breezy-packages ./

#deb http://packages.dotdeb.org stable all

deb-src http://ftp.de.debian.org/debian testing main contrib non-free

#deb-src http://security.debian.org stable/updates main contrib non-free

#deb http://http.us.debian.org/debian etch main contrib non-free

#deb http://security.debian.org/ etch/updates main

#deb http://http.us.debian.org/debian etch main contrib non-free

#deb http://packages.dotdeb.org stable all

#deb-src http://ftp.de.debian.org/debian testing main contrib non-free

#deb http://security.debian.org/ etch/updates main contrib

#deb-src http://security.debian.org/ etch/updates main contrib

# Security updates for “stable”

#deb http://security.debian.org stable/updates main contrib non-free

#deb http://security.debian.org testing/updates main contrib non-free

# Stable

#deb http://ftp.de.debian.org/pub/debian stable main contrib non-free

#deb http://ftp.de.debian.org/pub/debian-non-US stable/non-US main contrib non-free

# Stable Sources

#deb-src http://ftp.de.debian.org/pub/debian stable main contrib non-free

#deb-src http://ftp.de.debian.org/pub/debian-non-US stable/non-US main contrib non-free

#deb-src http://security.debian.org/ etch/updates main contrib.

# apt-get install libkrb53 libcupsys2-gnutls10 libldap2 libldap2-dev libkrb5-dev krb5-doc krb5-user krb5-config

# apt-get install libkrb5-dev krb5-doc krb5-user krb5-config

NTLM Authentication

Krb5.conf:

[libdefaults]

defaultrealm = YOURORG.NET

# encrypt = true

# The following krb5.conf variables are only for MIT Kerberos.

# krb4config = /etc/krb.conf

# krb4realms = /etc/krb.realms

# kdctimesync = 1

# ccachetype = 4

# forwardable = true

# proxiable = true

# The following encryption type specification will be used by MIT Kerberos

# if uncommented. In general, the defaults in the MIT Kerberos code are

# correct and overriding these specifications only serves to disable new

# encryption types as they are added, creating interoperability problems.

# defaulttgsenctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5

# defaulttktenctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5

# permittedenctypes = aes256-cts arcfour-hmac-md5 des3-hmac-sha1 des-cbc-crc des-cbc-md5

# The following libdefaults parameters are only for Heimdal Kerberos.

# v4instanceresolve = false

# v4nameconvert = {

# host = {

# rcmd = host

# ftp = ftp

# }

# plain = {

# something = something-else

# }

# }

# fcc-mit-ticketflags = true

[realms]

YOURORG.NET = {

adminserver = YOURORG.NET

kdc = XX.XX.XXX.XXX

defaultrealm = YOURORG.NET

}

[domainrealm]

.yourorg.net = YOURORG.NET

yourorg.net = YOURORG.NET

Squid Changes:

authparam ntlm program /usr/bin/ntlmauth –helper-protocol=squid-2.5-ntlmssp

authparam ntlm children 30

authparam ntlm keepalive on

authparam basic program /usr/bin/ntlmauth –helper-protocol=squid-2.5-basic

authparam basic children 5

authparam basic realm Squid proxy-caching web server

authparam basic credentialsttl 2 hours

acl ntlm proxyauth REQUIRED src=10.0.0.0/8

httpaccess allow ntlm

Smb.conf

# Global parameters

[global]

workgroup = YOURORG

realm = YOURORG.NET

preferred master = no

server string = Samba file and print server

security = ADS

encrypt passwords = yes

log level = 3

log file = /var/log/samba/%m

max log size = 50

# winbind separator = +

password server = XX.XX.XXX.XXX

printcap name = cups

printing = cups

idmap uid = 10000-20000

idmap gid = 10000-20000

nsswitch.conf

# /etc/nsswitch.conf

#

# Example configuration of GNU Name Service Switch functionality.

# If you have the glibc-doc-reference' and info’ packages installed, try:

# `info libc “Name Service Switch”’ for information about this file.

passwd: compat winbind

group: compat winbind

shadow: compat winbind

hosts: files dns wins

networks: files

protocols: db files

services: db files

ethers: db files

rpc: db files

netgroup: nis

Key exchange btw linux and domain

# kinit adnan.shahzad@yourorg.net

For Domain joing

# net ads join -S XX.XX.XXX.XXX -U Shahzad