Internet gateway on FreeBSD

Building a gateway to the global network on FreeBSD – this is one of the most frequent cases using this system. The main pluses of this decision are: stability, scalability, resistance to high loads and of course free of charge all the used software. In this article were used FreeBSD 7.0 RELEASE amd64, IPFW as firewall, daemon natd and squid as proxy server.

Let’s start with the installation of IPFW. To do this, recompile the kernel with support for multiple functions. Go to the directory corresponding to the architecture of our CPU and make a copy of the default kernel as ROUTER:

cd / 
cp usr/src/sys/amd64/conf GENERIC ROUTER

editing our new kernel and adding new features:

cpu HAMMER
ident ROUTER
makeoptions DEBUG=- G # Build kernel with gdb (1) debug symbols
options IPFIREWALL # firewall
options IPFIREWALL_VERBOSE # Logging package, if in rule is written log
options IPFIREWALL_VERBOSE_LIMIT = 100 # limit log (repeated)
options IPFIREWALL_DEFAULT_TO_ACCEPT # default rule - permitting
options IPDIVERT # required for NAT
options IPFIREWALL_FORWARD # packet forwarding
options DUMMYNET # speed limit

building and installing the new kernel:

cd /usr/src
make buildkernel KERNCONF = ROUTER
make installkernel KERNCONF = ROUTER

add in rc.conf following lines:

firewall_enable = "YES"
firewall_type = "Open"
firewall_logging "YES"
natd_enable = "YES"
natd_interface = "rl0";

restarting: If all goes well, then we should have open firewall with NAT. While left as they are. The next step we will install a proxy server.

cd /usr/ports/www/squid
make install clean
rehash

Next edit the configuration file of SQUID. (all the restrictions are based on IP): vi /usr/local/etc/squid/squid.conf

Port to listen
http_port 3128
 
# Port for transparent proxy
http_port 3129 transparent
 
# List of words that are being discovered in the URL cause processing without caching
hierarchy_stoplist cgi-bin?
 
# The ACL that cause mismatch with the cache, and query with an answer will not be cached
acl QUERY urlpath_regex cgi-bin \?
 
#
no_cache deny QUERY
 
# cache memory
cache_mem 256 MB
 
# The directory for the cache, the number - the size of the cache in Mb, number of first level directories, number of second-level directories in each directory of the first.
cache_dir ufs /usr/local/squid/cache 50000 64 512

# Access log - path of log file.
access_log /var/log/squid/access.log

# File hosts, checked at startup. Because it takes a domain name and added to the incomplete addresses
hosts_file /etc/hosts

# Directory where you store HTML c text errors
error_directory /usr/local/etc/squid/errors/Russian-1251
cache_log /var/log/squid/cache.log

# Debug_options ALL, 5
pid_filename /var/log/squid/squid.pid

# Ports on which will open truth proxy
acl safe_ports port 80 # http
acl safe_ports port 21 # ftp
acl safe_ports port 443 # ssl
acl icq_ports port 5190 # ICQ

# Users who will use internet with some restrictions
acl inet_users src "/usr/local/etc/squid/inet_users"

# Users with full access to internet
acl inet_full src "/usr/local/etc/squid/inet_full"

 Describe the networks (all IPs)
 acl all src 0.0.0.0/0.0.0.0
 
 # Describe localhost
 acl localhost src 127.0.0.1/255.255.255.255
 # Forbidden in the URL of expression (for all Url)
 acl deny_url url_regex "/usr/local/etc/squid/deny_url"
 # Illegal domain names
 acl deny_domains dstdomain "/usr/local/etc/squid/deny_domains"
 
 # Users with limited Internet access, only
 # A specific set of resources.
 acl inet_restrict src "/usr/local/etc/squid/inet_restrict"
 
 # List of sites for those who have their particular set of
 acl domains_for_restrict dstdomain "/usr/local/etc/squid/domains_for_restrict"
 
 # ICQ users
 acl inet_icq src "/usr/local/etc/squid/inet_icq"
 
 # Allow access to the entire group inet_full
 http_access allow inet_full
 
 # Notch prohibited chunks url, chop advertising if necessary
 # Http_access deny deny_url
 
 # Allow port asechny those who have ICQ
 http_access allow inet_icq icq_ports
 
 # Notch banned domains
 http_access deny deny_domains
 
 # Notch all the ports intermediate safe_ports
 http_access deny! safe_ports
 
 # Inet allow ordinary users
 http_access allow inet_users
 
 # Inet allow limited users to the Allowed Sites
 http_access allow inet_restrict domains_for_restrict
 
 # Block all unnecessary
 http_access deny all

summary of the configuration: now we have the standard port and transparent proxy; accepting requests http, https ftp, icq. next create and fill the content of all files listed in this config, then making the user squid owner of the folder of the cache, then create the cNche and start squid:

chown -R squid:wheel /usr/local/squid
 squid -z
 /usr/local/etc/rc.d/squid start
 ps -waux | grep squid
 squid 965 0,0 0,1 7688 2076 ?? Is 21:37 0:00,00 /usr/local/sbin/squid -D
 squid 967 0,0 1,0 28168 20008 ?? S 21:37 0:06,00 (squid)-D (squid)
 squid 1008 0.0 0.0 2532 844 ?? Is 21:37 0:00,00 (unlinkd) (unlinkd)
 root 7943 0,0 0,1 6928 1428 p0 S+ 16:02 0:00,00 grep squid

