[Serveur Dédié] Serveur Mail

Introduction

Dans cette article nous allons voir la mise en place d’un serveur mail utilisant OpenSMTPD comme service SMTP et Dovecot en tant que service IMAP ainsi que Roundcube comme webmail.

OpenSMTPD a été vu dans un précédent article.

Dovecot est un service permettant la mise en place de serveur imap ou pop3. Dovecot a été vu sur ce site sur ce lien.

Nous allons présenter la configuration de OpenSMTPD ainsi que celle de Dovecot puis nous détaillerons les modifications qui on été nécessaires au fonctionnement des deux services ainsi que son utilisation d’un point de vue utilisateur via le déploiement de Roundcube sur un serveur web Nginx hébergé  par FreeBSD 9.2. Continuer à lire

OpenBSD 5.5 est sorti

Comme tous les 6 mois une nouvelle version d'OpenBSD est publiée.

OpenBSD est un système d'exploitation orienté sécurité et réseau, dont les principaux avantages sont la stabilité, grâce aux audits sur le code source, mais également l'ensemble très large de fonctionnalités réseau qu'il fournit.

Mises à jour

Améliorations sur l'installeur

L'installeur d'OpenBSD gère désormais l'installation automatisée (autoinstall). Cette installation automatisée permet de déployer ou mettre à jour rapidement OpenBSD par le réseau en spécifiant un fichier de réponses. Ce fichier est distribué via un serveur HTTP dont l'adresse est renseignée dans l'option next-server du DHCP. Cette installation est possible à la fois en installation par le réseau (netboot) et par le CD-ROM.

time_t 64 bits

Le problème actuel de la variable time_t est qu'elle est codée sur 32 bits dans tous les systèmes UNIX. Le 19 janvier 2038 à 3h14 et 7 secondes cette variable atteindra sa valeur limite, causant des problèmes graves, avec la réinitialisation de celle-ci à zéro.

L'équipe d'OpenBSD a fait un énorme travail afin de convertir le type de variables en 64 bits, de corriger tous les programmes inclus dans la distribution et patcher/auditer les différents ports.

Packet Filter

  • Packet Filter inclut désormais un nouveau système de queue afin de gérer la qualité de service.
  • Le paramètre received-on peut désormais prendre pour valeur any afin de correspondre à toutes les interfaces, excepté celles de loopback.
  • La politique de blocage par défaut dans le pf.conf de base est désormais un block return.

Sécurité

  • OpenBSD ne garantissait pas la sécurité par la signature cryptographique des paquets. C'est désormais chose faite, les paquets et la distribution sont désormais signés via l'outil signify.
  • relayd gère désormais la fonction Perfect Forward Secrecy de TLS avec ECDHE (courbe elliptique Diffie-Hellman). Cette option est désormais activée par défaut.
  • Le générateur de nombres aléatoires est désormais initialisé par le bootloader.
  • Le protecteur de la pile du noyau est également initialisé par le bootloader.

Réseau

  • Prise en charge de VxLAN
  • Amélioration de la gestion du déchargement des sommes de contrôles TCP/UDP/ICMP (checksum offload)
  • Activation de la prise en charge de domaines de routage IPv6 (ping6, traceroute6…)
  • tcpdump peut désormais détecter des sommes de contrôle incorrectes sur ICMP et ICMPv6
  • Diverses améliorations sur dhclient et dhcpd.

Performances

  • Les relations entre le cache des tampons et le démon de swap ont été améliorées.

Logiciels

Voici une liste non exhaustive de logiciels inclus dans OpenBSD 5.5

  • Gnome 3.10.2
  • KDE 4.11.5
  • PostgreSQL 9.3.2
  • Postfix 2.11
  • PHP 5.4.24
  • Firefox 26
  • OpenSSH 6.6
  • OpenSMTPd 5.4.2

Pilotes

  • Gestion des cartes réseau virtuelles VMware VMXNET3
  • Gestion des contrôleurs SCSI VMware Paravirtual
  • Gestion des contrôleurs SCSI virtio
  • Gestion des périphériques de nombres aléatoires virtio
  • Gestion des trackpad Broadcom présents dans les Macbook récents
  • KMS gère désormais les sorties DisplayPort
  • Ajout du système de fichiers tmpfs
  • Plusieurs améliorations sur la couche FUSE.

Plateformes matérielles

  • alpha : gestion multi-processeur
  • aviion : gestion des processeurs AViiON
  • armv7 remplace la prise en charge de l'architecture Beagle.

LibreSSL et HeartBleed

Malgré la sortie de cette version 5.5 et le fork de la bibliothèque OpenSSL en LibreSSL, orchestré par l'équipe d'OpenBSD afin de nettoyer et auditer le code d'OpenSSL, le processus de sortie de la version 5.5 n'a pas permis de patcher la faille avant création de la distribution. Il faut ainsi patcher la libssl d'OpenBSD après mise à niveau/installation.

Mettre à jour OpenBSD en 5.5

Pour passer en 5.5, il vous faudra au préalable OpenBSD 5.4. Réalisez ensuite la liste d'actions suivantes:

  • Booter sur le CD d'installation OpenBSD 5.5 (ou en PXE) et sélectionnez upgrade
  • Rebooter
  • Monter le CD d'installation dans le système à jour (mount /dev/cd0a /mnt)
  • Mergez les fichiers de configuration
sysmerge -Ss /mnt/5.5/amd64/etc55.tar.gz
  • Enfin nettoyez le système des fichiers inutiles
rm -f /usr/libexec/identd
rm -f /usr/lib/libcompat.a /usr/lib/libcompat_p.a
rm -f /usr/include/{re_comp,regexp,sgtty,sys/timeb}.h
rm -f /usr/share/man/man3/{re_comp,re_exec,rexec,regexp}.3
rm -f /usr/share/man/man3/{cuserid,ftime,gtty,setrgid,setruid,stty}.3
rm -f /etc/rc.d/popa3d
rm -f /usr/bin/{crunchgen,nawk}
rm -f /usr/sbin/{iopctl,popa3d}
rm -f /usr/share/man/man8/{iopctl,popa3d}.8
rm -rf /usr/X11R6/include/freetype2/freetype
rm -f /usr/X11R6/include/ft2build.h
rm -f /usr/mdec/installboot
rm -f /usr/share/man/man8/{amd64,i386}/installboot.8
rm -f /var/account/acct
rm -f /var/games/tetris.scores

mv /etc/nsd.conf /var/nsd/etc/nsd.conf
cd /usr/sbin && rm nsd-notify nsd-patch nsd-xfer nsd-zonec nsdc
cd /usr/share/man/man8 && rm nsd-notify.8 nsd-patch.8 nsd-xfer.8 \
   nsd-zonec.8 nsdc.8
chown _nsd /var/nsd/db/nsd.db
printf '\nremote-control:\n\tcontrol-enable: yes\n' >> /var/nsd/etc/nsd.conf

Problèmes de login

Après la mise à jour d'OpenBSD, si votre shell est ZSH vous serez déconnecté après authentification. Pour résoudre ce souci, passez en single (tapez boot -s dans le bootloader), montez le / en lecture-écriture, lancez le réseau et mettez à jour zsh

mount -rw /
sh /etc/netstart
export PKG_PATH="http://ftp.openbsd.org/pub/OpenBSD/5.5/packages/amd64/"
pkg_add -u zsh

OpenSMTPD, Premiers pas

Nous utilisons tous des services de messagerie en ligne tel que Gmail, Outlook, Yahoo… Mais si vous vouliez prendre le contrôle de vos mails? comment faire?

Comparons la technologie Exchange de Microsoft avec ses CAL’s et ses licences et son budget ou les technologies open-source comme Sendmail, Postfix ou dans notre cas OpenSMTPD.

OpenSMTPD

Afin d’avoir un service aussi-complet que Gmail il faudra mettre en place plusieurs briques et OpenSMTPD en fait partie. OpenSMTPD est  un service SMTP libre utilisant le-dit protocole comme défini dans la RFC 5321. Il permet d’échanger des e-mails avec d’autres systèmes utilisant ce protocole comme Sendmail, Postfix, etc…

OpenSMTPD est un service « jeune » qui a voulu reprendre la simplicité de compréhension et de configuration du firewall Packet Filter d’OpenBSD. Ce service est implémenté depuis OpenBSD 4.6 dans la branche « unstable » et depuis OpenBSD 5.3 en tant que stable.

Ici nous utilisons la version 5.4.1 d’OpenSMTPD.

Le MAN est la première phase de l’approche pour utiliser ce service, il fournit les premières étapes pour un déploiement propre.

smtpd is not enabled by default.In order to use it as the system
mailer, ensure the mail queue is empty, then stop sendmail(8):

# /etc/rc.d/sendmail stop
Modify the current mailwrapper(8) settings by editing /etc/mailer.conf:
           sendmail        /usr/sbin/smtpctl
           send-mail       /usr/sbin/smtpctl
           mailq           /usr/sbin/smtpctl
           makemap         /usr/libexec/smtpd/makemap
           newaliases      /usr/libexec/smtpd/makemap

Disable the sendmail clientmqueue entry in crontab(1).

Rebuild the aliases database, and enable the daemon:

# newaliases
# echo "sendmail_flags=NO" >> /etc/rc.conf.local
# echo "smtpd_flags=" >> /etc/rc.conf.local
# /etc/rc.d/smtpd start

Maintenant que le paramétrage du service au niveau du système est fait nous allons passer à la configuration du fichier « smtpd.conf ».

listen on all

table aliases db:/etc/mail/aliases.db

# Uncomment the following to accept external mail for domain "example.org"
#
# accept from any for domain "example.org" alias <aliases> deliver to mbox
accept from any for domain "dev.unix-experience.fr" alias <aliases> deliver to maildir
accept for local alias <aliases> deliver to maildir
accept from local for any relay

Le service est à présent configuré, il nous reste à accepter les connexions externes sur le port 25 avec Packet Filter (CF plus loin) et à redémarrer le service smtpd avec la commande /etc/rc.d/smtpd restart.

Pour vérifier votre configuration Opensmtpd comme pour PF il existe la commande smtpd -n.

Pour lancer smtpd en mode debug lancer la commande smtpd -dv.

Configurez maintenant Packet Filter (rappel: fichier /etc/pf.conf)

 pass in proto tcp to self port smtp

Vérifiez maintenant la syntaxe et chargez le jeux de règles:

#Pour verifier la syntaxe 
pfctl -nf /etc/pf.conf

#Pour charger les nouvelles regles
pfctl -f /etc/pf.conf

Pour conclure cette partie, réalisons un test:

telnet dev.unix-experience.fr 25
Connected to dev.unix-experience.fr.
Escape character is '^]'.
220 hermes.my.domain ESMTP OpenSMTPD

Allons un peux plus loin dans notre configuration et renforçons la sécurité:

Chiffrement TLS

#Macro
pki dev.unix-experience.fr certificate "/etc/mail/certs/pcn0.crt"
pki dev.unix-experience.fr key  "/etc/mail/certs/pcn0.key"
##Configuration
listen on pcn0 port 25 tls-require pki dev.unix-experience.fr auth-optional hostname "dev.unix-experience.fr"

Accordons une analyse de cette ligne de configuration du fichier smtpd.conf

listen on pcn0 port 25 : le service écoutera sur l’interface pcn0 sur le port 25 ( si le paramètre « all » est actif, le service écoutera sur toutes les interfaces)

