IT-Service GmbH 


rigel.ulm.go-itservice.de

IBM Thinkpad X41 mit Debian 7.0 Wheezy als Firewall und Proxyserver

Linux installieren

Mit Debian Wheezy 7.0 CD booten.
	Language:	German<enter>
		...	
	Rechnername:	rigel
	IP:		192.168.80.1
Passwort root ..., User: dummy, Kein echter User nötig, diese werden von dem alten Rechner übernommen. Partitionieren (ist eine kleine 16GB SSD):
	Festplatte:	manuell
	15,0 GB	sda1	ext3  /	(formatieren, bootflag)
	 1,0 GB	sda2	swap
Grundsystem wird installiert ...
	Spiegel:	ja
	Server:		ftp.uni-erlangen.de
	Proxy:		<leer>
Bei Debian Software Auswahl folgende Aufgaben angeben:
    Umgebungen: Webserver,ssh,laptop,system
Folgende zusäzliche Pakete und die unter Wheezy für php und perl angegebenen mit aptitude auswählen:
	bind9
	catdoc (wegen xls2csv)
	cryptsetup
	debconf-utils
	dos2unix
	hdparm
	imagemagix
	iptables
	hostapd
	ldap-utils
	lynx
	mcrypt	
	mysql-client (= mysql-client-5.5 + mysql-common)
	mysql-server  (= mysql-server-5.5 + mysql-common)
	ntpdate
	+ perlmodule  (unter nicht-installiert -> perl, siehe Allgemeines zu "Wheezy")
	+ php5 (inclusive diverser Module siehe Allgemeines zu "Wheezy")
	phpldapadmin
	phpmyadmin
	rsh-redone-client
	rsync
	samba
	slapd
	squid
	squidguard
	ssh
	xcftools
Nach der Installation Passwörter für mysql, ldap ec. eingeben.

Grundkonfiguration

Damit der neue Rechner sich wie der alte verhält, werden die Hostkeys, das /root-Verzeichnis und /usr/local/bin vom alten Rechner rigel geholt.
/root/.ssh
/root/
/etc/ssh/ssh_host_dsa_key
/etc/ssh/ssh_host_dsa_key.pub
/etc/ssh/ssh_host_rsa_key
/etc/ssh/ssh_host_rsa_key.pub
/usr/local/bin/
Dateien anpassen. Bei passwd, shadow und group geht das am besten so:
# cp passwd passwd.ORG
# cat /OLD/etc/passwd >> passwd
Alte Einträge ausser den echten Usern löschen. Dateien zum Anpassen:
/etc/passwd
/etc/shadow
/etc/group
/etc/idmapd.conf
/etc/profile	(nur wegen export EDITOR=vi)
/etc/init.d/obi1
/etc/sudoers	(kopieren)
/etc/ssh/sshd_config
/etc/samba/smb.conf
/etc/bind/		(Dateien vom alten Server kopieren, named.conf.local, named.conf.options anpassen)
/etc/resolv.conf
/etc/hosts
/etc/network/interfaces
/root/fwstart	(netzwerkinterfaces)
/root/fwmask	(netzwerkinterfaces)

Startdatei in rc.n

bereits in squeeze wurde die Reihenfolge der Bootskripte auf abhänigkeitsgesteuerte Bootskripte geändert. Diese sind komplizierter aufgebaut und nüssen ihre Abhängigkeiten und "start","stop" Zweige enthalten. Ist das Startskript, im Beispiel /etc/init.d/obi1 fertig, wird es in den Bootablauf eingebunden. Hierzu wird im Verzeichnis /etc/init.d folgendes Kommando ausgeführt:
# update-rc.d obi1 defaults

bind 9

unter rigel.squeeze sind die Konfigurationsdateien des alten Servers rigel
# cp /rigel.squeeze/etc/bind/ulm* /etc/bind/
# cp /rigel.squeeze/etc/bind/named.conf.local /etc/bind/
in etc/bind/named.conf.options forwarder eintragen

sshd

