Ostatnia aktualizacja 2009.03.27.

Witam

Umieściłem tu opis instalacji i konfiguracji transparentnego Squida 3.0 na GNU/Linuksie w połączeniu z dansguardianem i clamavem.
Chcemy osiągnąć
  • szybkie i bezpieczne (ochrona antywirusowa) przeglądanie www
  • bez pornografii
  • ale za to permanentną inwigilacją użytkowników.
  • I jeszcze użytkownik nic nie musi konfigurować po swojej stronie (transparentność).

    Mała uwaga (TODO). W zasadzie bez problemu dało się wstrzyknąć do squida spreparowane pakiety SNMP i wywalić go przez to, że źle wywoływał alokację malloc(). W wersji tej, którą opisuję taka iniekcja nie działa, ale muszę o tym poczytać jeszcze.

    Bardzo ważne. Ten dokument jest w trakcie edycji (przechodzę z wersji 2.6 na 3.0) - chcę sie pobawić ICAPem. Czyli część dokumentu może pasować do 2.6 część do 3.0 itp itd. Na pewno nie da się postawić squida ctrl-c ctrl-v korzystając z tego dokumentu.

    Download:
  • SQUID 3.0stable13
  • Clamav 0.95
  • DansGuardian Stable 2.8.0.6 + Antivirus plugin stable 6.4.4.2
  • Dansguardian 2.10.0.3
  • A Library for Posting Electronic Mail
  • Blacklista i pharselista



    Squid to najlepszy w galaktyce program cacheujący, filtrujący (ACL) i kontrolujący przepływ (DELAY POOLS).
    Program ten jest darmowy - oparty jest na licencji GPL. Aby osiągnąć jednak wydajność porównywalną z komercyjnymi rozwiązaniami niezbędny jest jego dość mocne podstrojenie.
    Większość błędów w konfigurowaniu i uruchamianiu squida wynika z totalnego niezrozumienia zasad jego działania - traktowania go jak jakiejś rury co z jednej strony coś wlata a z drugiej wylata. Tymczasem jest to program nasłuchujący na porcie i mający adres IP. No i oczywiscie na wlocie i na wylocie może być więcej rur. BTW: mówię o routingu wielobramowym i kilku podsieciach po stronie LAN routera.
    CLAMAV jest GPL antywirusem.
    DansGuardian jest filtem filtrującym pornografię, przemoc etc na stronach www.

    Przy opisywanej poniżej instalacji należy zwrócić uwagę aby squid, clamav i dansquardian chodziły w tej samej grupie i userze.
    Używam slacka 12 ze swaretem, ale dla różnych dystrybucji katalogi poszczególnych bibliotek mogą się rożnić.
    Clamav jest przekonfigurowany (w sensie over-, a nie pre- tzn jest wkonfigurowanych wnim za dużo opcji), aby w przyszłości mógł współpracować z MTA.
    Interface eth1 to karta lan rutera 10.10.10.1/24

    Aha i jeszcze sprawa konwencji: znak hasz (#) może oznaczać bądź to komentarz (w pliku), lub polecenie wykoywane z prawami roota w linii poleceń. W linii poleceń znak ($) mówi nam, że polecenie wykonywane jest z prawami normalnego usera.
    ################################# libesmtp #################################
    $ cd /usr/src/libesmtp-1.0.4
    # ./configure
    # make
    # make install
    # ldconfig
    #  
    ################################# clamav   #################################
    $ cd /usr/src/clamav-0.91.2
    $ ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var \
    --with-user=nobody --with-group=nogroup
    # make
    # make install
    # touch /var/log/freshclam.log
    # touch /var/log/clamd.log
    # chown nobody.nogroup /var/log/freshclam.log
    # chown nobody.nogroup /var/log/clamd.log
    
    Zmiana /etc/freshclam.conf
    	# Example
    	UpdateLogFile /var/log/freshclam.log
    
    Zmiana /etc/clamd.conf
    	# Example
    	User nobody
    	LogFile /var/log/clamd.log
    	LogFileMaxSize 0
    	ScanMail Yes
    	FixStaleSocket Yes
    
    # freshclam -d -c 3
    # echo "freshclam -d -c 3" >> /etc/rc.d/rc.local 
    
    Sprawdzanie czy bangla nam clamav (w tym celu na dysk wgramy TESTOWY wirus):
    $ echo 'X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*' > ~/wir.txt
    $ clamscan ~/*
    	./aaa.cf: OK
    	./wir.txt: Eicar-Test-Signature FOUND
    
    ################################# dansguardian #############################
    $ cd /usr/src/dansguardian-2.8.0.6-antivirus-6.4.4.2
    # ./configure --with-av-engine=clamdscan --cgidir=/usr/local/apache/htdocs/dans/www/ \
    --runas_usr=nobody --runas_grp=nogroup
    $ make
    # make install
    $ make clean
    
    Zmiany w /etc/dansguardian/dansguardian.conf
    language = 'polish'
    # LAN rutera, mozna podac tylko jedno IP
    filterip = 10.10.10.1
    # Port dansguardiana
    filterport = 3128
    # Namiary na squida
    proxyip = 10.10.10.1
    proxyport = 8080
    # Metoda identyfikacji użytkownika
    usernameidmethodproxyauth=off
    # Info tylko dla postmastera
    notify = 2
    emaildomain = 'mail.server.tld'
    postmaster = 'postmaster@server.tld'
    
    Balcklistę rozpakowywujemy do /etc/dandguardian/blacklists/
    Balcklistę rozpakowywujemy do /etc/dandguardian/phraselists/
    W standardowej instalacji DG jest bardzo agresywny, IMHO należy mimo wszystko troche odblokować. Przykładowo
    1. plik /etc/dansguardian/bannedphraselist to lista wyrażeń, których znalezienie na stronie sugeruje treści niedozwolone. Radziłbym na przykład zahaszować linie .Include</etc/dansguardian/phraselists/gambling/banned> odpowiadajacą za winiki totolotka (zakazane słowo lotto).
    2. plik /etc/dansguardian/bannedextensionlist zawiera listę rozszerzeń, których użytkownik nie może pobierać. Ustawienie difoltowe powoduje, iż użytkownik nie może pobrać w zasadzie niczego. Analogicznie warto zainteresować się plikiem /etc/dansguardian/bannedmimetypelist.
    3. Z blacklistami jest juz troszkę większy problem. Spróbuj przeszukać na http://urlblacklist.com/?sec=search frazy onet.pl - zobaczysz ile znajdziesz domen :)
      Blacklista podzielona jest na poszczególne kategorie - ich opis znajduje sie w pliku /etc/dansguardian/blacklists/CATEGORIES.
      Abu uaktywnić którąś z kategorii odhaszowywujemy odpowiednie wpisy z plików /etc/dansguardian/bannedsitelist i /etc/dansguardian/bannedurllist.
      Przyładowo odznaczenie:
      • mail, webmail - spowoduje, iż nasi userzy nie będą mogli używać poczty przez www
      • sports, sportnews - spowoduje, iż nasi userzy nie będą mogli poczytać wiadomości sportowych
      • adult - spowoduje, iż nasi userzy nie będą mogli pooglądać rozebranych Pań. Będą natomiast mogli oglądać stony z pornografią
      • dating - wyłączenie serwisów randkowych
      • violence - wyłączenie serwisów propagujących przemoc
      Wszystkich kategorii jest 60.
    4. W pliku /etc/dansguardian/dansguardianf1.conf znajduje się parametr naughtynesslimit ustawiamy go na 50 dla małych dzieci, 100 dla starszych dzieci, 160 dla młodzieży.
    ################################# squid ####################################
    # cd /usr/src/squid-3.0.STABLE13
    # ./configure --enable-storeio="diskd,ufs,null"  \
    --enable-linux-netfilter \
    --enable-underscores \
    --enable-removal-policies="heap,lru" \
    --enable-http-violations \
    --with-openssl \
    --with-dl  \
    --with-pthreads \
    --enable-large-files \
    --enable-err-language=Polish --enable-default-err-language=Polish \
    --enable-delay-pools \
    --with-pthreads \
    --disable-ident-lookups \
    --disable-internal-dns\
    --disable-carp \
    --disable-icmp \
    --disable-wccp \
    --disable-htcp \
    --enable-jestem-userem-ktory-nic-nie-czyta-tylko-kopiuje-bez-zastanowienia \
    --disable-snmp \
    --enable-kill-parent-hack \
    --enable-time-hack \
    --enable-forw-via-db \
    --disable-cache-digests \
    --enable-large-files \
    --disable-internal-dns \
    --enable-http-violations
    
    # make
    # make install
    
    Zmiany w /usr/local/squid/etc/squid.conf (Superważne i wymagające ingerencji użytkownika paramerty zaznaczono na niebiesko, parametry, które sugerowałbym zmienić, lub o nich chociaż pogooglować zaznaczyłem na czarno, natomiast mało użyteczne i nie wpływające marginalnie na osiągi squida na biało. Opis wszystkich parametrów można pobrać stąd.
    # NETWORK OPTIONS
    # -----------------------------------------------------------------------------
    # Port na którym squid nasłuchuje i transparentność
    http_port 8080 transparent
    
    # OPTIONS WHICH AFFECT THE CACHE SIZE
    # -----------------------------------------------------------------------------
    # Należy pamiętać iż to nie jest cała pamięć użyta przez squida
    # Tu jest ustawienie dla mnie, a mam 1024 MB. 
    # cache_mem = (RAM - linux - apache - mysql - MTA - userzy - etc) / 3
    cache_mem 194 MB
    
    # Informacje na jakim poziomie zapełnienia ma pracować dyskowy cache
    # Przy 80% demon powinien zacząć się martwić jego wymianą (low) lub agresywnie wziąć się do roboty (high) 
    # przy pełnym zapełnieniu cache.
    cache_swap_low 80%
    cache_swap_high 100%
    
    # LFUDA ma hit rate mniejszy, a byte hit o kilkanaście procent większy od GDSF.
    # Zatem ustawiamy politykę LFUDA dla dysku (optymalizacja dla byte hit ratio) 
    # i GDSF dla pamięci (zatrzymuje w cache niewielkie często używane obiekty).
    # Jeśli używamy polityki LFUDA dla dysku poniższy parametr należy zwiększyć,
    # w celu zmaksymalizowania byte hit.
    maximum_object_size 32768 KB
    # Poniżej tej wartości obiekty NIE są zachowywane na dysku.
    minimum_object_size 0 KB
    maximum_object_size_in_memory 128 KB
    ipcache_size 16384
    fqdncache_size 0
    cache_replacement_policy heap LFUDA
    memory_replacement_policy heap GDSF
    
    
    # LOGFILE PATHNAMES AND CACHE DIRECTORIES
    # -----------------------------------------------------------------------------
    # Chce mieć 6GB cache (mam na dysku 16GB wolnego)
    # Liczba środkowa w parametrze cache_dir to liczba katalogów pierwszego poziomu.
    # Wyliczamy ją dzieląc miejsce przeznaczone na cache przez średnią wielkość obiektu, 
    # a nastepnie wynik jeszcze raz dzielimy przez 32. Przykładowo:
    # Liczba katalogów pierwszego poziomu = (6144 / (16 * 32))
    cache_dir ufs /usr/local/squid/var/cache 6144 12 256
    # Logi (Permanentna inwigilacja + wyłączenie logów niepotrzebnych ani mi, ani squidowi).
    # Wyłączenie logowania wpływa na wydajność systemu.
    cache_log /dev/null
    cache_store_log none
    
    # OPTIONS FOR EXTERNAL SUPPORT PROGRAMS
    # -----------------------------------------------------------------------------
    dns_nameservers 10.10.10.1
    
    
    # OPTIONS FOR TUNING THE CACHE
    # -----------------------------------------------------------------------------
    # Reguły odświeżania. Parametry po kolei
    # 1. Url
    # 2. Minimalny wiek obiektu w minutach
    # 3. Maksymalny stosunek wieku obiektu do czasu od ostatniej modyfikacji
    # 4. Maksymalny wiek obiektu w minutach
    # Proponuję usunąć linijkę z uporem maniaka lansowaną w necie ^gopher: 1440 0% 1440.
    # Znasz kogoś kto używa świstaka w XXI w?
    # Kolejne linijki były skuteczne w 2005 roku. Odkąd Microsoft wprowadził ograniczenia
    # dla niezarejestrowanych kopii ruch zmalał 200 krotnie :)
    refresh_pattern -i \.(gif|jpg|jpeg|png|html|bmp)   0   50%    7200 reload-into-ims
    refresh_pattern -i \.(zip|gz|bz2|exe|rar|mp3|mpg|avi|wmv|vqf|ogg)   43200 100%    43200   reload-into-ims
    refresh_pattern windowsupdate.com/.*\.(cab|exe|dll)     43200    100% 43200   reload-into-ims
    refresh_pattern download.microsoft.com/.*\.(cab|exe|dll) 43200   100% 43200   reload-into-ims
    refresh_pattern au.download.windowsupdate.com/.*\.(cab|exe|dll) 43200 100% 43200 reload-into-ims
    refresh_pattern symantecliveupdate.com/.*\.(zip|exe)    43200    100% 43200   reload-into-ims
    refresh_pattern windowsupdate.com/.*\.(cab|exe)         43200   100% 43200   reload-into-ims
    refresh_pattern download.microsoft.com/.*\.(cab|exe)    43200   100%	43200   reload-into-ims
    refresh_pattern avast.com/.*\.(vpu|vpaa)    43200   100%    43200	reload-into-ims
    refresh_pattern .               0       20%     4320
    
    # TIMEOUTS
    # -----------------------------------------------------------------------------
    half_closed_clients off
    
    # ACCESS CONTROLS
    # -----------------------------------------------------------------------------
    # maxconn - maksymalna ilość jednoczesnych połączeń z jednego adresu,
    # aby zadziałało nie zmieniać difoltu dla client_db
    acl siec src 10.10.10.0/255.255.255.0
    acl ZA-DUZO maxconn 50
    http_access deny ZA-DUZO siec
    follow_x_forwarded_for allow siec
    http_access allow siec
    
    # ADMINISTRATIVE PARAMETERS
    # -----------------------------------------------------------------------------
    visible_hostname server.firma.tld
    
    # MISCELLANEOUS
    # -----------------------------------------------------------------------------
    # Anonimowość dla użytkownikow za natem - squid ustawia w nagłówku HTTP/1.1 
    # pole 'X-Forwarded-For: unknown' zamiast 'X-Forwarded-For: 10.10.10.171'. 
    # Więcej o tym: http://www.squid-cache.org/Doc/FAQ/FAQ-4.html#ss4.18
    forwarded_for off
    # Wyłączenie logowania zapytań ICP z innych serwerów web cache
    log_icp_queries off
    store_avg_object_size 16 KB
    store_objects_per_bucket 36
    # Włączenie buforowania dla logów zapisywanych przy pomocy funkcji stdio (cache_log)
    buffered_logs on
    reload_into_ims on
    acl FTP proto FTP
    always_direct allow FTP
    
    # Fake, aby logi serwerów www pokazywały coś na kształt:
    # 61.82.164.18 - - [26/May/2006:00:29:21 +0200] "GET /index.txt HTTP/1.0" 200 1867 "http://www.tescik.tld/" 
    # "Nutscrape/1.0 (CP/M; 8-bit)"
    # Info od Jażyn: Z tym fejkiem są problemy z logowaniem do niektórych serwisów:
    # poczta.wp.pl, czy czat na WP.
    header_access User-Agent deny all
    header_replace User-Agent Nutscrape/1.0 (CP/M; 8-bit)
    
    strip_query_terms off
    
    # mkdir /usr/local/squid/var/cache
    # chown nobody.nogroup /usr/local/squid/var/* -R
    # /usr/local/squid/sbin/squid -z
    # /usr/local/squid/sbin/squid -D -YC
    # echo "/usr/local/squid/sbin/squid -D -YC" >> /etc/rc.d/rc.local 
    # dansguardian start
    # echo "dansguardian start" >> /etc/rc.d/rc.local 
    # clamd
    # echo "clamd" >> /etc/rc.d/rc.local 
    
    Ustawienia netfiltra
    Hosty 10.10.10.123 oraz 10.10.10.127 poddane są działaniu dansguardiana i clamava:
    # iptables -A INPUT -i eth1 -p tcp --src 10.10.10.0/24 --dport 8080 -m state --state NEW -j ACCEPT
    # iptables -A INPUT -i eth1 -p tcp --src 10.10.10.123 --dport 3128 -m state --state NEW -j ACCEPT
    # iptables -A INPUT -i eth1 -p tcp --src 10.10.10.127 --dport 3128 -m state --state NEW -j ACCEPT
    # iptables -A PREROUTING -t nat -p tcp -s 10.10.10.123 -d ! 10.10.10.0/24 --dport 80 -j DNAT \
    --to-destination 10.10.10.1:3128
    # iptables -A PREROUTING -t nat -p tcp -s 10.10.10.127 -d ! 10.10.10.0/24 --dport 80 -j DNAT \
    --to-destination 10.10.10.1:3128
    # iptables -A PREROUTING -t nat -p tcp -s 10.10.10.0/24 -d ! 10.10.10.0/24 --dport 80 -j DNAT \
    --to-destination 10.10.10.1:8080
    
    Nic nie szkodzi oczywiście aby używać konstrukcji typu:
    # iptables -t filter -I OUTPUT -d 10.10.10.1 -p tcp --dport 3128  -m owner ! --uid-owner dansguardian -j DROP
    

    Przykładowe działanie:

    Zabronione www.wiesniaczki.pl



    BONUS 1:
  • ZPH TOS - markowanie w sależności od trafienia dla późniejszego kolejkowania. Następnie w squid.conf umieszczamy
    # Ustawienie bitu TOS dla poszczególnych pakietów
    zph_tos_local 8 
    zph_tos_peer 0 
    zph_tos_parent off
    
    a następnie filtrujemy po bicie TOS



    BONUS 2: Jeśli posiadasz ruting wielobramowy (czyli przykładowo DSL i polpaka) ciekawym podejściem wydaje się aby puścić cały ruch WWW poprzez łącze DSL, a pozostały przez łącze symetryczne. W tym celu działamy w sposób następujący (bash konieczne prawa roota):
    # Przy routingu wielobramowym wykrywam oczywiste oszustwa,
    # w ten sposób że rp_filter daje 1.
    # Przy wielu bramach zatem:
    echo "0" > /proc/sys/net/ipv4/conf/all/rp_filter
    
    EXTDEV="eth0"		# Interface połączony do polpaka
    EXTDEV2="eth2"		# Interface połączony do DSL
    INTDEV="eth1"		# LAN
    
    GATE="62.87.182.117"    # Gateway pierwszego lacza
    GATE2="84.40.251.1"     # Gateway drugiego lacza
    
    EXTIP="62.87.182.118"   # IP pierwszego lacza (daj "ip a s dev $EXTDEV | grep inet" aby się upewnić)
    EXTIP2="84.40.251.75"   # IP drugiego lacza
    
    P_NET="62.87.182.118/30" # Sieć pierwsze łącze
    P2_NET="84.40.211/24"    # Sieć drugie łącze
    INTNET="10/8"		 # LAN 
    
    # Tworzymy trasy do bramy i dodajemy trasę domyślną przez tą bramę
    ip ro a $P_NET dev $EXTDEV src $EXTIP table polpak
    ip ro a $P2_NET dev $EXTDEV2 src $EXTIP2 table dsl
    ip ro a $P_NET dev $EXTDEV src $EXTIP
    ip ro a $P2_NET dev $EXTDEV2 src $EXTIP2
    
    ip ro a default via $GATE table polpak
    ip ro a default via $GATE2 table dsl
    
    # Któredy co ma chodzić
    ip ru a from $EXTIP table polpak
    ip ru a from $EXTIP2 table dsl
    
    # Trasa domyślna wiedzie przez polpak
    ip ro d default
    ip ro a default via $GATE
    
    # 127.0.0.1...
    ip ro a $INTNET     dev $INTDEV table polpak
    ip ro a $P2_NET     dev $EXTDEV2 table polpak
    ip ro a 127.0.0.0/8 dev lo   table polpak
    ip ro a $INTNET     dev $INTDEV table dsl
    ip ro a $P_NET      dev $EXTDEV table dsl
    ip ro a 127.0.0.0/8 dev lo   table dsl
    
    ip ro f table cache
    
    W pliku /etc/iproute2/rt_tables dodajemy
    201     dsl
    202     polpak
    
    W /usr/local/squid/etc/squid.conf dodajemy iż squid ma pracować na łaczu niesymetrycznym.
    tcp_outgoing_address 84.40.251.75 siec 
    udp_outgoing_address 84.40.251.75 siec
    
    i restartujemy squida
    /usr/local/squid/sbin/squid -k reconfigure
    
    Poniżej przedstawiam jednodniowe statystyki dla takiego połączenia (robione w tym samym czasie). Dramatis personae to mały serwer podłączonych 70 osób, sieć radiowa, w nocy prędkość zwiększana trzykrotnie w stosunku do nominalnej.

    Łącze symetryczne 2MB
    Łącze asymetryczne 1MB/512kB

    Troszkę inną bajkę mamy przy dwóch łączach symetrycznych. Chorobą byłoby użycie powyższej metody. Zastosuj LB.
    Jeśli nie poradzisz sobie z LB to można prosto przy pomocy squida puścić część ruchu jedną a część drugą bramą:
    acl SIEC1 src 10.10.11.0/24
    http_access allow SIEC1
    tcp_outgoing_address 212.241.71.120 SIEC1
    
    acl SIEC2 src 10.10.10.0/24
    http_access allow SIEC2
    tcp_outgoing_address 80.50.243.71  SIEC2
    



    TODO (stan na luty 2007):