tls-require : Force les clients à établir une connexion sécurisée avant d’être autorisés à dialoguer au SMTP, l’option tls seule peux suffire mais tls-require renforce globalement en forçant les clients à établir une connectrion sécurisé avant d’être autorisé à démarrer une transaction SMTP. Cette option nécessite l’utilisation et la création de certificats.
Il est utile de noter que si nous ne créons qu’un certificat et sa clé et non le CA ainsi que le DH le service utilisera  ces paramètres par défaut.

pki dev.unix-experience.fr Nous spécifions les certificats par l’instruction pki qui nous permet de spécifier l’emplacement du certificat ainsi que de sa clé. « dev.unix-experience.fr » correspond à l’argument hostname comme spécifié dans le man de smtpd.conf.

Ce mécanisme est similaire au macro de Packet filter et doivent donc être déclaré en amont de la configuration

hostname Hermes : permet de spécifier un nom pour la bannière smtpd.

Test d’envoi

Nous allons à présent réaliser un test d’envoi de mail via la commande

mail, en ayant lancé smtpd en mode debug, ainsi nous pourrons comprendre les interactions par les logs.

echo "Ceci est un message de test" |mail -v -s "TEST MAIL" root@localhost
<<< 220 hermes.my.domain ESMTP OpenSMTPD
>>> EHLO localhost
<<< 250-hermes.my.domain Hello localhost [local], pleased to meet you
<<< 250-8BITMIME
<<< 250-ENHANCEDSTATUSCODES
<<< 250-SIZE 36700160
<<< 250 HELP
>>> MAIL FROM: <root@hermes.my.domain>
<<< 250 Ok
>>> RCPT TO: <root@localhost>
<<< 250 Recipient ok
>>> DATA
<<< 354 Enter mail, end with "." on a line by itself
>>> .
<<< 250 e636d771 Message accepted for delivery
>>> QUIT
<<< 221 Bye

Ceci est le détail des interactions qui ont eu lieu pendant la communication avec le serveur SMTP. On y retrouve les champs du destinataire et de l’émetteur.

Si on regarde les logs de plus près, nous pouvons observer que le service est extrêmement verbeux:

smtp-in: New session 000000001f305e85 from host 0@localhost [local]
debug: aliases_get: returned 1 aliases
debug: 0x12ad371d0000: end of message, msgflags=0x0000
smtp-in: Accepted message e636d771 on session 000000001f305e85: from=<root@hermes.my.domain>, to=<root@localhost>, size=245, ndest=1, proto=ESMTP
debug: scheduler: evp:e636d771a30c37cc scheduled (mda)
debug: lka: userinfo <getpwnam>:unixexperience
smtp-in: Closing session 000000001f305e85
debug: mda: new session 000000002962b8f8 for user "unixexperience" evpid e636d771a30c37cc
debug: smtp: 0x12ad371d0000: deleting session: done
debug: mda: no more envelope for "unixexperience"
debug: mda: got message fd 3 for session 000000002962b8f8 evpid e636d771a30c37cc
debug: mda: querying mda fd for session 000000002962b8f8 evpid e636d771a30c37cc
debug: smtpd: forking mda for session 000000002962b8f8: "/home/unixexperience/Maildir" as unixexperience
debug: mda: got mda fd 4 for session 000000002962b8f8 evpid e636d771a30c37cc
debug: mda: end-of-file for session 000000002962b8f8 evpid e636d771a30c37cc
debug: mda: all data sent for session 000000002962b8f8 evpid e636d771a30c37cc
debug: smtpd: mda process done for session 000000002962b8f8: exited okay
delivery: Ok for e636d771a30c37cc: from=<root@hermes.my.domain>, to=<root@localhost>, user=unixexperience, method=maildir, delay=1s, stat=Delivered
debug: mda: session 000000002962b8f8 done
debug: mda: user "unixexperience" becomes runnable
debug: mda: all done for user "unixexperience"

Nous pouvons alors décrire les étapes de réception du mail par dans un premier par le MTA qui à rechercher un alias liant le destinataire (root@localhost), une fois identifié comme l’utilisateur « unixexperience », le MTA transmet le message au MDA interne de opensmtpd en  attribuant alors l' »evpid » que l’on peux interprété comme « enveloppe identifer » au MDA.

Ensuite une session interne s’initialise ou le message va être délivré dans l’emplacement Maildir correspond à l’utilisateur unixexperience.

Configuration d’un relais

Nous pouvons considérer vouloir faire relayer nos mails par notre service SMTP dans le cadre où les ports ou la destination de notre SMTP est bloquée à notre emplacement géographique ou tout simplement pour en faire un relais Nous allons donc ajouter une règle qui relaiera nos mails via GMAIL.

Voici à quoi ressemble notre fichier smtpd.conf:

pki dev.unix-experience.fr certificate "/etc/mail/certs/pcn0.crt"
pki dev.unix-experience.fr key  "/etc/mail/certs/pcn0.key"

listen on pcn0 port 25 tls-require pki dev.unix-experience.fr auth-optional hostname "dev.unix-experience.fr"
listen on pcn0 port 465 smtps pki dev.unix-experience.fr auth-optional  hostname "dev.unix-experience.fr"

table secrets db:/etc/mail/secrets.db
table aliases db:/etc/mail/aliases.db

# Uncomment the following to accept external mail for domain "example.org"http://www.unix-experience.fr/wp-admin/post.php?post=2889&action=edit&message=10
#
# accept from any for domain "example.org" alias <aliases> deliver to mbox
accept from local for any relay via tls+ auth://label@smtp.gmail.com:587 auth <secrets>

Pour arriver à cette configuration nous avons dû réaliser plusieurs actions.

touch "label IDGOOGLE@gmail.com:PASSWD" >> /etc/mail/secrets
makemap /etc/mail/secrets
chmod 640 /etc/mail/secrets* 
chown root:_smtpd /etc/mail/secrets*

Nous avons donc crée un fichier contenant les informations d’identification pour utiliser le relais de google. Ensuite nous avons créé le fichier « secrets.db » qui sera utilisé par smtpd et restreint les permissions sur ce fichier ainsi que son propriétaire et le groupe auxquels il appartient pour que ceux-ci puissent être lisible par le daemon d’OpenSMTPD. Nous avons renseigné ce fichier sous cette forme dans « smtpd.conf ».

table secrets db:/etc/mail/secrets.db

Maintenant la régle du relai:

accept from local for any relay via tls+auth://label@smtp.gmail.com:587 auth <secrets>

accept from local for any  : Nous acceptons les envoie de mail localement pour n’importe quel destination.

relay via tls+auth://label@smtp.gmail.com:587 auth <secrets> : Nous relayons via une authentification TLS en utilisant les information d’authentification correspondant à l’étiquette label sur le smtp de Gmail sur le port 587 en utilisant la table secrets.

Conclusion

Nous reprendrons OpenSMTPD dans un article consacré à la mise en place d’un serveur mail complet avec la technologie de virtualisation libvirt.

Ce qu’il faut retenir de OpenSMTPD:

– Produit en cours de développement- Ajout de nouvelles fonctionnalités dans le futur
– Facilité de compréhension de la configuration

Ce qui est valable aujourd’hui pour son utilisation ne le sera sans doute plus demain.

Source:

Merci à la Mailing List d’OpenSMTPD pour m’avoir éclaircit sur le fonctionnement des étiquettes ainsi qu’une relecture de l’article.

http://www.opensmtpd.org/fr/list.html

http://www.openbsd.org/cgi-bin/man.cgi?query=smtpd&sektion=8

Monter une AP Wi-Fi avec OpenBSD

Suite à un récent achat de matériel afin de me débarrasser de ma livebox qui plante trop souvent, j'ai choisi de faire mon propre routeur ADSL.

Pour faire un routeur, rien ne vaut un OS de qualité: OpenBSD. Au niveau hardware, j'ai choisi une board Alix 2d13 et une carte mini PCI Wi-Fi Atheros DNMA92 et ses antennes.

Nous allons voir dans ce tutoriel comment configurer OpenBSD afin de transformer notre routeur en borne Wi-Fi.

IMG_20131105_203131

Initialisation sur la board

Si vous comptez utiliser une board Alix, voici (rapidement) comment installer OpenBSD et se connecter en série à l'équipement.

Insérez la carte compact flash dans un lecteur compatible (interne ou USB) puis montez le lecteur sur une machine virtuelle en 32bits (i386), en tant que disque dur. (Sur libvirt il suffit de spécifier /dev/sdX comme chemin de disque dur, /dev/sdX étant le lecteur compact flash).

Installez ensuite OpenBSD comme d'habitude, à l'exception près qu'il faudra activer com0 a 38400 baux et ne pas configurer d'interfaces réseau.

Une fois l'installation terminée, éteignez la machine lancez un sync dans votre terminal et retirez la carte compact flash du lecteur. Insérez la ensuite sur la board et alimentez la.

Si tout se passe bien OpenBSD bootera comme sur un serveur classique.

Configuration du réseau

Nous allons ici bridger toutes les interfaces réseau afin de faire fonctionner le système comme un switch.

Configuration Ethernet

La board Alix 2d13 dispose de 3 interfaces Ethernet. Nous aurons uniquement besoin de les allumer.

echo "up" > /etc/netstart vr0echo "up" > /etc/netstart vr1
echo "up" > /etc/netstart vr2
sh /etc/netstart vr0
sh /etc/netstart vr1
sh /etc/netstart vr2

Configuration Wi-Fi

Passons à la configuration de l'interface Wi-Fi.

Ouvrez le fichier /etc/hostname.athn0 et indiquez la configuration suivante:

nwid "monSSID"
wpa
wpaprotos wpa2
wpakey maclefdelamortquitue
media autoselect mediaopt hostap
up
chan 1

Précisons:

  • nwid: il s'agit de votre SSID
  • wpa & wpaprotos: on active le chiffrement WPA. Si vous ne spécifiez pas wpaprotos WPA et WPA2 seront disponibles
  • wpakey: votre clef WPA
  • media autoselect mediaopt hostap: configure la carte Wi-Fi en mode AP et sélectionne automatiquement les options 802.11a/b/g
  • chan: le canal de transmission Wi-Fi. Sélectionnez un canal qui soit 1, 6 ou 11, étant peu utilisé par les AP/box de vos voisins.

J'ai remarqué qu'il fallait mettre le canal en dernier, après avoir allumé la carte Wi-Fi, autrement celle-ci n'émet pas. Cela doit dépendre des pilotes.

Enfin lancez l'interface:

sh /etc/netstart athn0

Configuration de l'interface de loopback

Dans un souci de détail, nous allons créer une interface de loopback qui aura l'adresse IP de notre AP. Cette IP aurait pu être spécifiée sur une interface Ethernet ou Wi-Fi mais la solution serait moins élégante.

echo "inet 10.0.0.1 255.255.255.0 NONE" > /etc/hostname.vether0
echo "description Bridge-WiFi" >> /etc/hostname.vether0
sh /etc/netstart vether0

Configuration du bridge

Pour finir on va créer notre bridge. Ouvrez le fichier /etc/hostname.bridge0

up
add vether0
add vr0
add vr1
add vr2
add athn0

et lancez l'interface

sh /etc/netstart bridge0

Note: si votre équipement est branché sur un commutateur supportant le spanning-tree, ajoutez les options stp dans le fichier /etc/hostname.bridge0

Conclusion

Si tout s'est bien passé, vous devriez voir apparaître le SSID que vous avez configuré. Ce tutoriel ne permet pas de distribuer des adresses IP, si vous le souhaitez, configurez (subnet et interfaces d'écoute) et lancez le démon dhcpd.

Sortie d’OpenBSD 5.4

Tous les 6 mois OpenBSD met à jour sa distribution. Cette mise à jour indique la fin du support de la version 5.2.

