HAVP - HTTP AntiVirus Proxy


Ecrit en octobre 2005 par DENIS Kevin -- kevin (arobase) alinto (point) com
  1. Introduction

    Dans cet article, nous allons étudier la mise en place d'un proxy http antivirus: HAVP (http://www.server-side.de). Chacune des pages web demandée par un client est analysée par un antivirus. L'antivirus peut être au choix clamav, F-prot ou Kaspersky. De plus, HAVP sait parfaitement travailler avec squid au cas où vous souhaitez continuer de l'utiliser.
    Nous verrons premièrement comment installer l'antivirus utilisé par HAVP. Deuxièmement, comment installer HAVP et les modifications à effectuer pour le faire fonctionner. Enfin, nous verrons des exemples de configuration d'HAVP:
    1) seul
    2) seul en proxy transparent
    3) et les deux moyens différents de l'utiliser conjointement avec squid.

  2. Installation d'un antivirus, d'HAVP et sa mise en place

      Avant d'installer havp, il vous faut un antivirus fonctionnel sur votre système. Je vais expliquer succintement comment en installer un, tout en privilégiant clamav dans la suite de la documentation.

    1. Antivirus

      1. clamav

        Clamav est un antivirus à signature, disponible en GPL. Les sources et la documentation de clamav se téléchargent sur le site http://www.clamav.net. A l'heure ou j'écris cet article, la dernière version est la 0.86.2 . Si vous le recompilez pour la première fois, il faut ajouter l'utilisateur unix "clamav"

        # groupadd clamav
        # useradd -g clamav -s /bin/false -c "Clam AntiVirus" clamav
        #
        
        Puis en tant qu'utilisateur
        $ tar zxvf clamav-0.86.2.tar.gz
        $ cd clamav-0.86.2
        $ ./configure && make
        $ su
        # make install
        
        Pour plus de précisions sur les détails d'installation, reportez vous à la documentation incluse dans le paquetage.
        Si votre distribution linux est la debian lancez les deux commandes
        # apt-get install clamav
        # apt-get install clamav-daemon
        
        qui installeront clamav et freshclam (nous reviendrons à cet outil en fin de paragraphe).

      2. F-prot

        F-prot est un antivirus disponible gratuitement pour un usage personnel. Il vous faut néanmoins une version corporate (payante) pour l'utiliser avec havp. Des versions d'évaluation sur le site web http://www.f-prot.com sont disponibles.
        Récupérez fp-linux-ms.trial.tar.gz et installez-le. Vérifiez la présence du daemon f-prot (f-protd). Lisez la documentation associée.

      3. Kaspersky

        Kaspersky est un antivirus commercial, payant dans tous les cas de figures. Il est possible de télécharger une version d'évaluation sur http://www.kaspersky.com. Pour le tester, récupérez la dernière version disponible, installez-la et lisez la documentation associée.

      Quel que soit l'antivirus utilisé, il est nécessaire de se procurer les dernières mises à jour en permanence. Chaque antivirus vient avec un outil automatique pour récupérer les dernières signatures et moteurs antivirus:

      • freshclam pour clamav.
      • check-updates.pl pour f-prot.
      • kavupdater pour kaspersky.
      Dès l'installation de votre antivirus, lancez une mise à jour pour vous assurer du bon fonctionnement du mécanisme d'update.

      Reportez vous ensuite à la documentation de votre antivirus pour tester son efficacité sur un virus. Pour ce faire, vous pouvez télécharger un faux virus sur http://www.eicar.com qui vous permettra de vérifier son bon fonctionnement.

    2. HAVP

      HAVP se télécharge sur http://www.server-side.de. Le projet évolue très vite, il est préférable de toujours télécharger la dernière version. C'est un programme conçu pour à l'origine pour linux mais il existe des patchs pour le faire fonctionner sur solaris et freeBSD.

      1. Compilation

        Même si votre distribution vous propose une version packagée, je vous conseille de prendre les sources et de le recompiler vous même. L'exercice n'est pas trop difficile et vous bénéficierez des dernières corrections de bugs et de fonctionnalités. En ce moment, il sort une nouvelle version tous les 15 jours environ.
        Attention à la recompilation: depuis la version 0.72, HAVP supporte les antivirus clamav, f-prot et Kaspersky. La sélection de l'antivirus se fait avec un paramètre donné au script ./configure:

        • clamav:
          ./configure --with-scanner=libclamav (--autres options)
        • f-prot:
          ./configure --with-scanner=fprot (--autres options)
        • Kaspersky:
          ./configure --with-scanner=aveclient (--autres options)
        J'utiliserai clamav et toutes les autres options par défaut:
        $ tar zxvf havp-0.72.tar.gz
        $ cd havp-0.72
        $ ./configure --with-scanner=libclamav
        $ make
        $ su
        # make install
        
        Vous ne devez avoir aucune erreur lors de l'éxécution de ces commandes. Vérifiez la présence du binaire havp sous /usr/local/sbin/havp et des fichiers de configuration sous /usr/local/etc/havp/ (si vous avez choisi des chemins différents lors du ./configure, ajustez les)

      2. Ajustements du système

        HAVP a besoin pour fonctionner d'une partition montée en "mandatory locking". (pour plus de détails sur le mandatory locking, vous pouvez lire man 8 mount et man 2 fcntl). Il vous faut une partition de libre, montée avec l'option -o mand. Cette partition écrira temporairement tous les fichiers à scanner. Il est donc recommandé d'utiliser le filesystem le plus rapide possible en terme de création/destruction de fichiers. Resiserfs ou ext2 semblent être les plus adaptés. ext3 est pénalisé par les écritures du journal. On peut utiliser les options "-o noatime,async" afin de ne pas positionner la valeur atime sur les fichiers et d'être asynchrone: les fichiers ne sont pas écrits immédiatement sur le disque, mais sont conservés en cache. Lorsque le fichier est petit, il est scanné et supprimé rapidement, donc le disque n'a effectué aucune opération lente comme l'écriture ou la suppression.
        Deuxième point: Quelle taille donner à cette partition? La réponse dépendra de l'utilisation faite d'HAVP. Quelle allouer a HAVP pour effectuer ses scans? La majorité des fichiers webs seront très petits (des pages html pesant quelques ko) et certains peuvent être très gros (par exemple archives tgz ~Mo, images iso: ~700Mo). Dans cet article, je ne scanne pas de fichiers plus gros que 10Mo et je considère que trois utilisateurs maximum téléchargent simultanément au plus 10Mo. Une partition de 30Mo me sera donc suffisante pour ces tests. Nous verrons plus loin la variable MAXSCANSIZE et les fichiers whitelist et blacklist qui permettent une sélection plus fine des fichiers à mémoriser.
        Dans le cadre d'une utilisation plus intensive, lorsque HAVP manque de place sur sa partition le chargement échoue et la page affiche une erreur.

        Si vous disposez d'une partition hda42 de libre, utilisez les commandes suivantes:

        # mke2fs /dev/hda42
        (..snip..)
        # mkdir /var/tmp/havp
        # mount -t ext2 -o mand,async,noatime /dev/hda42 /var/tmp/havp
        #
        
        Si vous n'avez pas une partition de disponible, il est possible d'utiliser un fichier monté en loopback. Attention cependant; les performances d'un fichier monté en loopback sont plus faibles qu'un vrai disque dur. Par exemple pour disposer d'un pseudo-disque de 30Mo:
        # mkdir /var/tmp/havp
        # dd if=/dev/zero of=/tmp/disk30M bs=1024k count=30
        30+0 enregistrements lus.
        30+0 enregistrements écrits.
        # mke2fs /tmp/disk30M
        mke2fs 1.35 (28-Feb-2004)
        /tmp/disk30M is not a block special device.
        Proceed anyway? (y,n) y
        (...snip...)
        # mount -t ext2 -o loop,mand,noatime,async /tmp/disk30M /var/tmp/havp
        #
        
        Si vous recherchez les performances et que vous disposez de beaucoup de RAM, vous pouvez utiliser un ram-disque ou le tmpfs. Contrairement au ramfs qui peut avoir le défaut de grossir indéfiniment, le tmpfs s'ajuste par défaut à la moitié de la RAM et n'augmente pas plus. Il est possible d'ajuster au vol sa taille maximale (voir la documentation /usr/src/linux/Documentation/filesystems/tmpfs.txt):
        # mkdir /var/tmp/havp
        # mount -t ramfs -o mand,noatime,async /dev/ram0 /var/tmp/havp
        #
        Ou:
        # mkdir /var/tmp/havp
        # mount -t tmpfs -o mand,noatime,async /dev/shm /var/tmp/havp
        #
        
        Au finale, donnez dans tous les cas les droits d'écriture à l'utilisateur nobody et au groupe nogroup:
        # chown -R nobody.nogroup /var/tmp/havp
        

        L'utilisateur unix qui possède les droits du programme havp sera "nobody" et de groupe "nogroup". Il faut lui donner les droits sur certains fichiers afin qu'il puisse écrire dedans. Il faut créer un fichier pour enregistrer son PID, et un répertoire ou ranger ses logs:

        # touch /var/run/havp.pid
        # chown nobody.nogroup /var/run/havp.pid
        # mkdir /var/log/havp
        # chown nobody.nogroup /var/log/havp
        #
        
        Si votre distribution linux nettoie à chaque démarrage le répertoire /var/run pensez à recréer et redonner le fichier /var/run/havp.pid à nobody.nogroup . HAVP peut fonctionner quand même sans ce fichier, mais il est recommandé de le garder pour faire fonctionner le script init.d/havp.

  3. Fonctionnement

      Avant de démarrer HAVP, configurez selon vos besoins ce logiciel. Nous verrons en premier lieu comment le faire fonctionner seul, puis conjointement avec squid.

    1. Configuration en stand-alone

      1. havp.config

        Le fichier de configuration principal se situe sous /usr/local/etc/havp et s'appelle havp.config. Il est abondamment commenté. Seules les options les plus importantes vont attirer notre attention.

        • USER et GROUP sont l'uid et le gid sous laquelle tourne HAVP (par défaut: nobody.nogroup). HAVP n'a aucunement besoin des droits root. Vous pouvez lui donner l'uid de clamav ou de tout autre utilisateur du système (par exemple squid). Vous pouvez également créer un utilisateur et un groupe dédié. Pensez à corriger les droits en fonction (log, pid, partition, voir le chapitre précédent). Pour le développement je garderai nobody.nogroup .
        • PIDFILE /var/run/havp.pid est le fichier qui contient le pid d'HAVP. Utile pour le script /etc/init.d/havp. Il doit être en rw pour l'utilisateur sous lequel tourne HAVP.
        • SERVERNUMBER 4 représente le nombre initial de serveur lancés en parallèle. Dans mon exemple, 4 est suffisant. Adaptez à votre cas réél.
        • ACCESSLOG /var/log/havp/access.log et ERRORLOG /var/log/havp/havp.log logueront les accès à HAVP, et les logs généraux internes à HAVP (et pas seulement les erreurs contrairement à ce que le nom de variable laisse imaginer!). Ces deux fichiers doivent être en droits rw pour l'utilisateur sous lequel tourne HAVP.
        • SCANTEMPFILE /var/tmp/havp/havp-XXXXXX est comme son nom l'indique, le nom des fichiers temporaires scannés par HAVP. Ces fichiers doivent résider sur une partition montée avec l'option -o mand (voir plus haut). L'uid sous lequel tourne HAVP doit avoir les droits dans ce répertoire.
        • DBRELOAD 60 : HAVP recharge la base virale de clamav toutes les x minutes (ici toutes les heures, donc). Il est possible d'indiquer 0, dans ce cas il faut envoyer un SIGHUP au démon HAVP pour qu'il recharge la base.
        • PORT 8080 est le port sous lequel écoute havp (par défaut 8080). Utilisez un port de libre (faites attention de ne pas rentrer en conflit avec un autre programme serveur installé sur votre système).
        • BIND_ADDRESS NULL : Si vous disposez de plusieurs interfaces réseaux, il est possible d'astreindre havp a n'écouter que sur l'une d'entre elles.
          NULL signifie toutes les interfaces du système
          127.0.0.1 n'écoutera que sur la carte lo
          une adresse spécifique n'écoutera que sur cette adresse.
        • TEMPLATEPATH /usr/local/etc/havp/templates/fr est le chemin qui indique la localisation des messages d'erreur. La version 0.72 propose de, en, es, fr, it, nl, pf. Je choisis fr/ (J'en ai fait la traduction, autant l'utiliser)
        • WHITELIST /usr/local/etc/havp/whitelist et BLACKLIST /usr/local/etc/havp/blacklist : les URL de la WHITELIST sont automatiquement acceptés sans scan; les URL de la BLACKLIST provoquent un refus automatique.
        • MAXSCANSIZE 10000000 représente la taille maximale des fichiers en octets qu'HAVP va scanner. Lorsque l'analyse antivirus est négative passée cette taille, les fichiers sont considérés sains et renvoyés au client. Cela signifie donc que seuls les "MAXSCANSIZE" premiers octets du fichier seront scannés. Cela signifie que si vous téléchargez un zip et qu'un virus est présent au delà de cette taille, il ne sera pas scanné! Si vous indiquez 0, tous les fichiers seront scannés intégralement peu importe leur taille, mais alors attention à la taille de la partition /var/tmp/havp! (imaginez que trois utilisateurs peuvent télécharger chacun une image iso de distribution linux) Je me fixe arbitrairement pour ce test ~10Mo.
        Il reste d'autres options, je vous invite à lire le fichier de config qui est commenté. Pour les utilisateurs de f-prot, il faut renseigner les valeurs de FPROTSERVER et FPROTPORT. Pour les utilisateurs de Kaspersky, il faut utiliser AVECLIENT et AVESOCKET.

      2. Les fichiers WHITELIST et BLACKLIST

        Whitelist
        Ce fichier est rangé sous /usr/local/etc/havp/ et s'appelle whitelist (si vous suivez ma configuration donnée en exemple, voir chapitre précedent).
        Si une URL demandée correspond à une URL de la whitelist, elle est automatiquement envoyée au client sans être scannée. Pour HAVP une URL est constituée d'un domaine et d'un chemin: domaine/chemin. Des wildcards peuvent être placées au début d'un domaine, ou au début ou à la fin d'un chemin.
        Prenons des exemples:

        • www.server-side.de : cette URL seule est whitelistée
        • www.server-side.de/* : le domaine entier est whitelistée
        • */*.gif : tous les gifs de tous les domaines sont whitelistés
        • *sourceforge.net/*clamav-* : les téléchargements de base de virus de clamav sont whitelistés. Je vous conseille de mettre cette ligne dans la whitelist. Ainsi, havp ne bloquera pas les mises-à-jour de clamav.
        Blacklist
        Ce fichier est rangé à /usr/local/etc/havp/blacklist et fonctionne exactement de la même manière, sauf qu'au lieu d'autoriser la page sans la scanner, il renvoie vers une page d'erreur (sans même scanner). Pour tout le reste, voir le paragraphe sur la whitelist.

        Le fichier blacklist prendra toujours la priorité sur le fichier whitelist dans le cas ou une URL apparaît dans les deux fichiers.

      3. Démarrage en mode normal

        Lancez en root havp avec en paramètre son fichier de configuration:

        # havp -c /usr/local/etc/havp/havp.conf
        Starting Havp Version: 0.72
        #
        
        Il est possible, une fois HAVP lancé, de connaître les paramètres de configuration utilisés à l'aide du switch -s:
        # havp -c /usr/local/etc/havp/havp.config -s
        # HAVP uses these configuration parameters:
        ACCESSLOG=/var/log/havp/access.log
        (..snip..)
        #
        
        havp lancé, un ps ax doit vous le montrer, un netstat -na doit afficher (entre autre) le port 8080 en LISTEN.
        Lancez un navigateur web, paramétrez-le pour qu'il utilise un proxy sur l'adresse IP de la machine sur laquelle tourne havp (en local 127.0.0.1) et de port 8080. Connectez vous sur internet, allez sur http://www.eicar.com et testez votre antivirus (lien: The AntiVirus testfile eicar.com). Vous devez avoir le message d'alerte HAVP. Les logfiles d'HAVP doivent montrer un accès de l'IP 127.0.0.1 si vous êtes en local ou de l'adresse IP du client qui a réalisé le test.
        Arrivé à ce point, vous pouvez tester toutes les autres configurations de cet article. Si cette configuration ne fonctionne pas, inutile d'en essayer une autre avant que celle ci ne soit fonctionnelle.

      4. Fonctionnement en proxy transparent

        Plutôt que de devoir modifier chacune des machines de votre LAN afin de leur faire prendre en compte le proxy HAVP, il est possible de faire en sorte que votre firewall redirige de manière transparente les requêtes HTTP vers HAVP au lieu de les laisser sortir. Pour cela il faut ajouter à votre havp.config:

        • TRANSPARENT true
        De plus, il faut ajouter une règle iptables pour rediriger le flux vers votre proxy. Cette exemple considèrera que la patte interne de votre firewall/proxy est eth0, que havp écoute sur le port 8080, sur la même machine que le firewall:
        # iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
        
        Ainsi les flux sortant sont reroutés vers HAVP, et filtrés. Vos clients ne peuvent pas sortir en direct.
        Désactivez tous les proxys de votre navigateur, dirigez vous sur la page de test d'eicar.com et le virus devrait être bloqué.

        Si votre firewall n'est pas la même machine que celle sur laquelle tourne HAVP, il faut ajouter plusieurs règles supplémentaires. Nous allons utiliser pour cela des règles avancées de routage réseau. Il vous faudra les outils fournis dans le paquet iproute2.
        La machine sur laquelle tourne havp s'appelle (havp) (à remplacer par son adresse IP). La carte interne du firewall est eth0. Les commandes à utiliser sur le firewall sont les suivantes:

        # iptables -t mangle -A PREROUTING -j ACCEPT -p tcp --dport 80 -s (havp) 
        # iptables -t mangle -A PREROUTING -j MARK --set-mark 3 -p tcp --dport 80 
        # ip rule add fwmark 3 table 2 
        # ip route add default via (havp) dev eth0 table 2 
        
        Premièrement, les paquets en destination du port 80 (web) provenant de la machine (havp) sont acceptés. Deuxièmement, nous marquons les autres paquets des autres machines. Ensuite nous indiquons à ces paquets marqués d'utiliser la table 2. Et cette table 2 indique que ces paquets sont routés vers la machine (havp).
        Pour que la transparence soit complète, il faut que les paquets originaires d'havp soient bien retransmis. Sur la machine (havp), il faut ajouter:
        # iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080
        
        De cette manière il est possible de séparer physiquement le firewall du proxy antivirus, tout en conservant un comportement transparent.
        Pour plus d'informations sur le fonctionnement d'un proxy transparent, vous avez le Transparent-Proxy-mini-HOWTO, traduit en français par exemple ici: http://www.ibiblio.org/pub/Linux/docs/HOWTO/translations/fr/html-1page/TransparentProxy.html

    2. Fonctionnement avec SQUID

      Squid est un serveur proxy d'une grande souplesse de configuration. http://www.squid-cache.org Je considère pour la suite des paragraphes que votre squid est correctement paramétré. Il est possible de chaîner havp et squid afin d'avoir simultanément un proxy antivirus et la possibilité de conserver squid. Il existe deux manières de faire, utiliser havp qui va demander les pages à squid qui réalisera la requête, ou bien squid qui demandera à havp les pages web.

      1. HAVP avec squid en proxy parent: client --> HAVP --> squid

        Il s'agit de la configuration la plus simple à mettre en oeuvre. Dans le havp.config, il faut ajouter l'adresse du proxy parent et le port sur lequel il écoute. Si havp et squid sont sur la même machine, et que squid écoute sur le port 3128 (port par défaut de squid), nous aurons:

        • PARENTPROXY localhost
        • PARENTPORT 3128
        Lancez squid, puis havp, faites pointer votre navigateur sur le proxy havp. HAVP demande la page à squid et la scanne.
        Cette méthode présente un inconvénient. Toutes les requêtes enregistrées par squid ont comme IP source l'IP de la machine havp puisque la requête est faite par HAVP! Donc aucun contrôle d'accès fait par squid n'est possible de cette manière.

      2. Squid avec HAVP en proxy parent: client --> squid --> HAVP

        Il existe une deuxième méthode pour chainer les proxys. Nous allons demander à squid d'interroger havp pour tous les downloads HTTP. Concrètement cela revient à ajouter à la configuration de squid:

        # Le "cache_peer" qui est en fait le proxy havp
        cache_peer havp parent 8080 0 no-query no-digest no-netdb-exchange
        # Les ACL mises en jeu
        acl Scan_HTTP proto HTTP
        never_direct allow Scan_HTTP
        # Le HTTP doit être demandé au cache_peer havp
        cache_peer_access havp deny !Scan_HTTP
        cache_peer_access havp allow Scan_HTTP
        
        Cette deuxième méthode permet de continuer d'utiliser squid en frontal, aves ses autorisations et ses ACL. Par contre, les logs d'HAVP montreront uniquement des requêtes provenant de la machine squid. A vous d'adapter en fonction de vos souhaits: les logs d'havp vous affichant quand, quels virus et quelle machine (son IP) a failli se faire infecter ou profiter de la finesse de configuration de squid.

    3. Automatisation au démarrage

      Le programme havp est fourni avec un script havp sous etc/init.d/ . C'est le script de démarrage du démon:

      $ /etc/init.d/havp help  
      Usage: /etc/init.d/havp {start|stop|status|restart|force-reload|reload|reload-lists}
      
      Par ce script vous pouvez automatiser facilement le démarrage d'havp au boot de votre machine. Inspirez vous de vos appels aux scripts contenus dans les différents runlevels. Par exemple, sur une slackware, il faudra ajouter dans le /etc/rc.d/rc.inet2:
      if [ -x /etc/init.d/havp ]; then
        echo "Demarrage du proxy antivirus HAVP"
        /etc/init.d/havp start
      fi
      
      Si vous ne savez pas à quel runlevel ni à quel moment le lancer, regardez quand et où est démarré squid. Mettez HAVP au même niveau.
      Si vous utilisez havp en proxy transparent, ajoutez les règles iptables (et ip route) dans les scripts de démarrage de votre système.

  4. Conclusion


Merci d'avoir lu cet article jusqu'au bout, j'espère qu'il vous a interessé.