Now go back to the firewall. Here is example script.

 #! /bin/sh
 
 # Before we start, reset the list
 ipfw -q -f flush
 
 # Set the prefix command to set the rules
 cmd = "ipfw -q add"
 skip = "skipto 400"
 wanip = "111.111.111.111" # external IP
 lannet = "192.168.0.0/24" # Internal network
 eif = "rl0" # external interface
 
 # There is no prohibition within the interface looking into a local network
 $cmd 010 allow all from any to any via re0
 
 # No restrictions on the Loopback interface
 $cmd 020 allow all from any to any via lo0
 
 # Chop attempts lo0 climb to somewhere and somewhere to climb on the lo0
 $cmd 030 deny ip from any to 127.0.0.0/8
 cmd 040 deny ip from 127.0.0.0/8 to any
 
 # Send all on a transparent squid
 $cmd 050 fwd 127.0.0.1,3129 tcp from $lannet to any 21,80,443,5190 out via $eif
 
 # Incoming NAT
 $cmd 060 divert natd ip from any to any in via $eif
 
 # Allow a package to pass, if the previous was added to
 # "Dynamic" rules table with a resolution of the state keep-state
 $cmd 070 check-state
 
 ############## Outgoing ################
 
 # Outgoing PING
 $cmd 100 $skip icmp from any to any keep-state
 
 # Outgoing NTP
 $cmd 105 $skip udp from any to any 123 out via $eif keep-state
 
 # Allow DNS
 $cmd 110 $skip udp from any to any 53 out via $eif keep-state
 $cmd 111 $skip tcp from any to any 53 out via $eif setup keep-state
 
 # We produce user to bypass SQUID
 $cmd 140 $skip all from $lannet to any 4899 out via $eif setup keep-state
 $cmd 150 $skip all from $lannet to any 3389 out via $eif setup keep-state
 $cmd 160 $skip all from $lannet to any 25 out via $eif setup keep-state
 $cmd 170 $skip all from $lannet to any 110 out via $eif setup keep-state
 
 # Allow full output from server
 $cmd 190 $skip all from $wanip to any out via $eif setup keep-state
 
 ############# Incoming ################
 
 # Disallow all incoming traffic from the reserved address spaces
 $cmd 200 deny all from 192.168.0.0/16 to any in via $eif # RFC 1918 private IP
 $cmd 201 deny all from 172.16.0.0/12 to any in via $eif # RFC 1918 private IP
 $cmd 202 deny all from 10.0.0.0/8 to any in via $eif # RFC 1918 private IP
 $cmd 203 deny all from 127.0.0.0/8 to any in via $eif # loopback
 $cmd 204 deny all from 0.0.0.0/8 to any in via $eif # loopback
 $cmd 205 deny all from 169.254.0.0/16 to any in via $eif # DHCP auto-config
 $cmd 206 deny all from 192.0.2.0/24 to any in via $eif # reserved for docs
 $cmd 207 deny all from 204.152.64.0/23 to any in via $eif # Sun cluster
 $cmd 208 deny all from 224.0.0.0/3 to any in via $eif # Class D & E multicast
 
 # Disallow ident
 $cmd 215 deny tcp from any to any 113 in via $eif
 
 # Disallow all Netbios services. 137, 138, 139
 $cmd 220 deny tcp from any to any 137 in via $eif
 $cmd 221 deny tcp from any to any 138 in via $eif
 $cmd 222 deny tcp from any to any 139 in via $eif
 $cmd 223 deny tcp from any to any 81 in via $eif
 
 # Incoming ping, several types
 $cmd 300 allow icmp from any to $wanip in via $eif icmptypes 0,8,11 limit src-addr 2
 
 # Allow incoming www function, if there is a web server
 $cmd 310 allow tcp from any to $wanip 80 in via $eif setup limit src-addr 2
 
 # Allow incoming secure SSH, port number better change
 $cmd 320 allow tcp from any to $wanip 22 in via $eif setup limit src-addr 2
 
 # Allow incoming mail SMTP, if there is a mail server
 $cmd 330 allow tcp from any to $wanip 25 in via $ eif setup limit src-addr 2

 # Allow incoming mail POP3, if you have mail server
 $cmd 340 allow tcp from any to $wanip 110 in via $eif setup limit src-addr 2

 # Allow RAdmin, better change the port number
 $cmd 350 allow tcp from any to $wanip 4899 in via $eif setup limit src-addr 2

 # Allow already established connections
 $cmd 360 allow all from any to any established

 ########### Final ###############

 # Chop everything that is not spent in a skip
 $cmd 399 deny log all from any to any

 # Outgoing NAT
 $cmd 400 divert natd ip from any to any out via $eif

 # We produce packages from the skip
 $cmd 410 allow all from any to any

 # We cut all unnecessary to be entered in the log
 $cmd 999 deny log all from any to any

in rc.conf change firewall_type = “open” to firewall_script = “/etc/rules” and apply the rules of the script:

 nohup sh /etc/rules

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.