Gateway and Proxy Server with squid, squint, iptables in Ubuntu/Debian
What I have done in this howto ...
I have googled and took several references from several how-to/tutorials and adopted/tested them to my system/server and make a
Easy step-by-step howto. I hope this will help some other people who use/will use Linux as Gateway + Proxy Server.
I will revise this how-to time to time; you may give your valuable advise to me ...
STEP-01: Install Ubuntu Server Edition 8.04/8.10/9.04
Install Ubuntu Server Edition 8.04/8.10/9.04 On a particular server/pc which will be your gateway+proxy server.
Installation Requirements...
>> Internet Connection; and
While you install Ubuntu Server; Select the following pkgs...
>> OpenSSH Server
>> LAMP (Optional; if you want to use squid graphical log analyzer like squint)
Also determine that; you have two ethernet interfaces...
interface eth0 is connected to Internet
interface eth1 is connected to Local Network
Suppose,
eth0 have IP: 123.49.42.180
eth1 have IP: 192.168.100.1
STEP: 02- Put IP Address on LAN Interface and DNS Address
| # vi /etc/network/interfaces |
|
# The loopback network interface auto lo iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static address 123.49.42.180 netmask 255.255.255.224 network 123.49.42.160 broadcast 123.49.42.191 gateway 123.49.42.161 # The secondary network interface auto eth1 iface eth1 inet static address 192.168.100.1 netmask 255.255.255.0 network 192.168.100.0 broadcast 192.168.100.255 |
| Save + Exit | # /etc/init.d/networking restart |
Put dns server address... |
| # vi /etc/resolv.conf |
|
nameserver 4.2.2.1 nameserver 4.2.2.2 |
| Save + Exit |
| Now you should get the Internet |
STEP: 03- Install some basic packages
|
# apt-get update # apt-get -q -y install build-essential rcconf vim-nox iftop |
STEP: 04- NAT and basic firewall with iptables
| Make a nat/firewall script as /usr/bin/nat_firewall.sh "directory" |
| # vim /usr/bin/nat_firewall.sh |
Add or copy/past the following lines (Use your own values of ips/ethernet) ... |
|
#!/bin/bash echo -e "\n>>> LOADING NAT FIREWALL ...\n" echo -e ">>> RESETING IMPORTANT PARAMETERS ...\n" #Reduce DoS'ing ability by reducing timeouts ... echo 1 > /proc/sys/net/ipv4/ip_forward echo 1 > /proc/sys/net/ipv4/tcp_syncookies echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter echo 1 > /proc/sys/net/ipv4/conf/lo/rp_filter echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts echo 30 > /proc/sys/net/ipv4/tcp_fin_timeout echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time echo 1 > /proc/sys/net/ipv4/tcp_window_scaling echo 0 > /proc/sys/net/ipv4/tcp_sack echo 1280 > /proc/sys/net/ipv4/tcp_max_syn_backlog echo -e ">>> RESETING FIREALL ...\n" iptables -F INPUT iptables -F OUTPUT iptables -F FORWARD iptables -F -t mangle iptables -F -t nat iptables -F iptables -X iptables -Z iptables -t nat -F iptables -t nat -X iptables -t nat -Z iptables --table nat -F iptables --delete-chain iptables --table nat --delete-chain iptables -t mangle --delete-chain echo -e ">>> LOADING MODULES ...\n" /sbin/modprobe ip_tables /sbin/modprobe ip_queue /sbin/modprobe iptable_filter /sbin/modprobe iptable_mangle /sbin/modprobe iptable_nat /sbin/modprobe ipt_limit /sbin/modprobe ipt_LOG /sbin/modprobe ipt_MASQUERADE /sbin/modprobe ipt_multiport /sbin/modprobe ipt_REDIRECT /sbin/modprobe ipt_REJECT /sbin/modprobe ipt_state /sbin/modprobe ip_nat_ftp /sbin/modprobe ip_conntrack /sbin/modprobe ip_conntrack_ftp echo -e ">>> SETING VARIABLES ...\n" WAN="eth0" LAN="eth1" IPT="/sbin/iptables" LAN_IP="192.168.100.0/24" # IP addresses on the LAN side WAN_IP="123.49.42.180" # IP from ISP Connected to Internet echo -e ">>> SETING POLIECY ...\n" $IPT -F INPUT $IPT -P INPUT DROP $IPT -F OUTPUT $IPT -P OUTPUT ACCEPT $IPT -F FORWARD $IPT -P FORWARD ACCEPT echo -e ">>> SETING CUSTOM RULES ...\n" $IPT -A INPUT -i lo -j ACCEPT $IPT -A INPUT -i $LAN -j ACCEPT $IPT -A INPUT -i $WAN -m state --state ESTABLISHED,RELATED -j ACCEPT # ENABLE SOME SERVICES .... for i in 22 78 25 53 80 8080 443 110 143 do $IPT -A INPUT -i $WAN -p tcp --dport $i -j ACCEPT done # ALLOW DNS(udp)/icmp $IPT -A INPUT -i $WAN -p udp --dport 53 -j ACCEPT $IPT -A INPUT -p icmp --icmp-type 8 -s 0/0 -d $WAN_IP -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -p icmp --icmp-type 0 -s 0/0 -d $WAN_IP -m state --state ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -p icmp --icmp-type 8 -s 0/0 -d $LAN_IP -m state --state NEW,ESTABLISHED,RELATED -j ACCEPT $IPT -A INPUT -p icmp --icmp-type 0 -s 0/0 -d $LAN_IP -m state --state ESTABLISHED,RELATED -j ACCEPT #Limiting the incoming icmp ping request: $IPT -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j ACCEPT $IPT -A INPUT -p icmp -m limit --limit 1/s --limit-burst 1 -j LOG --log-prefix PING-DROP: $IPT -A INPUT -p icmp -j DROP #### SOME PORT BLOCK badport="135,136,137,138,139,445" $IPT -A INPUT -p tcp -m multiport --dport $badport -j DROP $IPT -A INPUT -p udp -m multiport --dport $badport -j DROP $IPT -A INPUT -p tcp -m multiport --sport $badport -j DROP $IPT -A INPUT -p udp -m multiport --sport $badport -j DROP # SNAT/NAT $IPT -t nat -A POSTROUTING -s $LAN_IP -d 0/0 -j SNAT --to-source $WAN_IP # TPROXY (Uncomment 'remove hash #' this line after you configure squid proxy) # $IPT -t nat -A PREROUTING -p tcp -s $LAN_IP --dport 80 -j REDIRECT --to-port 8080 # echo -e ">>> FIRWALL LOADED [DONE] \n" |
| Save + Exit |
|
# chmod 755 /usr/bin/nat_firewall.sh # vim /etc/rc.local |
Add the following line in /etc/rc.local before the line 'exit 0'... |
| /usr/bin/nat_firewall.sh |
| Save + Exit |
| Now run the nat_firewall.sh script; See the output bellow;. |
| # /usr/bin/nat_firewall.sh |
Output |
|
>>> LOADING NAT FIREWALL ... >>> RESETING IMPORTANT PARAMETERS ... >>> RESETING FIREALL ... >>> LOADING MODULES ... >>> SETING VARIABLES ... >>> SETING POLIECY ... >>> SETING CUSTOM RULES ... >>> FIRWALL LOADED [DONE] |
|
Now go to a client PC and put the local ip address (from 192.168.100.0/24) and verify that you are getting internet via your linux-gateway. |
STEP: 05- Install and Configure Squid
|
Download the latest version of squid from
http://www.squid-cache.org/Versions/v3/3.0/ |
|
# cd /opt/ # wget http://www.squid-cache.org/Versions/v3/3.0/squid-3.0.STABLE15.tar.gz |
Unpack and Install Squid... |
|
# tar zxvf squid-3.0.STABLE15.tar.gz # cd squid-3.0.STABLE15 # ./configure --prefix=/usr --includedir=/usr/include --datadir=/usr/share --bindir=/usr/sbin --libexecdir=/usr/lib/squid --localstatedir=/var --sysconfdir=/etc/squid --enable-removal-policies=heap,lru --enable-storeio=diskd,aufs,ufs --enable-time-hack --enable-snmp --with-large-files --enable-linux-netfilter --enable-large-cache-files --disable-ident-lookups --enable-cache-digests --enable-underscores --enable-kill-parent-hack --enable-follow-x-forwarded-for # make all # make install |
Configure Squid... |
|
# useradd squid # vim /etc/passwd |
Change " squid:x:.....:/home/squid:/bin/bash " to " squid:x:......:/home/squid:/bin/false" |
| Save + Exit |
|
# cd /etc/squid/ # cp squid.conf squid.conf.orig # echo "" > squid.conf # vim squid.conf |
Now Insert (you may copy/past) the following configuration, |
|
############## Start of squid.conf ########### cache_effective_user squid cache_effective_group squid # put your own/appropriate dns address on tag 'dns_nameservers' dns_nameservers 4.2.2.1 4.2.2.2 icp_query_timeout 1000 # tag 'high_memory_warning' should be 1/4 of your total ram ... high_memory_warning 512 MB # visible_hostname should be your servers/systems/pcs hostname found in /etc/hostname file ... visible_hostname gw-proxy # tag 'cache_mem' should be 1/4 of your total ram ... cache_mem 512 MB cache_replacement_policy heap LFUDA memory_replacement_policy heap LFUDA cache_swap_low 90 cache_swap_high 95 # Object siez in cahce ... maximum_object_size 8192 KB maximum_object_size_in_memory 64 KB # cache storage scehme ... # cache can be in a directory or individual hdd partition and size should not be equal to your total hdd ... # here size is about 55GB out of a individual hdd partition labeled as 'cache' of 60GB... # create a directory named 'cache' in '/' (later mentioned) if you don't have individual partition.. cache_dir diskd /cache 55000 16 256 Q1=72 Q2=64 # Log files ... cache_store_log none cache_access_log /var/log/squid/access.log cache_log /var/log/squid/cache.log cache_mgr sysadmin@yourdomain.com refresh_pattern ^ftp: 1440 20% 10080 refresh_pattern ^gopher: 1440 0% 1440 refresh_pattern (cgi-bin|\?) 0 0% 0 refresh_pattern . 0 20% 4320 # Squid to run transparently ... http_port 8080 transparent # Acess Controll list ... acl manager proto cache_object acl localhost src 127.0.0.1/32 acl to_localhost dst 127.0.0.0/8 # acl SSL_ports port 443 acl Safe_ports port 80 # http acl Safe_ports port 21 # ftp acl Safe_ports port 443 # https acl Safe_ports port 70 # gopher acl Safe_ports port 210 # wais acl Safe_ports port 1025-65535 # unregistered ports acl Safe_ports port 280 # http-mgmt acl Safe_ports port 488 # gss-http acl Safe_ports port 591 # filemaker acl Safe_ports port 777 # multiling http acl CONNECT method CONNECT http_access allow manager localhost http_access deny manager http_access deny !Safe_ports http_access deny CONNECT !SSL_ports # your ip blocks ... acl mynetwork src 192.168.100.0/24 # block some common viruses ... acl badurl urlpath_regex -i cmd.exe acl virus urlpath_regex winnt/system32/cmd.exe? acl codered url_regex \/default\.ida$ acl dangurl urlpath_regex -i \.id[aq]\?.{100,} acl dangurl urlpath_regex -i /readme\.(eml|nws|exe) http_access deny badurl http_access deny virus http_access deny codered http_access deny dangurl # http_access allow mynetwork # acl PURGE method PURGE http_access allow PURGE localhost http_access deny PURGE # deny_info TCP_RESET all http_access deny all #put your WAN IP (Connected to internet, here eth0) tcp_outgoing_address 123.49.42.180 mynetwork # icp_access allow mynetwork icp_access deny all # htcp_access allow mynetwork htcp_access deny all ie_refresh on ######## End of squid.conf ############### |
| Save + Exit |
| Create necessary files to run squid ... |
|
# mkdir /var/log/squid
# touch /var/log/squid/access.log # touch /var/log/squid/cache.log # mkdir /cache # chown -R squid:squid /cache # chown -R squid:squid /var/log/squid # chown -R squid:squid /var/log/squid/ |
Creating cache sub-directories... |
|
# squid -z # chown -R squid:squid /cache |
Now run the squid service ... |
| # squid -D |
Check that squid sevice is running (you will see the process ids)... |
|
# pgrep squid # vim /etc/rc.local |
Add the following line in /etc/rc.local before the line 'exit 0'... |
| squid -D |
| Save + Exit |
| Activate the transparent proxy line in /usr/bin/nat_firewall.sh ... |
| # vim /usr/bin/nat_firewall.sh |
Enable the follwoing line (remove hash #) ... |
|
# TPROXY (Uncomment 'remove hash #' this line after you configure squid proxy) $IPT -A PREROUTING -t nat -s $LAN_IP -p tcp --dport 80 -j REDIRECT --to-port 8080 |
| Save + Exit |
| Re-run /usr/bin/nat_firewall.sh ... |
| # /usr/bin/nat_firewall.sh |
Now goto your local client pc and browse and see the log file in linux-gw/proxy server as ... |
| # tail -f /var/log/squid/access.log |
STEP: 06- Install squid log analyzer Squint
Among several squid (proxy) log analyzer, I found squint is cool and I still use it; though it is not updated since 2004, but still it works in latest version of Ubuntu Server Edtion 9.04 and Debian 5 Lenny without any funcitonal problem. I hope you already have installed LAMP while you installed the Linux, otherwise you have to install apache2 and php5 by apt-get and have to start the apache2 service. Download the last version of squint from my site link http://www.linux-bd.com/app/squint.tar.gz and install it. |
|
# cd /opt/ # wget http://www.linux-bd.com/app/squint.tar.gz # tar zxvf squint.tar.gz # cd squint-0.3.18/ # cp squint.pl squint.cron.sh /usr/local/bin # squint.cron.sh init # squint.cron.sh all |
After you apply the command # squint.cron.sh all you might see the output like bellow, but don't worry, it is ok. Also you might have to wait some time after applying the command, this depneds on the amount of access.log file you have. |
| OUTPUT SAMPLE ... |
|
Generating report to /var/www/squint/all/daily from 20090622 to 20090623 Parentheses missing around "my" list at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 247. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 341. Name "main::messagelog" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::listlimit" used only once: possible typo at /usr/local/bin/squint.pl line 168. Name "main::peak" used only once: possible typo at /usr/local/bin/squint.pl line 709. Name "main::nametofilenamebasehref" used only once: possible typo at /usr/local/bin/squint.pl line 568. Name "main::basedom" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::basename" used only once: possible typo at /usr/local/bin/squint.pl line 351. rm: cannot remove `/var/www/squint/all/weekly6': No such file or directory Generating report to /var/www/squint/all/weekly0 from 20090616 to 20090623 Parentheses missing around "my" list at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 247. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 341. Name "main::messagelog" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::listlimit" used only once: possible typo at /usr/local/bin/squint.pl line 168. Name "main::peak" used only once: possible typo at /usr/local/bin/squint.pl line 709. Name "main::nametofilenamebasehref" used only once: possible typo at /usr/local/bin/squint.pl line 568. Name "main::basedom" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::basename" used only once: possible typo at /usr/local/bin/squint.pl line 351. rm: cannot remove `/var/www/squint/all/monthly6': No such file or directory Generating report to /var/www/squint/all/monthly0 from 20090501 to 20090601 Parentheses missing around "my" list at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. Useless use of a variable in void context at /usr/local/bin/squint.pl line 404. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 247. main::writeusersitereports() called too early to check prototype at /usr/local/bin/squint.pl line 341. Name "main::messagelog" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::listlimit" used only once: possible typo at /usr/local/bin/squint.pl line 168. Name "main::peak" used only once: possible typo at /usr/local/bin/squint.pl line 709. Name "main::nametofilenamebasehref" used only once: possible typo at /usr/local/bin/squint.pl line 568. Name "main::basedom" used only once: possible typo at /usr/local/bin/squint.pl line 351. Name "main::basename" used only once: possible typo at /usr/local/bin/squint.pl line 351. ~# |
Now there is a bug in crontab format of squint in /etc/crontab to work the squint properly we have to fix that. Open the crontab file and see what exits for squint section. |
| # vim /etc/crontab |
You will see the following section |
|
# squint squid reports # Weekly, on Mondays 00 01 * * Monday root /usr/local/bin/squint.cron.sh weekly # Monthly, on the first day of the month 00 02 1 * * root /usr/local/bin/squint.cron.sh monthly # Daily at 3am 00 03 * * * root /usr/local/bin/squint.cron.sh daily |
You have to replace the Monday with numaric 1 which also means it is Monday (first working day of a week) but in numaric vlaue. Otherwise crontab daemon will not run properly. |
So, Finally the crontab section for squint will be as follows |
|
# squint squid reports # Weekly, on Mondays 00 01 * * 1 root /usr/local/bin/squint.cron.sh weekly # Monthly, on the first day of the month 00 02 1 * * root /usr/local/bin/squint.cron.sh monthly # Daily at 3am 00 03 * * * root /usr/local/bin/squint.cron.sh daily |
| Save + Exit |
You will also see a directory name squint created in /var/www located as /var/www/squint that is your squint log storage directory, this is also the apache documentroot for accessing squint by web browser. |
Browse the location http://123.49.42.180/squint by your firefox/ie/opera web-browser and you should see the squid log files. |
So, I am done for now for linux as internet gateway, you may use this howto as a guideline and make changes as your requirements, also you may drop your asking to helpdesk@linux-bd.com |
...I believe that "There is no shortcut on the way of success" |