La version 5.4 est désormais sur pied et apporte des innovations et améliorations intéressantes.

Mises à jour

SSH/SFTP

  • SFTP supporte désormais la reprise de téléchargement partiel
  • Les clefs chiffrées stockées sur des cartes à puces sont désormais supportées par l'agent SSH

Packet Filter

  • Le comportement lors de fragmentation IP a été modifié
  • pfctl peut désormais afficher les compteurs match sur les tables
  • Les options divert-to et divert-reply supportent désormais IPv6
  • Correction d'un bug qui empêchait la création d'états ICMP lors de l'utilisation de PF en mode stateful

SMTPd

OpenSMTPD passe en version 5.3.3

  • Les backend SQLite et LDAP ont été ajoutés
  • Le comportement de la file des messages a été optimisé
  • Il est désormais possible de suspendre/reprendre l'ordonnancement par message
  • L'outil smtpctl permet désormais de visualiser l'état des routes empruntées par les messages, d'activer ces routes et de voir l'état des messages par domaine MX
  • Si le système de fichiers ou la file n'a plus que 10% d'espace libre, le démon refuse temporairement les messages
  • Le protocole LTMP est supporté

Réseau

  • Plusieurs correctifs sur BGPd
  • Des correctifs sur le pilote bge et notamment les cartes BCM5717/5718/5720
  • Correction d'un bug sur les pilotes virtio causant un kernel panic et des soucis sur la découverte de voisins IPv6
  • Beaucoup d'améliorations sur ldpd (démon MPLS)
  • La RFC 4191 concernant les avertissements d'informations de routes est désormais supportée par icmp6 et rtadvd
  • Les agrégats de liens (trunk) supportent désormais le jumbo frame
  • Plusieurs correctifs sur le démon npppd (PPTP, LT2P)
  • Le code du calcul des sommes de contrôle pour les protocoles a été réécrit
  • Le démon dhcpd se conforme de manière plus rigoureuse à la RFC 2131

Sécurité

  • La compression HTTPS a été désactivée sur httpd afin de contrer les attaques CRIME
  • inetd n'est plus démarré par défaut

Logiciels

  • drm 2.4.46
  • kerberbos/heimdal 1.5.2
  • sqlite 3.7.17
  • nginx 1.5.7
  • openSMTPD 5.3.3
  • perl 5.16.3

Pilotes

  • Support des cartes virtuelles VMWare VMXNet3
  • Support des cartes Realtek 8211C(L) GbE
  • Plusieurs correctifs sur les pilotes virtio
  • Support du chipset graphique Intel E7221
  • Support de KMS pour les pilotes graphiques AMD et Intel
  • Support expérimental de FUSE

Plateformes matérielles

OpenBSD a ajouté la compatibilité avec deux nouvelles plate-formes :

  • octeon
  • beagle (beaglebone/pandaboard)

Performances

L'équipe OpenBSD a amélioré les performances globales de la distribution en effectuant un travail sur les éléments suivants:

  • Les implémentations de bcopy/memmove/memcpy au niveau du noyau on été revues.
  • Les interruptions associées au système audio ne requièrent plus le verrou noyau (Giant Lock).
  • Un système de cache de symboles a été ajouté.

Processus de mise à jour

Pour effectuer la mise à jour de votre système, démarrez sur le CD d'OpenBSD 5.4 et choisissez l'option upgrade puis laissez vous guider. Une fois que le système a redémarré, montez ensuite le CD et lancez le processus de sysmerge

mount -t cd9660 /dev/cd0a /mnt
sysmerge -s /mnt/5.4/amd64/etc54.tgz

Vérifiez ensuite les différents diff que vous propose sysmerge et faites vos choix. C'est tout. Pour un processus de mise à jour plus détaillé, je vous invite à cliquer ici. Sources:

R&D: amélioration d’OpenOSPF

Suite à des travaux d'installation d'une liaison inter-site avec de nouveaux routeurs de bordure BGP+OSPF sous OpenBSD, je me suis rendu compte d'une limitation technique d'OpenOSPF.

En effet, mes routeurs devant distribuer les routes via GRE+OSPF, ils redistribuaient la route par défaut (obligatoire pour les routeurs internes), la route était redistribuée sur le tunnel GRE et provoquait une boucle de routage coupant le WAN.

La second limitation technique était celle de BGP et OSPF. OSPF étant prioritaire, si on redonde des routeurs de bordure, la route par défaut provoque une boucle de routage entre les routeurs de bordure.

OpenOSPF ne disposant pas de dispositif de filtrage, et devant en avoir un rapidement j'ai donc décidé de patcher le logiciel afin d'intégrer un dispositif de filtrage permettant de garder la cohérence de l'algorithme SPF tout en empêchant le système d'intégrer la route.

Je vous partage ce petit patch de 147 lignes permettant d'intégrer la fonctionnalité sur OpenOSPF (version d'OpenBSD 5.3), sous licence BSD.

--- /root/ospfd/ospfd.c 2011-11-15 05:17:46.000000000 +0100
+++ /usr/src/usr.sbin/ospfd/ospfd.c     2013-05-31 22:38:22.202030731 +0200
@@ -1,6 +1,7 @@
-/*   $OpenBSD: ospfd.c,v 1.78 2011/08/20 11:16:09 sthen Exp $ */
+/*   $OpenBSD: ospfd.c,v 1.79 2013/05/31 22:35:17 sthen Exp $ */

 /*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
  * Copyright (c) 2005 Claudio Jeker <claudio@openbsd.org>
  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -680,6 +681,7 @@
        struct area             *a, *xa, *na;
        struct iface            *iface;
        struct redistribute     *r;
+       struct kroute_filter *rf, *nrf;
        int                      rchange = 0;

        /* change of rtr_id needs a restart */
@@ -701,6 +703,14 @@
                        SIMPLEQ_REMOVE_HEAD(&xconf->redist_list, entry);
                        SIMPLEQ_INSERT_TAIL(&conf->redist_list, r, entry);
                }
+               for (rf = LIST_FIRST(&conf->kroute_filter_list); rf != NULL; rf =
nrf) {
+                       nrf = LIST_NEXT(rf, entry);
+                       kr_filter_del(rf);
+               }
+               for (rf = LIST_FIRST(&xconf->kroute_filter_list); rf != NULL; rf =
nrf) {
+                       nrf = LIST_NEXT(rf, entry);
+                       LIST_INSERT_HEAD(&conf->kroute_filter_list, rf, entry);
+               }
                goto done;
        }

@@ -891,3 +901,26 @@
                        return (i);
        return (NULL);
 }
+
+int
+kr_filter_do(struct kroute *kr)
+{
+       struct kroute_filter    *i;
+       
+       LIST_FOREACH(i, &ospfd_conf->kroute_filter_list, entry) {
+               /*
+                * TODO: filter all routes for one nexthop
+                */
+               if (i->prefix.s_addr == kr->prefix.s_addr &&
+                   i->prefixlen == kr->prefixlen &&
+                   (i->nexthop.s_addr == kr->nexthop.s_addr ||
+                   i->nexthop.s_addr == INADDR_ANY)) {
+                               log_info("ospfd_filternexthop: filtering route %s/%u",
+                                       inet_ntoa(i->prefix), i->prefixlen);
+                               log_info("ospfd_filternexthop: nexthop is %s",
+                                       inet_ntoa(i->nexthop));
+                               return (1);
+               }
+       }
+       return (0);
+}

--- /root/ospfd/ospfd.h 2013-02-16 04:03:42.000000000 +0100
+++ /usr/src/usr.sbin/ospfd/ospfd.h     2013-05-31 22:38:44.768029188 +0200
@@ -1,6 +1,7 @@
-/*   $OpenBSD: ospfd.h,v 1.91 2013/01/17 10:07:56 markus Exp $ */
+/*   $OpenBSD: ospfd.h,v 1.92 2013/05/31 22:38:56 markus Exp $ */

 /*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
  * Copyright (c) 2004 Esben Norby <norby@openbsd.org>
  * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
  *
@@ -387,6 +388,7 @@
        u_int8_t                border;
        u_int8_t                redistribute;
        u_int                   rdomain;
+       LIST_HEAD(, kroute_filter)      kroute_filter_list;
        char                    *csock;
 };

@@ -526,6 +528,14 @@
        int                      level;
 };

+/* kernel route filtering */
+struct kroute_filter {
+       LIST_ENTRY(kroute_filter)       entry;
+       struct in_addr           prefix;
+       struct in_addr           nexthop;
+       u_int8_t                 prefixlen;
+};
+
 /* area.c */
 struct area    *area_new(void);
 int             area_del(struct area *);
@@ -564,6 +574,9 @@
 void            kr_ifinfo(char *, pid_t);
 struct kif     *kif_findname(char *, struct in_addr, struct kif_addr **);
 void            kr_reload(void);
+struct kroute_filter *kr_filter_new(struct in_addr, struct in_addr,
u_int8_t);
+void kr_filter_del(struct kroute_filter *);
+struct kroute_filter *kr_filter_find(struct ospfd_conf *, struct
in_addr, struct in_addr, u_int8_t);

 u_int8_t       mask2prefixlen(in_addr_t);
 in_addr_t      prefixlen2mask(u_int8_t);
@@ -592,6 +605,7 @@
 void   imsg_event_add(struct imsgev *);
 int    imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t,
            pid_t, int, void *, u_int16_t);
+int             kr_filter_do(struct kroute *);

 /* printconf.c */
 void   print_config(struct ospfd_conf *);