Damit de Zugang von aussen von Netzen aus möglich ist, bei denen eine (Firmen)Firewall den Internetzugang via ssh auf Port 22 verhindert, lauscht der sshd auch auf Port 563, das ist der Port für "secure News". Dazu muß in der /etc/ssh/sshd_config nur eine weitere Port Zeile eingetragen werden. Port 443 (https) wäre noch besser, der ist fast überall frei, allerdings läuft der Apache auch auf Port 443, so daß diese Option nicht möglich ist:
Port 22
Port 563

Apache2

sites (nur einzelne virtual Host Abschitte) in /etc/apache2/sites-available anlegen und dann einen link aus /etc/apache2/sites-enabled auf das Konfigfile anlegen. Die Webseiten selbst liegen auf dem Fileserver sgrx1 unter /home/go/SITE und werden via nfs gemountet

mysql Datenbanken anlegen:

Als root an der Datenbank anmelden, dann sukzessive die einzelnen Datenbanken nebst GRANTS anlegen (z.B. myulm):
> CREATE DATABASE mygoitservice DEFAULT CHARACTER SET latin1 COLLATE latin1_german1_ci;
> GRANT ALL PRIVILEGES ON mygoitservice.* TO USER@localhost IDENTIFIED BY 'PASSWD';
am alten Server wurden die Daten mit
# mysqldump -uUSER -pPASSWD mygoitservice > /root/mygoitservice.sql
exportiert. Jetzt am neuen einspielen:
# mysql -uUSER -pPASSWD mygoitservice < /rigel.squeeze/root/mygoitservice.sql

Proxy squid (2.6) und Zusatz squidguard installieren

Von blinkenden Werbebannern und anderen lässtigen "Ads" genervt, wollte ich diese loswerden. Meine Wahl fiel auf die Kombination squid mit squidguard, was gut funktioniert und recht leicht zu installieren ist. Schritte:
squid installieren
squidguard installieren, beide via aptitude
Die Weiterleitung Squid => squidguard einrichten oder anpassen, diese steht in der letzten Zeile der /etc/squid/squid.conf
url_rewrite_programm /usr/bin/squidGuard -c /etc/squid/squidGuard.conf
Achtung, unter squeeze (squid 2.5) lautete diese Direktive redirect_program also nicht einfach kopieren!
die IP-Adressen:Ports, auf denen squid lauschen soll, werden ebenfalls eingetragen:
http_port 192.168.70.10:3128
http_port 192.168.70.10:8080
http_port 192.168.80.1:3128
http_port 192.168.80.1:8080

Die shallalist Regeldaten holen von http://www.shallalist.de/Downloads/shallalist.tar.gz
Dieses Datei verschieben nach /var/lib/squidguard/db/. Es wird davon ausgegangen das squid unter dem User proxy läuft. Die Shallaliste liegt im Unterverzeichnis /var/lib/squidguard/db/BL
# cd /var/lib/squidguard/db/
# gunzip shallalist.tar.gz
# tar -xvf shallalist.tar
# chown -R proxy:proxy BL
# /etc/init.d/squid restart
# tail -F /var/log/squid/blocked.log
Die Konfigdateien fuer SquidGuard ist hier als /etc/squid/squidGuard.conf festgelegt
In der /etc/squid/squidGuard.conf verwende ich im ersten Abschnitt das voreingestellte Thema "adv" für Werbung, "tracker" für Webverfolgung und ein optional ein drittes, eigendefiniertes namens "obi". Beim Anlegen der eigenen Regel müssen in dem entsprechenden Unterverzeichnis, im Beispiel /var/lib/squidguard/db/BL/obi die entsprechenden Dateien liegen. Sonst funktioniert der squidguard nicht und läßt jeden Traffic zu.
Jetzt lossurfen mit rigel als Proxy. Auf den meisten Mainstreamwebseiten tauchen sofort Einträge in der blocked.log auf. Weiterer Vorteil der Werbeausblendung: Surfen ist merklich schneller und die CPU Auslastung durch den Browser oft wesentlich niedriger. Auf Clientseite habe ich im iceweasle noscript installiert. Damit hat man auch vor anderem Traffic Ruhe.
Wenn nach dem Neustart von squidguard unter Debian wheezy oder jessie die Fehlermeldung "This account is currently not available" kommt, kann man in der /etc/passwd /bin/bash als shell für den User proxy, unterdem squidguard läuft, eintragen. Squidguard konfigurieren mit
dpkg --configure squidguard

