Trying to find a use for an old HP integrity RX2600 (with 4 Gb of RAM though), i decided to configure it as a proxy server for my network. It's quite hard to find any use for these machines, since there's only a short availability of software on windows (no exchange,iis,sql - at least as far as i searched). They were supposed to run HPUX but i don't think that anyone wants to fuck around with this OS.
So, my environment was the following
- HP inegrity rx2600 with CentOS 4.7 ia64 already installed (ask me for help on this - mybe i'll record my experience in another post) with 2 network cards : eth0 for LAN interface and eth1 for internet. Happened to have two 36Gb SCSI disks disposable, one for the system (sda) and the other for proxy functions (mounted to a directory /squid_cache)
- Windows Server 2003 Active directory environment with two DNSs and DCs.
REQUIREMENTS:
1. The proxy machine should incorporate firewall capabilities. Although my network is already protected by a hardware firewall, it's always a good idea to provide the maximum security and also monitor user's activities.
2. Internet connectivity (http only in particular) for all registered users in domain.
3. Exclusion of non-domain PCs from internet access. Hey that's really important! I do not want everyone plugging his/her laptop, PDA etc, copying the network settings and connecting to my corporate network and browsing the www. After a research i made there were 2 ways to accomplish this. Either through domain isolation with ipsec or with the way i propose (proxy authentication). I have to admit that ipsec domain isolation is a more solid implementation protected by strong security, unsurpassed by my users, mostly led by simple curiosity. On the contrary, it introduces some overhead to my already slow network and obsolete users' PCs and most of all
THERE IS NO FUCKING WAY to implement domain isolation in linux. And i mean complete domain isolation on a network interface, not just host-to-host communication over ipsec! Anyway,after all, it's just internet, not my secure internal network!
4. Users should bypass proxy when using outlook and ftp. Just a simple firewall rule, but really important to me.
5. As much open-source as possible. All above requirements (ESPECIALLY DOMAIN ISOLATION) are met bi ISA server, but as i mentioned, there is no ISA for IA64 architecture and even if existed, it costs money! Moreover, there is a trend in my corporation to move to open-source solutions in the immediate future.
STEPS
Preperation was really easy on CentOS. Samba, ntp and winbind are already installed and working even in my old version (4.7), but updated them just in case. In an ubuntu experiment i tried before centos i had to install samba, samba-common, winbind, krb5-workstation and ntp. In any case, you have to make CentOS box join the windows domain first.
- Start with ntp because Kerberos algorithms used on Active Directory require time synchronization of machines. All you have to do is:
-make sure ntpd is on: chkconfig ntpd on
-stop iptables firewal temporarily : service iptables stop
-add your domain controllers to /etc/ntp.conf: echo "server <domain controller ip> " >> /etc/ntp.conf
- make an initial tyme synchronization : ntpdate <DC ipadress>
- edit /etc/ntp.conf to remove any other server lines you do not want. Inside a Kerberos realm, what is really important is that all computers have the same time, not necessarily correct!
For any questions, there are numerous references, like this one : CentOS / Red Hat Configure an NTP Client And Server
- Configure Samba and Winbind. Edit /etc/krb5.conf like my example. My domain here is mits.local and my domain controllers are mits-root and mits-root-02:
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = MITS.LOCAL
dns_lookup_realm = false
dns_lookup_kdc = false
[realms]
MITS.LOCAL = {
kdc = mits-root.mits.local
kdc = mits-root-02.mits.local
admin_server = mits-root.mits.local
default_domain = mits.local
}
[domain_realm]
.mits.local = MITS.LOCAL
mits.local = MITS.LOCAL
[kdc]
profile = /var/kerberos/krb5kdc/kdc.conf
[appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
}
- Same way, this is my /etc/samba/smb.conf
[global]
workgroup = server string = Samba Server Version %v
log file = /var/log/samba/%m.log
max log size = 50
security = ADS
passdb backend = tdbsam
realm = MITS.LOCAL
password server = mits-root.mits.local
idmap uid = 16777216-33554431
idmap gid = 16777216-33554431
template shell = /bin/false
winbind enum users = yes
winbind enum groups = yes
encrypt passwords = yes
winbind use default domain = yes
obey pam restrictions = yes
- Now you have to add an A record to your DNS server with the FQDN of your proxy machine, in my case integrity.mits.local. Also edit /etc/resolv conf and add your DNS server there. Verify with nslookup.
- Finally it is time to join the machine to the domain. First, ensure Kerberos connectivity by typing:
kinit administrator
You are then asked for password and if eferything is OK you receive no further info (in my case though, there is a message for new mail, but has nothing to do with what we're doing). After this, you have to type
net ads join -u administrator
or in case of problem
net ads join -u administrator -S <your PDC emulator>
You should receive a message that your computer has joined the domain and also see your computer name listed in AD Users and Computers. Maybe not necessary, but i reboot at this point. After reboot, check connectivity:
wbinfo -t
should give you:
checking the trust secret via RPC call succeded
and wbinfo -g -u
should list your domain users and groups.
- Now you download latest squid source and language pack and extract them to the same directory. You follow installation without any surprises for missing libs BUT be carefull to run configure with ./configure –enable-storeio=aufs option. Aufs filesystem adds a considerable performance gain to the installation.=. Refer to this excellent article for further info on ufs vs aufs: Free Proxies Blog. The site suggests COSS vs aufs, but in my version of squid (3.1) is not yet stable. Finally, make sure that language pack is extracted at the same position as the source files. In other case refer to language pack documentation. For my colleagues who're not familiar with building from source, cd to the downloaded extracted directory, type :
./configure –enable-storeio=aufs
make
make install
- At this point you have squid ready. Now, you edit your squid.conf file located at /usr/local/squid/etc/squid.conf. Having read many tutorials and opinions (a good one here http://blog.last.fm/2007/08/30/squid-optimization-guide) and taking into account my system configuration, i ended up with the following squid.conf file:
http_port 192.168.48.100:3128
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1 c
cache_mgr noc@mits.gr
cache_effective_user squid
cache_effective_group squid
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
#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
http_access deny CONNECT !SSL_ports
# Leave coredumps in the first cache dir
coredump_dir /usr/local/squid/var/cache
# Add any of your own refresh_pattern entries above these.
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
access_log /usr/local/squid/var/logs/
access.log
icp_port 3130
icp_access deny all
htcp_access deny all
cache_mem 2048 MB
maximum_object_size_in_memory 12 MB
#Using my 36 GB disk mounted at /squid_cache for caching
cache_dir aufs /squid_cache 23000 16 256
minimum_object_size 0 KB
maximum_object_size 25 MB
cache_swap_low 96
cache_swap_high 98
cache_replacement_policy LFUDA
hierarchy_stoplist cgi-bin ?
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
acl my_net src 192.168.48.0/21
http_access deny !my_net
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 230 startup=0 idle=1
auth_param ntlm keep_alive on
acl ntlm proxy_auth REQUIRED
log_access allow all
#BLOCKED SITES
acl blocked_sites dstdomain '/usr/local/squid/etc/blocked_sites.list'
#deny_info BLOCKED_SITE blocked_sites
http_access deny blocked_sites
#########################################
#BLOCKED MIME TYPES
#acl mimeblockq rep_mime_type -i "/usr/local/squid/blocked_mimes.list"
#deny_info BLOCKED_MIMETYPE mimeblockq
#http_reply_access deny mimeblockq
#########################################
#BLOCK EXECUTABLES
acl exe-filter urlpath_regex -i \.(cmd|exe|bat)($|\??
deny_info BLOCKED_MIMETYPE mimeblockq
http_reply_access deny mimeblockq
#ONLY FOR MITS.LOCAL
acl mitsdomain srcdomain .mits.local
http_access deny !mitsdomain
deny_info PC_NOT_IN_DOMAIN mitsdomain
########################################
http_access allow ntlm
http_access deny all
For all choices there is good documentation. I will only add that i have not yet implemented blocked mime types yet (have to check my organization's rules first) and just block downloading of executables. Also, i need two extra files, blocked_sites.txt, where i put blocked domains preceded by a dot (.), eg .facebook.com and blocked_mimes.list, where i plan to put blocked mime types (to block my users from downloading not allowed content - it is interesting to google how to block also streaming). Finally, the rule for blocking non-domain pcs is not recommended by squid manual because it's a slow one. For each request, it queries the reverse zone of your DNS to see if ip corresponds to registered computer. Note that you have to configure a reverse zone in your DNS!
You may have noticed that i commented deny_info lines. I did so because this was causing some strange problems with client PCs running windows xp! I'm working on it and update when i end up with a solution.
- Now we need some tweaking. In some configurations, after reboot your users won't be able to authenticate, wbinfo not working and squid give you NT_STATUS_ACCESS_DENIED. The reason for this is that squid process does not have read access to the winbind pipe: /var/cache/samba/winbind_privileged. Here you either run squid as root (through cache_cache_effective_user directive in squid_conf), or by creating a squid user and giving him access to winbind_privileged. As you may have noticed, i prefer the last option. Create a user squid and make him member of squid group:
groupadd squid
useradd -g squid squid
Make him the owner of the chache direcory
chown -R squid:squid /squid_cache
Make him the owner of winbind pipe:
chown squid:squid /var/cache/samba/winbind_privileged
ATTENTION: This last command will cause winbind to fail in case you restart samba/winbind because it does not like not to be the owner of winbind_privileged. I have not yet found a straightforward way to adress this issue. Also, after reboot, the owner changes back to root, obviously at some early point of startup process. What i do is to add the previous lines in a startup script presented in step 100
- Now it's time to configure firewall. As i mentioned at the beginning, the requirements here are to allow only ssh and squid entering my machine. Also, there are some services (mail, ntp ftp) which i do not want to control and forward them. Finally, for some administrative tasks, there are also some ip's bypassing the firewall through NAT. So here is my iptables script:
#! /bin/csh -f
echo " Proxy firewall configuration script"
echo " Allows http traffic to SQUID PORT 3128"
echo "Detecting network interfaces "
set LAN = eth0
set INTERNET = eth1
echo LAN = $LAN
echo INTERNET = $INTERNET
echo "###############################################################"
echo " Configuring firewall for SQUID and mail services "
echo " Allowing NAT for the following ports:"
echo "# 110 -> POP3"
echo "# 25 -> SMTP"
echo "# 20 -> FTP"
echo "# 21 -> FTP control"
echo "# 53 -> DNS (UDP)"
echo "# 22 -> SSH"
echo "# 123 -> NTP"
echo "# If you eant to enable NAT for additional ports, have a look into"
echo "# firewall.exe at the corresponding <iptables> lines "
echo "####################################################################"
#############################################################################
# KERNEL CONFIGURATION
#############################################################################
# Drop ICMP echo-request messages sent to broadcast or multicast addresses
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts
# Drop source routed packets
echo 0 > /proc/sys/net/ipv4/conf/all/accept_source_route
# Don't accept ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/accept_redirects
# Don't send ICMP redirect messages
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
# Enable source address spoofing protection
echo 1 > /proc/sys/net/ipv4/conf/all/rp_filter
# Don't log packets with impossible source addresses
echo 1 > /proc/sys/net/ipv4/conf/all/log_martians
# Enable packet forwarding
echo 1 > /proc/sys/net/ipv4/ip_forward
# Enable TCP SYN cookie protection from SYN floods
echo 1 > /proc/sys/net/ipv4/tcp_syncookies
#####################################################################################################################
#####################################################################################################################
# FIREWALL CONFIG
#####################################################################################################################
#####################################################################################################################
#Clear and reset firewall
iptables -F
iptables -X
#Allow loopback calls
iptables -A INPUT -i lo -j ACCEPT
#####################################################################################################################
## FILTER TABLES
#####################################################################################################################
#Allow previously established tcp connections on internet interface ($INTERNET)-allow only incoming tcp initiated by us
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
#Drop non-conformant and suspicious (SYNC-FLOOD) traffic
iptables -A INPUT -m state --state INVALID -j DROP
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j LOG
iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Allow incoming traffic on intranet interface to the following ports :
# 3128 -> Squid listens here
iptables -A INPUT -p tcp -i $LAN --dport 3128 -j ACCEPT
iptables -A INPUT -p tcp -i $LAN --dport 22 -j ACCEPT
iptables -A INPUT -p tcp -i $LAN --sport 22 -j ACCEPT
#####################################################################################################################
## NAT TABLES
#####################################################################################################################
# Masquerade
# 110 -> POP3
# 25 -> SMTP
# 20 -> FTP
# 21 -> FTP control
# 53 -> DNS (UDP)
# 22 -> SSH
# 123 -> NTP
########SOS IPS without proxy start
## 192.168.48.3-4 : friend
## 192.168.48.5 : me
## 192.168.48.7 : boss
iptables -A FORWARD -i $LAN -s 192.168.48.3 -j ACCEPT
iptables -A FORWARD -i $LAN -s 192.168.48.4 -j ACCEPT
iptables -A FORWARD -i $LAN -s 192.168.48.5 -j ACCEPT
iptables -A FORWARD -i $LAN -s 192.168.48.7 -j ACCEPT
iptables -A FORWARD -i $LAN -s 192.168.50.3 -j ACCEPT
iptables -A FORWARD -i $LAN -s 192.168.50.8 -j ACCEPT iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.48.3 -j ACCEPT
iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.48.4 -j ACCEPT
iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.48.5 -j ACCEPT
iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.48.7 -j ACCEPT
iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.50.3 -j ACCEPT
iptables -A FORWARD -i $INTERNET -o $LAN -d 192.168.50.8 -j ACCEPT
########SOS IPS without proxy end
iptables -A FORWARD -p tcp -i $LAN --dport 110 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 110 -j ACCEPT
iptables -A FORWARD -p tcp -i $LAN --dport 25 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 25 -j ACCEPT
iptables -A FORWARD -p udp -i $LAN --dport 53 -j ACCEPT
iptables -A FORWARD -p udp -i $INTERNET --sport 53 -j ACCEPT
iptables -A FORWARD -p tcp -i $LAN --dport 20 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 20 -j ACCEPT
iptables -A FORWARD -p udp -i $LAN --dport 20 -j ACCEPT
iptables -A FORWARD -p udp -i $INTERNET --sport 20 -j ACCEPT
iptables -A FORWARD -p tcp -i $LAN --dport 21 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 21 -j ACCEPT
iptables -A FORWARD -p tcp -i $LAN --dport 22 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 22 -j ACCEPT
iptables -A FORWARD -p tcp -i $LAN --dport 123 -j ACCEPT
iptables -A FORWARD -p tcp -i $INTERNET --sport 123 -j ACCEPT
# iptables -t filter -A FORWARD -j LOG --log-level debug
iptables -P FORWARD DROP
iptables -t nat -X
iptables -t nat -F
iptables -t nat -A POSTROUTING -o $INTERNET -j MASQUERADE
########################################################################################################################
#Allow outgoing
iptables -P OUTPUT ACCEPT
########################################################################################################################
#Drop all other incoming traffic
iptables -P INPUT DROP
echo " DONE!"
##################################################################################################################
# STARTING SQUID#
##################################################################################################################
# Step 1 : take ownership of winbind pipe
chown root:root /var/cache/samba/winbindd_privileged
service winbind restart
service smb restart
chown squid:squid /var/cache/samba/winbindd_privileged
# Activating squid
/usr/local/squid/sbin/squid -N &
###################################################################################################################
- As you can see in the previous script, i have added a couple of lines to resolve winbindd_privileged problem and start squid. All is needed now is to add my script to /etc/rc.d/rc.local and init 6!
11. For further customization of the installation (ie when you don't want just a "ninja" solution), you can provide custom error messages by editing error pages located at /usr/local/squid/share/errors/templates