--- /root/ospfd/parse.y 2010-12-20 19:09:24.000000000 +0100
+++ /usr/src/usr.sbin/ospfd/parse.y     2013-05-31 22:39:09.098027524 +0200
@@ -1,6 +1,7 @@
-/*   $OpenBSD: parse.y,v 1.73 2010/12/13 13:43:37 bluhm Exp $ */
+/*   $OpenBSD: parse.y,v 1.74 2013/05/31 22:12:08 bluhm Exp $ */

 /*
+ * Copyright (c) 2013 Loic Blot <loic.blot@unix-experience.fr>
  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
  * Copyright (c) 2004 Ryan McBride <mcbride@openbsd.org>
  * Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -116,12 +117,14 @@

 %}

-%token AREA INTERFACE ROUTERID FIBUPDATE REDISTRIBUTE RTLABEL RDOMAIN
-%token RFC1583COMPAT STUB ROUTER SPFDELAY SPFHOLDTIME EXTTAG
+%token AREA INTERFACE ROUTERID FIBUPDATE
+%token REDISTRIBUTE RTLABEL RDOMAIN RFC1583COMPAT STUB ROUTER SPFDELAY
+%token SPFHOLDTIME EXTTAG
 %token AUTHKEY AUTHTYPE AUTHMD AUTHMDKEYID
 %token METRIC PASSIVE
 %token HELLOINTERVAL FASTHELLOINTERVAL TRANSMITDELAY
 %token RETRANSMITINTERVAL ROUTERDEADTIME ROUTERPRIORITY
+%token KROUTEIGNOREINSERT PREFIXLEN NEXTHOP
 %token SET TYPE
 %token YES NO
 %token MSEC MINIMAL
@@ -435,7 +438,32 @@
                }
                ;

-defaults       : METRIC NUMBER {
+defaults       : KROUTEIGNOREINSERT STRING PREFIXLEN NUMBER NEXTHOP STRING {
+                       struct kroute_filter* kroute_filter;
+                       struct in_addr prefix;
+                       struct in_addr nexthop;
+                       u_int8_t prefixlen;
+                       
+                       if (!inet_aton($2, &prefix)) {
+                               yyerror("bad network: %llu/%llu", $2, $4);
+                               free($2);
+                               YYERROR;
+                       }
+                       
+                       if (!inet_aton($6, &nexthop)) {
+                               yyerror("bad network: %llu/%llu", $2, $4);
+                               free($2);
+                               YYERROR;
+                       }
+                       
+                       prefixlen = $4;
+                       
+                       kroute_filter = kr_filter_new(nexthop,prefix,prefixlen);
+                       LIST_INSERT_HEAD(&conf->kroute_filter_list, kroute_filter, entry);
+                       
+                       free($2);
+               }
+               | METRIC NUMBER {
                        if ($2 < MIN_METRIC || $2 > MAX_METRIC) {
                                yyerror("metric out of range (%d-%d)",
                                    MIN_METRIC, MAX_METRIC);
@@ -508,7 +536,6 @@
                | MINIMAL {
                        $ = FAST_RTR_DEAD_TIME;
                }
-
 optnl          : '\n' optnl
                |
                ;
@@ -726,11 +753,14 @@
                {"hello-interval",      HELLOINTERVAL},
                {"include",             INCLUDE},
                {"interface",           INTERFACE},
+               {"kroute-ignore-insert", KROUTEIGNOREINSERT},
                {"metric",              METRIC},
                {"minimal",             MINIMAL},
                {"msec",                MSEC},
+               {"nexthop",             NEXTHOP},
                {"no",                  NO},
                {"passive",             PASSIVE},
+               {"prefixlen",   PREFIXLEN},
                {"rdomain",             RDOMAIN},
                {"redistribute",        REDISTRIBUTE},
                {"retransmit-interval", RETRANSMITINTERVAL},
@@ -1101,6 +1131,7 @@
        LIST_INIT(&conf->area_list);
        LIST_INIT(&conf->cand_list);
        SIMPLEQ_INIT(&conf->redist_list);
+       LIST_INIT(&conf->kroute_filter_list);

        yyparse();
        errors = file->errors;

--- /root/ospfd/printconf.c     2010-02-20 19:02:25.000000000 +0100
+++ /usr/src/usr.sbin/ospfd/printconf.c 2013-05-31 22:39:27.174026288
+0200
@@ -1,4 +1,4 @@
-/*   $OpenBSD: printconf.c,v 1.15 2010/02/16 08:39:05 dlg Exp $ */
+/*   $OpenBSD: printconf.c,v 1.16 2013/05/31 21:59:48 dlg Exp $ */

 /*
  * Copyright (c) 2004, 2005 Esben Norby <norby@openbsd.org>
@@ -32,6 +32,7 @@
 const char *print_no(u_int16_t);
 void   print_redistribute(struct redist_list *);
 void   print_rtlabel(struct ospfd_conf *);
+void   print_kroute_filter(struct ospfd_conf *);
 void   print_iface(struct iface *);

 void
@@ -54,6 +55,7 @@

        print_redistribute(&conf->redist_list);
        print_rtlabel(conf);
+       print_kroute_filter(conf);

        printf("spf-delay msec %u\n", conf->spf_delay);
        printf("spf-holdtime msec %u\n", conf->spf_hold_time);
@@ -109,6 +111,19 @@
 }

 void
+print_kroute_filter(struct ospfd_conf *conf)
+{
+       struct kroute_filter    *kroute_filter;
+       
+       LIST_FOREACH(kroute_filter, &conf->kroute_filter_list, entry) {
+               printf("kroute-ignore-insert %s prefixlen %u",
+                       inet_ntoa(kroute_filter->prefix),kroute_filter->prefixlen);
+               printf(" nexthop %s\n",
+                       inet_ntoa(kroute_filter->nexthop));
+       }
+}
+
+void
 print_iface(struct iface *iface)
 {
        struct auth_md  *md;

Sortie d’OpenBSD 5.3

OpenBSD 5.3 est sorti en ce 1er mai. Il s'agit d'un release intéressant en terme de fonctionnalités:

  • Le nouveau service npppd permet d'offrir un service de tunnels PPTP/LT2P(IPsec)/PPPOE, et est capable de se connecter à un serveur Radius.
  • Amélioration sur les processus de routage, notamment OpenBGPd
  • OpenSMTPd bénéficie d'énormément de remaniements en terme de fonctionnalités:
    • Une syntaxe proche de celle de PF
    • Il est possible de matcher des utilisateurs et domaines
    • Des performances augmentées
    • et bien d'autres choses
  • Des améliorations de performance notamment sur les drivers disque
  • Il est désormais possible de booter sur un raid 1 soft chiffré
  • De nouvelles fonctionnalités avec OpenSSH 6.2
  • Amélioration du support matériel, notamment des cartes Broadcom 5717,5719,5720 que l'on retrouve dans les serveurs Dell récents

Un changelog plus complet est disponible ici

Pour upgrader c'est très simple:

  • Booter sur l'ISO d'OpenBSD 5.3
  • Choisir upgrade
  • Sélectionner le disque et la partition
  • Demander à faire un fsck des partitions non-root (on ne sait jamais)
  • Choisir le cd des paquets OpenBSD
  • Eventuellement retirer les paquets X11 et Games (-x -g)
  • Rebooter

Pour finir vous pouvez faire un sysmerge afin de mettre à jour les fichiers /etc du système

  • mount /dev/cd0c /mnt
  • sysmerge -s /mnt/5.3/amd64/etc53.tgz

Sondes NRPE pour bgpd (BSD)

BGP est un processus très sensible. Il convient de le monitorer finement afin de pouvoir être certain de tous ses états.

Afin de pouvoir monitorer efficacement vos processus bgpd, voici quelques sondes NRPE qui peuvent être intéressantes.

Prérequis

Afin de pouvoir monitorer correctement bgpd, nous autoriserons l'utilisateur nrpe à utiliser la commande bgpctl. Il faut ajouter la ligne suivante dans /etc/sudoers

_nrpe ALL=(ALL) NOPASSWD: /usr/sbin/bgpctl

Vérification du processus

Cette sonde vérifie que le processus tourne bien et qu'il écoute en IPv4 et en IPv6

#! /bin/sh
#states
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

SERVICEON=$(ps aux|grep bgpd|wc -l| awk '{print $1}')
if [ "$SERVICEON" -lt 3 ];
then
        echo "Le service BGPv4 est hors ligne"
        return $STATE_CRITICAL;
else
        LISTENV4=$(netstat -anfinet|grep tcp|grep LISTEN|grep 179|wc -l|awk '{print $1}')
        LISTENV6=$(netstat -anfinet6|grep tcp|grep LISTEN|grep 179|wc -l|awk '{print $1}')
        if [ $LISTENV4 -lt 1 ];
        then
                echo "Le service BGPv4 n'écoute pas en IPv4 !"
                return $STATE_CRITICAL
        fi
        if [ $LISTENV6 -lt 1 ];
        then
                echo "Le service BGPv4 n'écoute pas en IPv6 !"
                return $STATE_CRITICAL
        fi
        echo "Service BGPv4 en ligne"
        return $STATE_OK
fi

Vérification de l'état des neighbors BGP

Cette sonde va regarder l'ensemble des neighbors BGP référencés et leurs états. Si le statut BGP est Established, alors la sonde considère que tout va bien. Cette sonde vérifie à la fois IPv4 et IPv6 et compte également le nombre de neighbors

#! /bin/sh
#states
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

NEIGHBORS_V4=$(sudo bgpctl sh nei|grep neigh |awk '{print $4}'|grep "\."|sed 's/,//')
NEIGHBORS_V6=$(sudo bgpctl sh nei|grep neigh |awk '{print $4}'|grep ":"|sed 's/,//')

NB_V4_NEIGHBOR=0
NB_V6_NEIGHBOR=0

for NEI in $NEIGHBORS_V4
do
        BGPSTATE=$(sudo bgpctl sh nei $NEI|grep "BGP state"|awk '{print $4}'|sed 's/,//')
        if [ "$BGPSTATE" == "Established" ];
        then
                NB_V4_NEIGHBOR=$(($NB_V4_NEIGHBOR+1))
        fi
done

for NEI in $NEIGHBORS_V6
do
        BGPSTATE=$(sudo bgpctl sh nei $NEI|grep "BGP state"|awk '{print $4}'|sed 's/,//')
        if [ "$BGPSTATE" == "Established" ];
        then
                NB_V6_NEIGHBOR=$(($NB_V6_NEIGHBOR+1))
        fi
done

if [ $NB_V4_NEIGHBOR -lt 1 ];
then
        echo "Aucun neighbor IPv4 disponible ! Routage BGP IPv4 inopérant"
else
        echo $NB_V4_NEIGHBOR" neighbor(s) IPv4 en ligne"
fi

if [ $NB_V6_NEIGHBOR -lt 1 ];
then
        echo "Aucun neighbor IPv6 disponible ! Routage BGP IPv6 inopérant"
else
        echo $NB_V6_NEIGHBOR" neighbor(s) IPv6 en ligne"
fi

if [ $NB_V4_NEIGHBOR -lt 1 ] || [ $NB_V6_NEIGHBOR -lt 1 ];
then
        return $STATE_CRITICAL
else
        return $STATE_OK
fi

Vérification de la collecte de routes

Ce script vérifie que des routes IPv4 et IPv6 sont collectées. Il vérifie également la présence d'une route par défaut.

#! /bin/sh
#states
STATE_OK=0
STATE_WARNING=1
STATE_CRITICAL=2
STATE_UNKNOWN=3

ROUTES_V4=$(sudo bgpctl sh rib|grep "^*>"|awk '{print $2}'|grep "\.")
ROUTES_V6=$(sudo bgpctl sh rib|grep "^*>"|awk '{print $2}'|grep ":")
DEFROUTE_V4=0
DEFROUTE_V6=0

NB_V4_ROUTES=0
NB_V6_ROUTES=0

OUTPUT=""

for RT in $ROUTES_V4
do
        if [ "$RT" == "0.0.0.0/0" ];
        then
                DEFROUTE_V4=1
        fi
        NB_V4_ROUTES=$(($NB_V4_ROUTES+1))
done

for RT in $ROUTES_V6
do
        if [ "$RT" == "::/0" ];
        then
                DEFROUTE_V6=1
        fi
        NB_V6_ROUTES=$(($NB_V6_ROUTES+1))
done

if [ $NB_V4_ROUTES -lt 1 ];
then
        OUTPUT="Aucune route IPv4 disponible ! Routage IPv4 inopérant"
else
        OUTPUT=""$NB_V4_ROUTES" route(s) IPv4 apprises"
fi

if [ $NB_V6_ROUTES -lt 1 ];
then
        OUTPUT=$OUTPUT", Aucune route IPv6 disponible ! Routage IPv6 inopérant"
else
        OUTPUT=$OUTPUT", "$NB_V6_ROUTES" route(s) IPv6 apprises"
fi

if [ $NB_V4_ROUTES -lt 1 ] || [ $NB_V6_ROUTES -lt 1 ];
then
        echo $OUTPUT
        return $STATE_CRITICAL
else
        if [ $DEFROUTE_V4 != 1 ];
        then
                OUTPUT=$OUTPUT", mais aucune route par defaut IPv4 !"
                echo $OUTPUT
                return $STATE_WARNING
        fi
        if [ $DEFROUTE_V6 != 1 ];
        then
                OUTPUT=$OUTPUT", mais aucune route par defaut IPv6 !"
                echo $OUTPUT
                return $STATE_WARNING
        fi
        echo $OUTPUT
        return $STATE_OK
fi

Mise en place de pare-feu/routeurs hautement disponibles avec CARP et pfsync + GRE et OSPF et IPSEC

Introduction

Nous allons voir dans cette article comment mettre en place de la haute disponibilité sur pare-feu en utilisant CARP et pfsync. Ensuite nous relierons deux sites par un tunnel GRE chiffré en IPSEC.

Ce tutoriel est réalisé sous Virtualbox.

Schéma global de la solution:

Infrastructure

Pour appréhender ce tutoriel vous devez avoir pris connaissance des liens suivants:

Nous allons dans cet exemple mettre en place trois serveurs OpenBSD, dont deux utilisant CARP (avec une IP virtuelle) pour assurer de la haute-disponibilté.

Voici le scénario:

  • Réseau d'entreprise
  • Site distant
  • LAN principal et LAN distant.

Matériel

  • Trois serveurs OpenBSD 5.2 disposant de deux cartes réseau:
    • em0: WAN
    • em1: LAN

Modifications du Noyau

Nous allons configurer le noyau de chaque OpenBSD afin qu'il puisse répondre à nos besoins.

Activez le routage en éditant le fichier /etc/sysctl.conf:

net.ipv4.ip_forward=1

ainsi que les options relatives à CARP:

net.inet.carp.preempt=1
net.inet.carp.log=3

Configuration de CARP et PFSync

Nos machines utilisent le réseau LAN via la plage d'adresses 10.17.0.0/24. Pour mettre en place CARP et pfsync nous allons avoir besoin de plusieurs interfaces que nous allons configurer.

Configuration de CARP

GATEWAY A

/etc/hostname.carp1

inet 10.17.0.12 255.255.255.0 NONE vhid 1 carpdev em1 \
pass unixperience advbase 1 advskew 100
GATEWAY B

/etc/hostname.carp1

inet 10.17.0.12 255.255.255.0 NONE vhid 1 carpdev em1 \
pass unixperience advbase 1 advskew 10

Le paramétrage définit:

  • Les requêtes CARP sont envoyées toutes les secondes entre les deux passerelles afin de définir le "Master" et le "Backup".
  • Le advbase étant identique, la gateway B sera maître étant donné que sont advskew est le plus faible

Configuration de PFSync

Par souci de sécurité nous allons mettre le trafic de synchronisation pfsync dans un VLAN dédié entre les gateway. Ce VLAN sera encapsulé sur l'interface em0 et tagué VLAN 2.

Gateway A

/etc/hostname.vlan2

inet 172.21.0.31 255.255.255.0 NONE vlan 2 vlandev em1

/etc/hostname.pfsync0

up syncdev vlan2 syncpeer 172.21.0.32
Gateway B

/etc/hostname.vlan2

inet 172.21.0.32 255.255.255.0 NONE vlan 2 vlandev em1

/etc/hostname.pfsync0

up syncdev vlan2 syncpeer 172.21.0.31

Une fois la configuration effectuée, on lance les interfaces dédiées avec le script de lancement d'OpenBSD (vous ne pouvez spécifier qu'une interface en argument, cela évitera de reconfigurer les interfaces physique):

sh /etc/netstart

Vous devez maintenant avoir 2 nouvelles interfaces réseau (carp1 et pfsync0), la première possèdant notre IP 192.168.56.101 de manière partagée.

ifconfig carp1
ifconfig pfsync0

Vous pouvez observer le basculement entre les serveurs en désactivant l'interface carp1 sur le serveur maître. L'autre serveur passera de backup à master (ce changement est visible dans la console tty1, via un message kernel, ou en tapant dmesg).

Connexion au site distant

Mise en place un Tunnel GRE

Vous trouverez plus d'informations sur le Tunnel GRE dans cet article: Tunnel GRE

Configurons maintenant les interfaces GRE sur chaque passerelle.

Gateway A

/etc/hostname.gre0

172.16.0.1 172.16.0.3 netmask 0xffffffff link0 up
tunnel 192.168.56.102 192.168.56.105

Gateway B

172.168.0.2 172.16.0.4 netmask 0xffffffff link0 up
tunnel 192.168.56.103 192.168.56.105

Gateway C (Routeur distant)

/etc/hostname.gre0

172.168.0.3 172.16.0.1 netmask 0xffffffff link0 up
tunnel 192.168.56.105 192.168.56.102

/etc/hostname.gre1

172.168.0.4 172.16.0.2 netmask 0xffffffff link0 up
tunnel 192.168.56.105 192.168.56.103

Chaque interface GRE est connectée à une des gateway de notre LAN.

Tapez ensuite la commande sh /etc/netstart sur chaque machine pour prendre en compte les tunnels. Testez ensuite le fonctionnement du tunnel en pingant "l'autre bout"

Nos sites distants sont désormais connectés. Le principal inconvénient est la sécurité. En effet, ces tunnels ne sont pas sécurisés, n'importe qui peut observer le trafic en clair sur le WAN. Le second problème est le routage, comment rendre cette interconnexion dynamique ? La réponse: OSPF.

Mise en place de OSPF

La mise en place d'ospf est plutôt simple. La lecture du man (article ospfd.conf) vous apportera toute la lumière nécessaire. Nous allons dans le cas présent utiliser l'aire OSPF 1 via les tunnels GRE et utiliser un mot de passe (hashé en MD5): unix-experience.

/etc/ospfd.conf (Gateway A)

router-id 192.168.56.102
redistribute connected
gre_if="gre0"
password="unix-experience"
auth-md 1 $password
auth-type crypt
auth-md-keyid 1
area 0.0.0.1 {
         interface $gre_if {}
}

/etc/ospfd.conf (Gateway C)

router-id 192.168.56.103
redistribute connected
gre_if0="gre0"
gre_if1="gre1"
password="unix-experience"
auth-md 1 $password
auth-type crypt
auth-md-keyid 1
area 0.0.0.1 {
         interface $gre_if0 {}
         interface $gre_if1 {}
}

Pour ceux connaissant la syntaxe de pf vous retrouverez des similitudes.

Après quelques secondes, tapez la commande netstat -nrf -inet afin de visualiser l'état de la table de routage. Elle devrait se remplir avec des champs de poids 32 (OSPF)

N'oubliez pas d'activer OSPF au démarrage via /etc/rc.conf.local

Mise en place d'IPSEC

Le tunnel GRE étant non chiffré, nous allons appliquer une couche de chiffrement IPSec entre nos deux sites. Il faut commencer par activer la prise en charge d'IPSEC dans le noyau:

net.inet.esp.enable=1
net.inet.ah.enable=1

Voici donc le fichier de configuration de GA qui devra être adapté pour chaque gateway.

/etc/ipsec.conf

ike esp transport from 192.168.56.102 to 192.168.56.105 \
psk unix-experience

Il faut ensuite échanger les clés publiques (créée dans le fichier /etc/isakmp/local.pub à l'installation).

Par exemple pour le chiffrement de GA vers GC, copiez le fichier local.pub de GA dans le fichier /etc/isakmpd/pubkeys/ipv4/192.168.56.102 sur GC (le nom de fichier correspondant à l'IP de GA)

Notez que si vous utilisez un nom DNS pour établir le tunnel, il faudra utiliser le répertoire FQDN avec pour nom de fichier le FQDN

Lancez ensuite le chiffrement IPSEC

isakmpd -K
ipsecctl -f /etc/ipsec.conf

Si vous rencontrez des problèmes, un tail sur le fichier /var/log/messages devrait permettre de comprendre les problèmes pouvant être rencontrés.

Si le tunnel est opérationnel, ajoutez l'entrée suivante dans /etc/rc.conf.local afin d'activer IPSEC au boot:

isakmpd_flags="-K"
ipsec=YES

Sources

Monter un proxy-cache performant avec Squid et OpenBSD

Les serveurs de proxy sont devenues monnaie courante, pour ne pas dire obligatoires en entreprise (notamment pour la collecte de logs). Le service le plus répandu est Squid, que ce soit en version 2.7 ou 3.1, les versions les plus fréquentes à l'heure actuelle (statistiques du 1er janvier 2013)

Pour ce tutoriel, nous allons utiliser OpenBSD 5.2 et Squid 3.3.4 ainsi que SquidGuard 1.4p3. La configuration de Squid ne sera pas détaillée en terme de sécurité, seuls les éléments d'interaction avec le système et entre Squid et SquidGuard seront rapidement évoqués. Nous n'utiliserons pas l'authentification.

Nous allons optimiser squid en mettant l'ensemble des données qui utilisent des accès disques en ramdisk, et régler les problématiques associées à ce type d'optimisation. Le serveur qui est utilisé dispose de 16Go de RAM afin d'emmagasiner l'ensemble du cache en RAM

Prérequis: configuration de Packet Filter

Vous devez configurer le firewall d'OpenBSD pour autoriser le port 3128 (port par défaut de squid) et autoriser le serveur à faire des requêtes HTTP/HTTPS. Une règle de redirection de ports à été ajoutée afin de faire du proxy transparent sur HTTP. Voici une configuration simple et fonctionnelle (Attention cela ne concerne que Squid):

#
# Macros & Tables
#
out_if="em0"
int_if="em1"
proxy_ip="10.1.1.1"
outgoing_proxy_ip="195.25.36.159"
table <clients> { 10.50.0.0/16 192.168.0.0/16 172.16.0.0/18 }

#
# Default rules
#

block in log all
pass out all

#
# NAT
#

pass in quick on $int_if to any port http rdr-to $proxy_ip port 3128

#
# Filtering
#

pass in quick on $int_if proto tcp from <clients> to $proxy_ip port 3128
pass on $out_if quick proto tcp from $outgoing_proxy_ip to port { http https }

Prérequis: configuration des limites OpenBSD

Afin de pouvoir supporter la charge en terme d'entrées sortes parallèles, nous devons augmenter les limites systèmes en terme de descripteurs de fichiers. Ouvrez le fichier /etc/login.conf et éditez la classe daemon en augmentant le nombre de descripteurs de fichiers à 4096:

daemon:\
        :ignorenologin:\
        :datasize=infinity:\
        :maxproc=infinity:\
        :openfiles-cur=<span style="color: #ff0000;">4096</span>:\
        :stacksize-cur=8M:\
        :localcipher=blowfish,8:\
        :tc=default:

Installation

Installez tout d'abord un OpenBSD tout frais, dans l'idéal en 5.2.

Ensuite on va installer les quelques prérequis, notamment squidGuard et squid2.7, qui serviront de support (notamment si vous souhaitez avoir les helper d'authentification):

export PKG_PATH="http://ftp.fr.openbsd.org/pub/OpenBSD/5.2/packages/amd64/"
pkg_add -i squid
pkg_add -i squidGuard
pkg_add -i wget

Maintenant on va prendre la version de Squid 3.3.4 sur le site de squid-cache.org et la compiler:

cd /root/
wget http://www.squid-cache.org/Versions/v3/3.3/squid-3.3.4.tar.gz
tar xvzf squid-3.3.4.tar.gz
cd squid-3.3.4
./configure  '--enable-pf-transparent' '--enable-follow-x-forwarded-for' '--with-large-files' '--enable-ssl' '--disable-ipv6' '--enable-esi' '--enable-kill-parent-hack' '--disable-snmp' '--with-pthreads'
make -j8
make install

Au niveau des options,

  • si vous n'utiliserez pas le proxy transparent (redirection port 80 -> 3128), retirez '--enable-pf-transparent'
  • si vous utilisez IPv6, retirez '--disable-ipv6'

L'option -j8 définit l'utilisation de 8 coeurs de processeurs pour la compilation, accélérant nettement le traitement.

Maintenant on va changer le chemin du service squid. Editez le fichier /etc/rc.d/squid et changez la ligne daemon par

daemon="/usr/local/squid/sbin/squid"

Changez maintenant les flags afin de charger le fichier de configuration de squid et activer le service dans /etc/rc.conf.local (s'il n'existe pas, crééez le)

squid=YES
squid_flags="-f /etc/squid/squid.conf"

Copiez maintenant le fichier squid.conf dans un répertoire plus approprié par rapport à OpenBSD

mkdir /etc/squid/
cp /usr/local/squid/etc/squid.conf.documented /etc/squid/squid.conf

Créez maintenant les répertoires de squidGuard dont nous aurons besoin:

mkdir /etc/squidguard/mount/

Configuration

Configuration de Squid

Nous allons maintenant configurer Squid afin d'utiliser Squidguard. Attention depuis la version 3.2, cela ne se configure pas comme en 3.1 et 2.7:

url_rewrite_program /usr/local/bin/squidGuard -c /etc/squidguard/squidguard.conf
url_rewrite_children 192 startup=150 idle=10 concurrency=0

Nous lançons par défaut 150 processus squidGuard, avec un maximum de 192, et 10 en spare.

Si vous souhaitez utiliser le proxy transparent, il faut absoluement rajouter un second port d'écoute en mode intercept

http_port 3128
http_port 3129 intercept

On configure maintenant l'espace mémoire à réserver à squid, ainsi que d'autres paramètres associés:

# Real squid memory cache
cache_mem 2800 MB
maximum_object_size_in_memory 8 MB

# Squid disk cache
cache_dir ufs /var/squid/cache 2800 16 64
minimum_object_size 3 KB
maximum_object_size 6 MB

# IP & DNS names memory cache
ipcache_size 10240
fqdncache_size 10240

# File descriptor number
max_filedescriptors 4096

Vous pouvez tuner ces paramètres en fonction de votre configuration, par exemple divisez par 2 la taille de chaque cache si vous n'avez que 8Go de mémoire. Changez la taille maximale des fichiers en cache suivant le type de pages et de documents qui transitent en HTTP, tout en étant raisonnable, ne mettez pas des ISO en mémoire, le cache sera très vite rempli ! (A moins que vous ayez 64Go de ram, minimum).

Configurez ensuite les autres options, ACL, etc... à votre guise.

Configuration de SquidGuard

Ouvrez le fichier /etc/squidguard/squidguard.conf (s'il n'existe pas créez le et peuplez le). Nous allons simplement modifier la ligne correspondant au répertoire de blacklists:

dbhome /etc/squidguard/mount/blacklists

Configuration du système

Nous allons maintenant nous occuper du tuning du système, de la configuration du boot, de la mise à jour des blacklists.

Dans un premier temps, on va créer 2 ramdisk pour stocker le cache "disque" de squid et les blacklists de squidGuard. Ouvrez le fichier /etc/fstab et ajoutez les 2 lignes suivantes:

swap            /etc/squidguard/mount   mfs rw,nodev,nosuid,noatime,-s=2096900 0 0
swap            /var/squid/cache        mfs rw,nodev,nosuid,noatime,-s=9236000 0 0

Les options intéressantes sont ici le noatime, et -s.

  • noatime: on n'écrit pas les heures d'accès dans le système de fichier, il est temporaire, c'est donc inutile
  • -s : correspond au nombre de blocs sur le FS. Généralement ce sont des blocs de 512k. Les deux valeurs correspondent ici respectivement à 991M et 4.3G

Montez maintenant les deux systèmes de fichiers:

mount /var/squid/cache
mount /etc/squidguard/blacklists

On va maintenant créer l'arborescence du cache squid et modifier les droits afin d'utiliser le pf transparent:

/usr/local/squid/sbin/squid -f /etc/squid/squid.conf -z
chown root:_squid /dev/pf
chmod 0640 /dev/pf

On va maintenant générer les blacklists de squidGuard. On se base sur celles de l'université de Toulouse:

cd /etc/squidguard/
/usr/local/bin/wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz
cd /etc/squidguard/mount/
tar xzf /etc/squidguard/blacklists.tar.gz
chown -R _squid:_squid /etc/squidguard/mount/
/usr/local/bin/squidGuard -b -c /etc/squidguard/squidguard.conf -C all
chown -R _squid:_squid /etc/squidguard/mount/

Après ce procédé, si vous tapez df -h vous devriez voir que vos ramdisk se sont remplis

mfs:185        4.3G    1.0M   4.3G    1%    /var/squid/cache
mfs:754       991M   78.8M    862M     8%    /etc/squidguard/mount

La solution est prête ! Il reste néanmoins une étape subsidiaire, que faire en cas de reboot (tout est perdu) et comment mettre à jour tout cela proprement ?

Je vous propose ce script utilisé depuis un moment en production dans mon laboratoire du CNRS sur notre double gateway Squid:

#! /bin/sh

#
# Functions
#

gen_blacklists() {
        # extraction
        cd /etc/squidguard/mount/
        tar xzf /etc/squidguard/blacklists.tar.gz

        # droits
        chown -R _squid:_squid /etc/squidguard/mount/

        # Generation
        /usr/local/bin/squidGuard -b -c /etc/squidguard/squidguard.conf -C all

        # on reapplique les droits
        chown -R _squid:_squid /etc/squidguard/mount/

        # backup en cas de reboot
        cp -Rp /etc/squidguard/mount/blacklists /etc/squidguard

        /etc/rc.d/squid start
}

# On eteint squid
/etc/rc.d/squid stop

# suppression des données en RAM
rm -R /etc/squidguard/mount/*
/sbin/umount /etc/squidguard/mount
# On attend que les volumes soient démontés
while [ $(df -h|grep /etc/squidguard/mount|wc -l|awk '{print $1}') -gt 1 ];
do
        sleep 1;
        /sbin/umount /etc/squidguard/mount
done

# On remonte le volume
mount /etc/squidguard/mount

# Au boot on ne fait que reprendre le backup
if [ "$1" == "boot" ];
then
        if [ -d /etc/squidguard/blacklists ];
        then
                cp -Rp /etc/squidguard/blacklists /etc/squidguard/mount/
                /etc/rc.d/squid start
        else
                # S'il n'y a pas de backup des blacklists, on va reprendre le tar.gz et les reconstruire
                if [ -f /etc/squidguard/blacklists.tar.gz ];
                then
                        gen_blacklists
                else
                        echo "/!\ Squid cannot be started because no blacklists found"
                fi
        fi
else
        # suppression de l'ancienne backup des blacklists
        if [ -d /etc/squidguard/blacklists ];
        then
                rm -R /etc/squidguard/blacklists
        fi

        # suppression de l'ancienne archive (au cas ou il y aura des doublon on supprime tout)
        rm /etc/squidguard/blacklists.tar.gz*

        # telechargement des BL
        cd /etc/squidguard/
        /usr/local/bin/wget ftp://ftp.univ-tlse1.fr/pub/reseau/cache/squidguard_contrib/blacklists.tar.gz

        gen_blacklists
fi

Ce script exécute 2 tâches, il gère la création complète des blacklists squidGuard et leur mise à jour, mais il fait également un backup de ces blacklists.

Il peut arriver que dans un PRA/PCA votre proxy et vos routeurs matériels tombent. Généralement OpenBSD redémarera plus vite que les routeurs, et il ne pourra pas télécharger les blacklists sur le net, et donc les générer, et squid ne démarrera pas.

Le script réalise un backup des listes générées et les restaure au boot. Si elles n'existent pas il reprend le dernier .tar.gz et refait le processus de génération. Si jamais il n'y a rien, eh bien il ne peut pas démarrer squid. L'utilisation de ce procédé se fait en passant l'argument boot au script

Maintenant on applique le script au démarrage, éditez le fichier /etc/rc.local et ajoutez lignes suivantes:

echo 'Started Squid Proxy Cache Service'
if [ -x /usr/local/squid/sbin/squid ]; then
        umount /var/squid/cache
        mount /var/squid/cache
        /usr/local/squid/sbin/squid -f /etc/squid/squid.conf -z
        chown root:_squid /dev/pf
        chmod 0640 /dev/pf
        /etc/squidguard/squidguard-update.sh boot
fi
echo ''

Editez également le fichier /etc/rc.shutdown afin de rajouter l'extinction propre de squid

echo 'Stopping Squid Proxy Cache Service'
if [ -x /usr/local/sbin/squid ]; then
        /etc/rc.d/squid stop
fi
echo ''

Pour terminer, on rajoute la planification de la mise à jour des blacklists, par exemple le dimanche matin à 5h:

crontab -e
00      5       *     *     6       /etc/squidguard/squidguard-update.sh > /dev/null

Votre proxy-cache est désormais prêt et optimisé !

Note: ces actions sont également réalisables sous FreeBSD et Linux, il faut simplement changer de technologie de ramdisk (mfs), et les chemins des fichiers. OpenBSD reste néanmoins le plus sécurité et performant pour ce type de processus.

Mise en place d’un portail captif sous OpenBSD

Un portail captif est une page qui peut s'avérer essentielle dans certains cas, comme par exemple pour proposer une accès internet temporaire à vos visiteurs. Nous allons voir comment mettre en place un portail captif en utilisant Packet Filter, Apache et un client Radius.

En terme de législation nous n'autorisons les gens à utiliser le réseau que s'ils acceptent la charte informatique. Celle que vous trouverez ici est un modèle inspiré par l'Université Paris XI et repris par l'Institut Optique Graduate School.

Ils vous faudra au préalable un serveur DHCP et un DNS. Ce tutoriel sous entend que vous savez déjà ce qu'est Packet Filter et comment le configurer dans les grandes lignes. Si vous ne souhaitez pas rediriger le trafic HTTP vers squid, il suffit de nater le trafic, comme pour le HTTPS.

En ce qui concerne le partie web, nous utiliserons l'Apache fourni sur OpenBSD (Apache 1.4), en lui ajoutant le support de php5.3 et le client radtest pour notre authentification, contenu dans FreeRadius. Enfin nous aurons besoin de sudo pour utiliser pfctl

export PKG_PATH=http://ftp.fr.openbsd.org/pub/OpenBSD/5.2/packages/amd64/
pkg_add -i php
pkg_add -i freeradius
pkg_add -i sudo

Pour terminer sur la partie réseau, notre portail captif dispose de deux interfaces

  • em0: l'interface de sortie Internet
  • em1: l'interface des clients qui iront sur le portail captif

Configuration de Packet Filter

Dans un premier temps nous allons configurer notre firewall. Nous aurons besoin d'une table dynamique où stocker nos clients une fois qu'ils seront authentifiés. (rappel la configuration de pf est dans /etc/pf.conf).

La dynamique du portail captif marchera de la manière suivante:

  • Si le client n'est pas authentifié, on redirige le trafic HTTP/HTTPS vers la machine elle-même (ici 192.168.1.1 sera son IP, et le réseau à envoyer dans le portail 192.168.1.0/24)
  • Sinon on redirige le flux HTTP vers notre proxy et on nate le flux HTTPS

En résumé, et en plaçant les règles en respectant les bonnes pratiques de Packet Filter on aura l'ensemble de règles suivantes:

#
# macros & tables
#
localip = "192.168.1.1"
localnet = 192.168.1.0/24
outgoing_iface = em0

table <captiveportal_allow> persist

#
# nat & rdr
#
# For allowed clients (nat https and rdr http to squid)
pass out quick proto tcp from <captiveportal_allow> to any port 443 nat-to (em0)
pass in quick proto tcp from <captiveportal_allow> to any port 80 rdr-to $localip port 3128
# For other clients
pass in quick proto tcp from $localnet to any port 80 rdr-to $localip port 80
pass in quick proto tcp from $localnet to any port 443 rdr-to $localip port 443

#
# filtering
#
pass in quick proto tcp from $localnet to $localip port { 80 443 }

Configuration de sudo

Nous devons maintenant configurer sudo qui vous permettre d'utiliser la commande pfctl. Ouvrez le fichier /etc/sudoers et ajoutez y la ligne suivante

www     ALL=(ALL) NOPASSWD: /sbin/pfctl

Configuration d'Apache

La première chose à faire et des désactiver le chroot d'apache afin qu'il puisse accéder à la commande pfctl (en effet la jail est tellement bien faite que si on laisse le chroot il est impossible d'avoir accès au device /dev/pf). Ajoutez le flag -u à Apache. On va au passage ajouter le flag permettant d'activer SSL. Ajoutez le contenu suivant au fichier /etc/rc.conf.local (sous OpenBSD):

httpd_flags="-u -DSSL"

La seconde étape consiste à configurer Apache pour qu'il redirige les erreurs 403 et 404 vers une page de redirection (en l'occurence ici, ce sera login.php). Cette manipulation nous permettra d'intercepter les pages demandées par le client et qui arrivent sur le serveur web Ouvrez le fichier /var/www/conf/httpd.conf et à l'endroit mentionnant les ErrorDocument ajoutez les lignes suivantes:

ErrorDocument 403 /openbsdcaptiveportal.php
ErrorDocument 404 /openbsdcaptiveportal.php

On dimensionne ensuite le nombre de requêtes pouvant être traitées simultanément en allumant 20 processus Apache et en autorisant 1024 clients:

StartServers 20
MaxClients 1024

On va également n'autoriser que le réseau du portail captif à se connecter à celui-ci:

<Directory "/var/www/htdocs">
    Options -Indexes FollowSymLinks
    Order Deny,Allow
    Deny from all
    Allow from 192.168.1.0/24
</Directory>

Enfin on termine par le support SSL.

<VirtualHost _default_:443>
        SSLEngine On
        SSLCertificateFile /etc/ssl/server.crt
        SSLCertificateKeyFile /etc/ssl/private/server.key
</VirtualHost>

Il ne nous reste plus qu'à générer les certificats

 openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout /etc/ssl/private/server.key -out /etc/ssl/server.crt

Scripts d'authentification

La partie intéressante concerne l'authentification. Dans un premier temps, inscrivez la règle suivante dans /var/www/htdocs/index.html

<meta http-equiv="refresh" content="0;URL='openbsdcaptiveportal.php'">

Ce script va permettre qu'un utilisateur demandant la racine d'un site soit redirigé vers le portail captif. Cela permet notamment aux sondes Nagios de ne pas détecter une erreur 403 due à l'interdiction de lister les répertoires.

Voici maintenant le script d'authentification. Il sera explicité plus bas:

<?php
        function redirectIfNotOnPortal() {
                $url = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"]=="on" ? "https://" : "http://").$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
                if($_SERVER["HTTP_HOST"] != "192.168.1.1") {
                        echo "<meta http-equiv="refresh" content="0;URL='http://192.168.1.1/login.php?url=".$url."'">";
                        exit(0);
                }
        }

        function showInfoChart() {
                $output = "<textarea disabled rows="10" cols="70">Charte d'utilisation

MyCompany

1\. Définition

L'acronyme MC définit MyCompany

2\. Champ d'application

La présente charte définit les règles d'utilisation des ressources informatiques de MC associée à ce service, en confirmité avec législation en vigueur. Elle décrit également les sanctions applicables en cas de non-respect de ces règles et rappelle les principaux textes de référence.

Elle s'applique à toute personne utilisant les ressources de MC Le non-respect de cette charte peut engager la responsabilité du signataire.

3\. Conditions d'accès au ressources informatiques

L'accès aux ressources informatiques de MC est soumis à autorisation et ne peut se faire que dans le cadre professionnel du signataire.

Le moyen d'accès aux ressources informatiques, de quelque nature qu'il soit (mot de passe, certificat, ) est strictement personnel et incessible. Il disparaît dès que son titulaire ne répond plus aux critères d'attribution tels que définis lors de l'attribution du-dit moyen. En cas de perte ou de vol, l'utilisateur doit contacter son correspondant informatique qui prendra les mesures jugées nécessaires.

Il est strictement interdit de mettre en place un équipement ou service informatique qui pourrait interférer dans le bon fonctionnement des ressources informatiques de MC.

4\. Respect de la déontologie informatique

Le signataire s'engage à ne pas effecter intentionnellement des opérations qui pourraient notamment, avoir pour conséquences:

- de dérober ou d'utiliser le moyen d'accès d'un autre utilisateur
- de masquer sa véritable identité ou d'usurper l'identité d'un tiers
- d'intercepter toute communication entre tiers
- d'altérer les données communicant entre tiers
- d'accéder aux données d'un tiers sans leur autorisation, de les supprimer ou de les modifier
- de porter atteinte à la vie privée d'un tiers
- d'interrompre ou d'altérer le fonctionnement normal du réseau ou d'un des systèmes connectés au réseau
- de contourner les contrôles d'accès et restrictions mis en place sur le réseau ou les systèmes connectés au réseau
- de reproduire, représenter, diffuser une oeuvre soumise aux droits d'auteurs

5\. Gestion des réseaux et systèmes informatiques

Le signataire est informé et accepte expressément que la Direction des Services Informatiques de MC procède à des contrôles de la bonne utilisation des ressources informatiques, pouvant avoir comme conséquence la connaissance de données à caractère privé ou confidentiel notamment les traces de connexion conservées pour une durée maximal d'un an.

Il accepte que la Direction des Services Informatiques prenne des mesures d'urgence, comme la limitation ou l'interruption temporaire du fonctionnement d'une partie ou de la totalité des réseaux et services de MC, afin de préserver la sécurité en cas d'incident ou de violation grave, telle que mentionnée dans le paragraphe précédent.

6\. Sanctions

En cas de manquement constaté aux règles énoncées dans la présente charte, le Service Informatique se réserve la possibilité de supprimer immédiatemment, pour une durée indéterminée, une partie ou la totalité des accès aux ressources informatique de MC. Après saisine des autorités compétences, le signataire pourra être poursuivi disciplinairement et/ou pénalement selon la nature du manquement.

7\. Cadre juridique

- loi 78-17 du 6 janvier 1978 relative à l'informatique, aux fichiers et aux libertés
- articles L335-2 et L335-3 du code de la propriété intellectuelle
- loi 2006-961 du 1er août 2006 relative aux droits d'auteurs et aux droits voisins dans la société de l'information
- loi 2004-575 du 21 juin 2004 pour la confiance dans l'économie numérique
- loi 2006-64 du 23 janvier 2006 relative à la lutte contre le terrorisme

8\. Modification de la charte

Le signataire est informé que cette charte peut être modifiée à tout moment.
</textarea>";
                return $output;
        }
        function showLoginContent($err="") {
                $url = (isset($_GET["url"]) && strlen($_GET["url"]) > 0 ? $_GET["url"] : "");
                $output = "<div id="logf"><img id="logi" width="400px" height="224px" src="logo_secu.jpg"/>
                        <div id="desc">Bienvenue sur le portail d'authentification de MyCompany.
                        Ce portail est strictement <b>réservé aux visiteurs</b>. Les <b>personnes enregistrxc3xa9es</b> sur notre annuaire doivent utiliser le rxc3xa9seau WiFi <b>MyCompany</b></div>
                        <form action="login.php?log=1".(strlen($url) > 0 ? "&url=".$url : "")."" method="POST">";
                $output .= "<h3>Charte d'utilisation</h3>".showInfoChart();
                $output .= "<h3>Authentification</h3>".$err."<center><table><tr><td style="text-align: right">Identifiant</td><td><input type="textbox" name="username"></td></tr>
                        <tr><td style="text-align: right;">Mot de passe</td><td><input type="password" name="password"></td></tr></table></center>
                        <input type="checkbox" name="charte" />J'accepte les conditions d'utilisation des ressources informatiques de MyCompany<br />
                        <input type="submit" id="send" value="Identification"></form></div>";
                return $output;
        }

        function showError($errid) {
                $output = "";
                switch($errid) {
                        case 1: $output .= "<div id="err">Certains champs n'ont pas été renseignés !</div>"; break;
                        case 2: $output .= "<div id="err">Identifiant ou mot de passe incorrect !</div>"; break;
                        case 3: $output .= "<div id="err">Impossible d'accéder au serveur RADIUS, veuillez contacter le support informatique !</div>"; break;
                        case 4: $output .= "<div id="err">Authentification correcte, néanmoins vous n'êtes pas autorisé à utiliser ce portail</div>"; break;
                        case 5: $output .= "<div id="err">Vous n'avez pas accepté la charte, accès refusé</div>";
                        case 6: $output .= "<div id="err">Erreur fatale au niveau du serveur. Service indisponible</div>";
                        default: break;
                }
                return $output;
        }

        function showStyle() {
                $output = "<style type="text/css">
                        body {
                                text-align: center;
                                font-size: 13px;
                                font-family: century gothic, verdana, sans-serif;
                                background-color: #FFF;
                        }
                        #err {
                                color: red;
                                width: 90%;
                                padding: 5px;
                                display: inline-block;
                                font-weight: bold;
                                margin: 15px;
                        }
                        #logf {
                                margin-top: 15px;
                                display: inline-block;
                                background-color: white;
                                border-radius: 5px;
                                padding: 0px 25px 25px 25px;
                                background-image: -moz-linear-gradient(center top , #FAFAFA 0px, #DCDCDC 100%);
                                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
                                width: 600px;
                        }
                        #logf input {
                                margin-bottom: 5px;
                        }
                        #logi {
                                margin-bottom: 15px;
                        }
                        #logf textarea, #desc {
                                text-align: left;
                        }
                        #logf #send {
                                margin-top: 15px;
                        }
                        #logok {
                                display: inline-block;
                                vertical-align: middle;
                                background-color: white;
                                border-radius: 5px;
                                padding: 25px;
                                background-image: -moz-linear-gradient(center top , #FAFAFA 0px, #DCDCDC 100%);
                                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
                                width: 600px;
                                top: 50%;
                                margin-left: -300px;
                                position: fixed;
                                margin-top: -100px;
                        }

                        </style>";
                return $output;
        }

        function tryAuthRadius($user,$pwd) {
                $out = "";
                exec("/usr/local/bin/radtest "".$user."" "".$pwd."" radiuserver.my.company:1812 0 radpwd",$out);
                for($i=0;$i<count($out);$i++) {
                        if(preg_match("#Access-Reject#",$out[$i]))
                                return 1;
                        else if(preg_match("#Access-Accept#",$out[$i]))
                                return 0;
                }
                if(!preg_match("#^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9]).(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$#",$_SERVER["REMOTE_ADDR"]))
                        return 4;
                return 2;
        }

        redirectIfNotOnPortal();

        // Header
        $output = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"><html><head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>MyCompany: Identification visiteur</title>';
        $output .= showStyle();

        $headeroutput = "";
        $url = "";

        if(isset($_GET["log"]) && $_GET["log"] == 1) {
                $username = (isset($_POST["username"]) && strlen($_POST["username"]) > 0 ? $_POST["username"] : "");
                $password = (isset($_POST["password"]) && strlen($_POST["password"]) > 0 ? $_POST["password"] : "");
                $charteaccept = (isset($_POST["charte"]) && strlen($_POST["charte"]) > 0 ? $_POST["charte"] : "");
                if(!$username || !$password) {
                        $tmpoutput .= showLoginContent(showError(1));
                }
                else if(!$charteaccept) {
                        $tmpoutput .= showLoginContent(showError(5));
                }
                else {
                        $errauth = tryAuthRadius($username,$password);
                        if($errauth != 0) {
                                switch($errauth) {
                                        case 1: $erroutput = showError(2); break;
                                        case 2: $erroutput = showError(3); break;
                                        case 3: $erroutput = showError(4); break;
                                        case 4: $erroutput = showError(6); break;
                                        default: $erroutput = ""; break;
                                }
                                $tmpoutput .= showLoginContent($erroutput);
                        }
                        else {
                                $tmpoutput .= "<div id="logok">Vous êtes maintenant identifié et pouvez accéder à Internet.<br /><br />";
                                if(isset($_GET["url"]) && strlen($_GET["url"]) > 0) {
                                        $url = $_GET["url"];
                                        $headeroutput = "<meta http-equiv="refresh" content="5;URL='".$url."'">";
                                        $tmpoutput .= "Vous serez redirigé dans 5 secondes vers l'adresse <a href="".$url."">".$url."</a></div>";
                                }
                                else {
                                        $tmpoutput .= "Vous pouvez maintenant quitter cette page et vous connecter aux sites web de votre choix";
                                }
                                $out="";
                                exec("/usr/bin/sudo /sbin/pfctl -t captiveportal_allow -T add ".$_SERVER["REMOTE_ADDR"]."",$out);
                        }
                }
        }
        else {
                $tmpoutput .= showLoginContent();
        }
        // End
        $output .= $headeroutput."</head><body>".$tmpoutput."</body></html>";
        echo $output;
?>

Ce script affiche une page web comportant 4 éléments fondamentaux:

  • Le logo et nom de l'entreprise
  • La charte d'utilisation
  • L'authentification par login/password
  • La signature de la charte

Au niveau de l'authentification 4 éléments sont testés:

  • L'existence de chacun des champs
  • La signature de la charte
  • L'authentification
  • L'adresse du client

Au niveau mécanisme de redirection, si l'utilisateur provient d'une URL, celle-ci est enregistrée afin de le rediriger sur la page demandée au bout de 5 secondes. En revanche s'il n'y en a pas il sera invité à quitter cette page.

Si l'authentification est réussie, l'utilisateur sera ajouté à la table captiveportal_allow.

Nettoyage des clients

La dernière étape consiste à nettoyer la table. Nous allons ajouter une règle au cron. Tapez crontab -e et ajoutez la ligne suivante:

# Captive portal
*     *     *     *     *     /sbin/pfctl -t captiveportal_allow -T expire 3600 > /dev/null

Migrer d’OpenBSD 5.1 à OpenBSD 5.2

OpenBSD 5.2 est sorti hier (le 1er novembre 2012). Voyons comment basculer d'OpenBSD 5.1 à OpenBSD 5.2. Le cas pratique présenté ici est la bascule d'une passerelle réseau redondée avec CARP (elle aurait pu être load balancée).

Je vous rappelle que l'équipe OpenBSD ne recommande pas de passer d'une version à une trop récente et de suivre l'évolution du système.

Temps de mise à jour (hors compilation d'éléments tiers): 12 minutes

Étape 1: Mise à niveau du système:

  1. Redémarrez votre serveur sur le CD d'OpenBSD 5.2
  2. Choisissez Upgrade puis votre clavier (fr pour nous)
  3. Choisissez le disque contenant la racine de votre système puis la partition racine. Un fsck va être effectué.
  4. Répondez oui au fsck des autres partitions, il se peut que cela n'aie pas été fait depuis très longtemps à cause de la criticité du système.
  5. Avancez dans l'installation en sélectionnant les packages système à installer. Je vous recommande tout sauf x11 et les jeux (-x et -g)
  6. Installez et redémarrez

Étape 2: Mise à niveau des services tiers

Si vous avez installé des services et paquets tiers, il va falloir faire cette étape, sinon c'est terminé.

Tapez les 2 commandes suivantes afin de mettre à jour les applications:

export PKG_PATH=http://ftp.fr.openbsd.org/pub/OpenBSD/5.2/packages/amd64/
pkg_add -u

Dans notre cas voici la sortie de la commande:

root@mgw> pkg_add -u                                                            ~
quirks-1.59->quirks-1.73: ok
arc-5.21p->arc-5.21p: ok
arping-2.09->arping-2.11: ok
bash-4.2.36:libiconv-1.14->libiconv-1.14: ok
bash-4.2.36:gettext-0.18.1p1->gettext-0.18.1p3: ok
bash-4.2.20->bash-4.2.36: ok
bwm-ng-0.6p0->bwm-ng-0.6p0: ok
bzip2-1.0.6->bzip2-1.0.6: ok
clamav-0.97.5p0:lha-1.14i.ac20050924.1->lha-1.14i.ac20050924.1: ok
clamav-0.97.5p0:zoo-2.10.1p1->zoo-2.10.1p1: ok
clamav-0.97.5p0:unzip-6.0p0->unzip-6.0p0: ok
clamav-0.97.3p3->clamav-0.97.5p0: ok
cyrus-sasl-2.1.25p2->cyrus-sasl-2.1.25p3: ok
db-4.6.21v0->db-4.6.21v0: ok
eventlog-0.2.12p0->eventlog-0.2.12p1: ok
femail-0.98->femail-0.98: ok
femail-chroot-0.98->femail-chroot-0.98p1: ok
glib2-2.32.4:pcre-8.21->pcre-8.30: ok
glib2-2.32.4:libelf-0.8.13p1: ok
glib2-2.32.4:python-2.7.1p12->python-2.7.3p0: ok
glib2-2.30.2p5->glib2-2.32.4: ok
havp-0.92ap0->havp-0.92ap1: ok
iftop-0.17p2->iftop-1.0pre2: ok
isc-dhcp-server-4.2.3.2->isc-dhcp-server-4.2.4: ok
libdnet-1.12p4->libdnet-1.12p4: ok
libexecinfo-0.2p0v0->libexecinfo-0.2p0v0: ok
libidn-1.22->libidn-1.25: ok
libxml-2.7.8p4->libxml-2.7.8p6: ok
lua-5.1.4p3->lua-5.1.5p0: ok
nagios-plugins-1.4.15p1->nagios-plugins-1.4.16: ok
nano-2.2.6->nano-2.2.6: ok
nmap-5.51p2->nmap-6.01: ok
nrpe-2.12.20100914p1->nrpe-2.12.20100914p1: ok
openldap-client-2.4.26->openldap-client-2.4.31: ok
php-5.3.10->php-5.3.14p1: ok
popt-1.16->popt-1.16: ok
rsync-3.0.9->rsync-3.0.9: ok
samba-3.6.6p0-ads:tdb-1.2.7->tdb-1.2.7: ok
samba-3.6.1p1-ads->samba-3.6.6p0-ads: ok
Removing
sqlite3-3.7.9p0->: ok
Problem: checksum doesn't match for /usr/local/sbin/squid
NOT deleting: /usr/local/sbin/squid
Renaming old file /usr/local/sbin/squid to /usr/local/sbin/squid.aD46RQezg5
squid-2.7.STABLE9p15-ntlm->squid-2.7.STABLE9p19-ntlm: ok
squidGuard-1.4p2-ldap->squidGuard-1.4p3-ldap: ok
syslog-ng-3.1.4p6:libdbi-0.8.3: ok
syslog-ng-3.1.4p1->syslog-ng-3.1.4p6: ok
wget-1.13.4->wget-1.13.4: ok
zsh-4.3.15->zsh-4.3.17: ok
Read shared items: ok
Look in /usr/local/share/doc/pkg-readmes for extra documentation.
--- -clamav-0.97.3p3 -------------------
You should also run rm -fr /var/db/clamav/*
You should also run rm -fr /var/spool/clamav/*
You should also run rm -fr /var/clamav/quarantine/*
You should also run rm -fr /var/clamav/tmp/*
You should also check /etc/clamd.conf (which was modified)
You should also check /etc/freshclam.conf (which was modified)
--- -cyrus-sasl-2.1.25p2 -------------------
You should also run rm -rf /var/sasl2/*
--- -isc-dhcp-server-4.2.3.2 -------------------
Remember to update /var/db/dhcpd.leases
--- -libxml-2.7.8p4 -------------------
Remember to update /var/db/xmlcatalog
--- -nrpe-2.12.20100914p1 -------------------
You should also check /etc/nrpe.cfg (which was modified)
--- -php-5.3.10 -------------------
You should also run rm -fr /etc/php-5.3/
To completely deinstall the package you need to
remove the symbolic link from /var/www/conf/modules
by performing the following step as root:

 rm -rf /var/www/conf/modules/php.conf
--- -python-2.7.1p12 -------------------
Don't forget to remove /usr/local/bin/python,
/usr/local/bin/2to3, /usr/local/bin/python-config and/or
/usr/local/bin/pydoc if they were symlinks to
/usr/local/bin/python2.7, /usr/local/bin/python2.7-2to3,
/usr/local/bin/python2.7-config or to /usr/local/bin/pydoc2.7.
--- -samba-3.6.1p1-ads -------------------
You should also check /etc/samba/smb.conf (which was modified)
--- -squid-2.7.STABLE9p15-ntlm -------------------
You should also run rm -rf /var/squid/cache/*
You should also run rm -rf /var/squid/logs/*
Couldn't delete /usr/local/sbin/squid (bad checksum)
You should also check /etc/squid/squid.conf (which was modified)
Files kept as partial-squid-2.7.STABLE9p15-ntlm package
--- -squidGuard-1.4p2-ldap -------------------
You should also check /etc/squidguard/squidguard.conf (which was modified)
You should also run rm -fr /etc/squidguard
You should also run rm -fr /var/db/squidGuard
You should also run rm -fr /var/log/squidguard/
--- -syslog-ng-3.1.4p1 -------------------
You should also check /etc/syslog-ng/syslog-ng.conf (which was modified)
--- +nagios-plugins-1.4.16 -------------------
The check_dhcp and check_icmp plugins need to run with superuser
privileges. For security reasons they are not installed suid root
by default. If you want to use them, you have to either change
their mode manually or use systrace's privilege elevation feature.
--- +php-5.3.14p1 -------------------
To enable the php-5.3 module please create a symbolic link from
/var/www/conf/modules.sample/php-5.3.conf to
/var/www/conf/modules/php.conf. As root:

    ln -sf /var/www/conf/modules.sample/php-5.3.conf /var/www/conf/modules/php.conf

The recommended php configuration has been installed to:
    /etc/php-5.3.ini.
--- +python-2.7.3p0 -------------------
If you want to use this package as your default system python, as root
create symbolic links like so (overwriting any previous default):
 ln -sf /usr/local/bin/python2.7 /usr/local/bin/python
 ln -sf /usr/local/bin/python2.7-2to3 /usr/local/bin/2to3
 ln -sf /usr/local/bin/python2.7-config /usr/local/bin/python-config
 ln -sf /usr/local/bin/pydoc2.7  /usr/local/bin/pydoc

Etape 3: Vérification

Comme vous pouvez le voir, pkg_add nous incite à vérifier les modifications qu'il a apportées au fichiers de configuration de vos services. Dans notre cas rien n'a été impacté par ces modifications.

Etape 4: Personnalisation

Pour terminer recompilez tous les logiciels tiers que vous avez compilés vous même.

Conseils annexes

Si vous utilisez CARP, n'oubliez pas d'incrémenter ou la valeur du advskew ou le carpdemote afin que votre serveur ne devienne pas maître (ifconfig -g carp cardemote 200).