Rechner als Software Accespoint

mit dem via USB angeschlossenem WLAN Adapter auf Basis des Atheros 9k kann problemlos ein WLAN Accesspoint aufgesetzt werden. Dazu wird der hostapd installiert und folgende Datei /etc/hostapd/hostapd.conf angelegt:
interface=wlan0
driver=nl80211
ssid=sirona
wme_enabled=0
channel=6
hw_mode=g

auth_algs=1
wpa=3
wpa_passphrase=MYPRESHAREDKEY
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP
rsn_pairwise=CCMP
vorher habe ich das Gerät wlan0 in der /etc/network/interfaces eingetragen mußte es aber trotzdem mit ifconfig initialisieren:
ifconfig wlan0 192.168.81.1 netmask 255.255.255.0
Weiter geht es bei der Konfiguration des Clients mira

Rechner als Gateway und Firewall mit IP-Tables

Der Rechner steht Firewall/Proxy/Gateway zwischen den Transfernetz (192.168.70.0 an /dev/eth1) des Routers (192.168.70.1) und dem internen Netz (192.168.80.0, an /dev/eth0). Da der X41 nur eine Ethernet Schnittstelle hat, verwende ich eine alte 3Com PCMCIA Karte als zweite.
. Zur Anbindung des WLANs wird ein USB WLAN-Adapter (192.168.81.0, an /dev/wlan0) auf Basis des Atheros 9k Chipsatzes verwendet, da dieser als Softwareaccesspoint arbeiten kann. Als Gateway und Firewall verwende ich ein aus verschiedenen Quellen zusammengebautes Shellskript. Das Skript ist hier im Anhang und wird beim Booten ausgeführt

BIOS Update

Beim Booten des Rechners bleibt dieser wegen der nicht zugelassenen SSD beim Booten stehen. Mein anderer X41 (polaris) meckert zwar bei der SSD ebenfalls, bootet aber nach ein paar Sekunden. Da ein nach dem Booten ewig auf Tastendruck wartender Server nicht akzeptabel schien, suchte ich im Internet nach einer Lösung. Hier ist sie, der Großteil der Infos stammt von thinkwiki.de/2010_Error_umgehen. Ich musste ausserdem erst eine Ersatzplatte und eine uralte Windows XP CD herauskramen, da das Flashen des Controllers und des BIOS nur unter Windows funktioniert. Hier die Anleitung zum Flashen in Kurzform:
Original BIOS Update
Auf dem X41 war BIOS 1.17a, bei Lenovo gibt es die Version 2.09 (Stand 08.05.2013) zum Download. Vor Flashen des Controllers muß das neueste BIOS eingespielt werden. Das von Lenovo geladene BIOS-Update Programm ausführen und den Anweisungen folgen.
Embedded Controller Update
Vor dem Update auf das modifizierte BIOS muß die aktuellste Version des Embedded Controllers installiert werden. Kontrolle auf der Startseite des BIOS mit der letzten Version im Lenovo Downloadbereich. Bei mir war Embedded Controller 1.00 auf dem X41, bei Lenovo 1.02 (Stand 08.05.2013) zum Download. Nach Einspielen des modifizierten BIOS kann kein Embedded Controller Update mehr durchgeführt werden!
NO 2010 BIOS Update
BIOS im Intenet suchen (oder Notfalls eine eMail an mich, Adresse siehe Impressum)
Das BIOS ISO wird auf eine CD gebrannt.
Beim Booten von CD startet der BIOS-Updater automatisch, mit "Y" beginnt der Flashvorgang.
Nach Beendigung des Flash-Vorganges wird eine Warnmeldung ausgegeben, die sinngemäß "BIOS Update fehlgeschlagen" lautet. Dies ist normal und kann ignoriert werden. X41 durch langes Drücken des Power-Schalters ausschalten.
Neu booten und dabei <F1> drücken, um ins BIOS zu gelangen.
Dort im Hauptmenü mittels <F9> Default-Werte laden ("Setup Defaults").
BIOS speichern und verlassen (<F10> "Save and Exit") ohne andere Einstellungen vorzunehmen.
Neu booten, jetzt kann man die BIOS-Einstellungen wieder anpassen.

Skript fwstart

#!/bin/sh
# Firewallscript "fwstart" fuer Router mit 2.4 Kernel
# aus dem Internet zusammengestopselt von
#
# go@guenther-obermaier.de, 2002
# 

EXT_IF=eth1
EXT_IP=192.168.70.10
INT_IF=eth0
INT_IP=192.168.80.1
WLAN_IF=wlan0
WLAN_IP=192.168.81.1
MYNET=192.168.80.0/255.255.255.0
MYWLAN=192.168.81.0/255.255.255.0
ALL=0.0.0.0/0.0.0.0

ICMP_RATE=50/s
ICMP_BURST=50
LOG_RATE=10/h
LOG_BURST=50

echo "Starting Firewall..."
echo 1 > /proc/sys/net/ipv4/ip_forward

#--------------#
# Prep Section #
#--------------#

##
## Temporarily block all traffic until new tables are finished
##

# Set strict filtering defaults to protect while chains are flushed
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP

# Flush Rules
iptables -F
iptables -X 

# Insert temporary blocking rules
iptables -I INPUT 1 -j DROP
iptables -I FORWARD 1 -j DROP
iptables -I OUTPUT 1 -j DROP

#-------------------#
# Filtering Section #
#-------------------#

##
## General Policies for icmp packets
##

# Create new chain
iptables -N icmp-policy

# Allow error icmp messages
iptables -A icmp-policy -p icmp --icmp-type destination-unreachable -j ACCEPT
iptables -A icmp-policy -p icmp --icmp-type source-quench -j ACCEPT
iptables -A icmp-policy -p icmp --icmp-type time-exceeded -j ACCEPT
iptables -A icmp-policy -p icmp --icmp-type parameter-problem -j ACCEPT

# Allow pings _from_ inside and privileged net
iptables -A icmp-policy -i $EXT_IF -p icmp --icmp-type echo-request -j ACCEPT
iptables -A icmp-policy -i $INT_IF -p icmp --icmp-type echo-request -j ACCEPT
iptables -A icmp-policy -i $WLAN_IF -p icmp --icmp-type echo-request -j ACCEPT

# Allow pings _to_ anywhere
iptables -A icmp-policy -p icmp --icmp-type echo-reply -j ACCEPT

##
## General Policies for tcp packets
##
iptables -N tcp-policy

# Log then drop suspicious packets (just one example...)
# iptables -A tcp-policy -p tcp --tcp-flags ALL FIN,URG,PSH -m limit --limit $LOG_RATE --limit-burst $LOG_BURST -j LOG --log-prefix "XMAS scan:" 
iptables -A tcp-policy -p tcp --tcp-flags ALL FIN,URG,PSH -j LOG --log-prefix "XMAS scan:" 
iptables -A tcp-policy -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP

# Allow local traffic on server
iptables -A INPUT -i lo -j ACCEPT

# Allow approved types of icmp, but limited in rate 
# iptables -A INPUT -m limit --limit $ICMP_RATE --limit-burst $ICMP_BURST -p icmp -j icmp-policy
iptables -A INPUT -p icmp -j icmp-policy
# iptables -A OUTPUT -p icmp -j icmp-policy
iptables -A INPUT -p icmp -j DROP

# Screen out malformed tcp packets
iptables -A INPUT -p tcp -j tcp-policy

# Forward packets from internal to external net
iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
iptables -A FORWARD -i $INT_IF -j ACCEPT
iptables -A FORWARD -i $WLAN_IF -j ACCEPT

# Allow new/established outgoing packets
iptables -A OUTPUT -d 127.0.0.1 -j ACCEPT
iptables -A OUTPUT -d $INT_IP -j ACCEPT
iptables -A OUTPUT -d $WLAN_IP -j ACCEPT
iptables -A OUTPUT -o "$EXT_IF" -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o "$INT_IF" -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o "$WLAN_IF" -m state --state NEW,ESTABLISHED -j ACCEPT

# established incoming packets on external network and internal network 
iptables -A INPUT -i "$EXT_IF" -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i "$INT_IF" -m state --state ESTABLISHED -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -m state --state ESTABLISHED -j ACCEPT
# ... forward them
iptables -A FORWARD -i "$EXT_IF" -m state --state ESTABLISHED -j ACCEPT

# Stop Traffic to/from some servers
iptables -A OUTPUT -d 62.109.129.145 	-j DROP # Adserver, nervt 
iptables -A OUTPUT -d 193.28.197.8	-j DROP # Adserver, nervt 

# Forward :81 to LAN-Cam .47:80

iptables -t nat -A PREROUTING -i "$EXT_IF" -p tcp --dport 81 -j DNAT --to 192.168.80.47:80
iptables -A FORWARD -d 192.168.80.47 -i "$EXT_IF" -p tcp --dport 80 -j ACCEPT

# Allow related ICMP packets from external network
iptables -A INPUT -i "$WLAN_IF" -p icmp -m state --state RELATED -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p icmp -m state --state RELATED -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p icmp -m state --state RELATED -j ACCEPT

# Allow some traffic to firewall from extern
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p udp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p udp --dport 123 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 389 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 563 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 3128 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$EXT_IF" -p tcp --dport 7822 -m state --state NEW -j ACCEPT

# Allow some traffic to firewall from WLAN
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p udp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p udp --dport 123 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 389 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 563 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 3128 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$WLAN_IF" -p tcp --dport 7822 -m state --state NEW -j ACCEPT

# Allow some traffic to firewall from intern
iptables -A INPUT -i "$INT_IF" -p tcp --dport 21 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 22 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p udp --dport 53 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 80 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p udp --dport 123 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 389 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 443 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 3128 -m state --state NEW -j ACCEPT
iptables -A INPUT -i "$INT_IF" -p tcp --dport 7822 -m state --state NEW -j ACCEPT

# Anything else is logged at a reasonable rate then dropped
# iptables -A INPUT -i $EXT_IF -m limit --limit $LOG_RATE --limit-burst $LOG_BURST -j LOG --log-prefix "Blocked from external net:" 
# iptables -A INPUT -i $INT_IF -m limit --limit $LOG_RATE --limit-burst $LOG_BURST -j LOG --log-prefix "Blocked from internal net:" 
iptables -A INPUT -j DROP 

#--------------#
# Post Section #
#--------------#

# Mask all outgoing
iptables -t nat -A POSTROUTING -o $EXT_IF -j MASQUERADE

##
## Restore traffic
##

# Restore normal defaults now that rules are finished
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP


# Delete temporary blocking rules
iptables -D INPUT 1
iptables -D FORWARD 1
iptables -D OUTPUT 1

echo ".... ok"

Konfigurationsdatei /etc/squid/squidGuard.conf

#
dbhome /var/lib/squidguard/db/BL
logdir /var/log/squid

dest adv {
	domainlist	adv/domains
	urllist		adv/urls
	redirect 302:http://myulm.go-itservice.com:80/images/pixel_C0C0C0.gif
	log blocked.log
}

dest tracker {
	domainlist	tracker/domains
	urllist		tracker/urls
	redirect 302:http://myulm.go-itservice.com:80/images/pixel_C0C0C0.gif
	log blocked.log
}

#dest obi {
#	domainlist	obi/domains
#	urllist		obi/urls
#	redirect 302:http://myulm.go-itservice.com:80/images/pixel_C0C0C0.gif
#	log blocked.log
#}

acl {
	default {
		pass !adv !tracker all
#		pass !adv !tracker !obi all
	}
}