Y’a plus simple mais c’est moins rigolo (updated)

Tags: , ,
4 Comments »

02 / 08 / 2011 – Mise à jour il-ne-faut-pas utiliser lo0 comme interface pivot, il ne faut pas. Pour une raison que j’ignore totalement, aucun autre protocole qu’ICMP n’a jamais fonctionné pendant nos tests, si d’aucuns ont une explication rationelle, je suis toutes ouïes. Le problème est résolu en utilisant les interfaces physiques.

IPsec. À l’évocation de ce terme technique, vous avez avalé d’un trait votre Gin Tonic, vous éteignez votre écran en espérant qu’il s’agisse d’un mauvais rève et vous décrivez des cercles dans votre bureau en vous frappant la tête avec une règle metallique.
Je le sais, j’étais pareil.

Et puis, avec l’ami mat, nous avons lu, épluché, factorisé, testé, pesté, hurlé, et finalement, je vous propose un petite petite bafouille sur l’art de mettre en place un tunnel IPsec entre deux machines NetBSD. Ouais.

Il me semble que cette configuration est assez classique, jugez plutot: une passerelle, chez vous, disposant d’un bridge vers un réseau quelconque d’opérateur qui fournit une adresse IP fixe publique (si ce n’est pas le cas, vous savez ce qu’il vous reste à faire), et de l’autre coté, une machine dédiée dont vous disposez chez l’un des multiples hébergeurs low-cost aujourd’hui disponibles.
Petite particularité, cette dernière, dans mon cas, est une machine virtuelle NetBSD, un domU hebergé par un dom0 Debian/GNU Linux.

En raison de cette particularité, la première étape consiste à manipuler iptables afin de translater les differents protocoles nécessaires à IPsec directement vers ma machine virtuelle. Sur mon dom0, j’ajoute donc les règles suivantes:

# isakmp
-A PREROUTING -i eth0 -p udp -m udp --dport 500 -j DNAT --to-destination 192.168.2.1:500 
# isakmp + nat-t
-A PREROUTING -i eth0 -p udp -m udp --dport 4500 -j DNAT --to-destination 192.168.2.1:4500 
# protocole ESP
-A PREROUTING -i eth0 -p esp -j DNAT --to-destination 192.168.2.1 
# protocole AH
-A PREROUTING -i eth0 -p ah -j DNAT --to-destination 192.168.2.1 

Nous considérerons que l’IP publique de cette machine est 1.2.3.4, l’IP privée du domU est 192.168.2.1.

Le logiciel que nous utiliserons pour établir notre tunnel IPsec, d’un coté et de l’autre, sera le fâmeux racoon.

Je vous jette en pâture la configuration simplifiée que j’utilise, cette dernière étant expliquée point par point à cette adresse:

# cat /etc/racoon/racoon.conf
path pre_shared_key "/etc/racoon/psk.txt";

padding {
    maximum_length 20;
    randomize off;
    strict_check off;
    exclusive_tail off;
}

listen
{
    isakmp 192.168.2.1 [500];
}

remote anonymous
{
    exchange_mode aggressive;
    dpd_delay 20;

    weak_phase1_check on;

    proposal
    {
        encryption_algorithm 3des;
        hash_algorithm sha1;
        authentication_method pre_shared_key;
        dh_group 2;
    }
}

sainfo anonymous
{
    pfs_group 2;
    encryption_algorithm 3des;
    authentication_algorithm hmac_sha1;
    compression_algorithm deflate;
}

Notez que je fais écouter isakmp sur l’adresse privée du domU.
Il faudra créer le fichier /etc/racoon/psk.txt avec des droits stricts (0600), qui contiendra l’adresse IP du peer et une passphrase:

# cat /etc/racoon/psk.txt
5.6.7.8 unepassphrasedunfortbeaugabarit

5.6.7.8 étant l’IP publique de ma passerelle.
Coté passerelle, justement, nous créons l’exacte copie de cette configuration en remplaçant l’ip d’écoute de isakmp et l’ip publique présente dans le fichier /etc/racoon/psk.txt par l’IP publique de notre machine hébergée (1.2.3.4, donc).

Ceci étant fait, il faut maintenant indiquer au noyau pour quels sous-réseaux il est nécessaire de crypter le trafic IP. Cette indication est donnée via l’outil setkey, qui lira le fichier /etc/ipsec.conf sous NetBSD (nous y reviendrons). Un peu de concentration, voici son contenu sur la machine hébergée:

# on fait le ménage
flush;
spdflush;
# et on indique nos routes
spdadd 10.0.0.1/32 10.0.0.2/32  any -P out ipsec esp/tunnel/192.168.2.1-5.6.7.8/require;
spdadd 10.0.0.2/32 10.0.0.1/32 any -P in ipsec esp/tunnel/5.6.7.8-192.168.2.1/require;

Ici, 10.0.0.1 est le “réseau” (une IP unique dans mon cas) joignable à travers IPsec, via le tunnel établi entre l’IP privée de mon domU et l’IP publique de ma passerelle. De l’autre côté, le “réseau” est 10.0.0.2.
Afin de clarifier les choses, voici la configuration coté passerelle:

flush;
spdflush;
spdadd 10.0.0.2/32 10.0.0.1/32  any -P out ipsec esp/tunnel/5.6.7.8-1.2.3.4/require;
spdadd 10.0.0.1/32 10.0.0.2/32 any -P in ipsec esp/tunnel/1.2.3.4-5.6.7.8/require;

Miroir miroir, c’est suykidikihé, on observe que la configuration est l’exacte symétrie de celle présente sur la machine hébergée à cette difference près que notre passerelle s’adresse à une IP publique, le dom0, de l’autre coté, s’occuppe de translater tout ce merdier en IP privée.
Ça va, vous suivez toujours ?
Il ne reste qu’une opération à mener pour que ces réseaux se voient: router effectivement ces divers réseaux entre eux; mais voila, pour l’instant les IPs endpoint du tunnel IPsec n’existent pas, et pour pallier à cela, nous allons une fois de plus abuser de l’ami loopback nous allons utiliser des alias sur les interfaces physiques (virtuelles dans le cas du domU) . Par exemple, sur notre domU:

# ifconfig xennet0 alias 10.0.0.1 netmask 255.255.255.255

Et sur notre passerelle:

# ifconfig sip0 alias 10.0.0.2 netmask 255.255.255.255

Reste à effectivement router ces “réseaux” entre eux, par exemple sur la passerelle:

# route add -host 10.0.0.1 10.0.0.2

Avant d’automatiser tout ce petit monde, vous pouvez d’ores et déjà réaliser quelques tests “live”. Chargez d’abord vos règles SPD des deux côtés:

# setkey -f /etc/ipsec.conf

Puis démarrez racoon en mode debug + verbose, sans passer en tâche de fond:

# racoon -F -d -v -f /etc/racoon/racoon.conf

Une fois satisfaits, nous allons pouvoir automatiser ces opérations afin qu’elles soient prises en compte à chaque boot. Non, nous n’allons pas écrire un script à la con.
Tout d’abord, nous préparons nos interfaces d’alias à l’aide du fichier /etc/ifaliases, sur notre machine hebergée par exemple:

# cat /etc/ifaliases
10.0.0.1 xennet0 255.255.255.255

Puis nous mettons en place les routes statiques:

# cat /etc/route.conf 
host 10.0.0.2 10.0.0.1

Enfin, nous indiquons à rc qu’il devra charger la base SPD et démarrer racoon à l’aide du fichier /etc/rc.conf:

ipsec=YES
racoon=YES

Et nous y voila, une connectique sûre, standard et bidirectionelle en un tournemain.

En terme de latence, ça donne ça:
Sans IPsec

64 bytes from 1.2.3.4: icmp_seq=0 ttl=52 time=21.770 ms

Avec IPsec

64 bytes from 10.0.0.1: icmp_seq=0 ttl=255 time=21.869 ms

Tranquille hein.

Je vous livre en sus les quelques liens qui nous ont aidé à peaufiner notre configuration:

  • http://www.kame.net/newsletter/20001119/
  • http://www.netbsd.org/docs/network/ipsec/
  • http://www.netbsd.org/docs/network/ipsec/rasvpn.html
  • http://wtf.hijacked.us/wiki/index.php/IPSEC-Racoon
  • http://www.mad-hacking.net/documentation/linux/networking/ipsec/nat-vpn.xml
  • http://www.lacave.net/~fred/racoon/config.html

Et vous souhaite une bonne nuit.

Rapid’CGI PHP, nginx et NetBSD

Tags: , , ,
3 Comments »

Update

Le post ci-dessous est à considérer “historique”, car depuis pkgsrc-2012Q2, php-fpm est disponible en standard et se configure le plus aisemment du monde.


Il y a une foultitude de documentations sur la façon de faire tourner PHP via fastCGI sur un nginx, et à chaque fois, j’ai l’impression de lire des tambouilles copiées/collées de ci et de là. Ça cause de scripts (non portables la plupart du temps), de wrappers, et autres solutions capillotractées, et ça me plaît pas. En dépilant un peu, j’ai abouti à une solution que je trouve élégante… sous NetBSD evidemment :)

Tout d’abord, il s’agit de compiler PHP avec le support fastCGI, sans pollution avec le module CGI. Ceci est réalisé grâce au fichier /etc/mk.conf et la directive suivante:

PKG_OPTIONS.php=        -cgi fastcgi

Un make install clean plus loin, on peut s’assurer du support fastCGI d’un des binaires générés de cette façon:

$ /usr/pkg/libexec/cgi-bin/php -h|grep -i bind
  -b | Bind Path for external FASTCGI Server mode

Il existe dans pkgsrc un outil spécialement dédié à gérer ce type d’implémentation, il s’agit de www/spawn-fcgi, que nous installons donc sans hésiter. spawn-fcgi a le bon goût d’être controlé par le fichier /etc/rc.conf, ainsi, après avoir copié /usr/pkg/share/examples/rc.d/spawnfcgi dans le repertoire /etc/rc.d, on configure le logiciel de cette façon:

$ grep spawn /etc/rc.conf
spawnfcgi=YES
spawnfcgi_jobs="php"
spawnfcgi_php_command="/usr/pkg/libexec/cgi-bin/php"
spawnfcgi_php_args=""
spawnfcgi_php_user="nginx"
spawnfcgi_php_address="127.0.0.1"
spawnfcgi_php_port="9000"
spawnfcgi_php_children="3"

Attention toutefois, il existe un minuscule bug dans rc.d/spawnfcgi que j’ai signalé au mainteneur, voici le patch trivial à appliquer:

--- /usr/pkg/share/examples/rc.d/spawnfcgi      2011-07-24                      
12:57:38.000000000 +0200                                                        
+++ /etc/rc.d/spawnfcgi 2011-07-24 17:16:49.000000000 +0200                     
@@ -38,6 +38,7 @@                                                               
                job_user=$(eval echo \$${name}_${job}_user)                     
                job_cwd=$(eval echo \$${name}_${job}_cwd)                                       job_socket=$(eval echo \$${name}_${job}_socket)                 
+               job_port=$(eval echo \$${name}_${job}_port)                     
                job_socket_mode=$(eval echo \$${name}_${job}_socket_mode)       
                job_address=$(eval echo \$${name}_${job}_address)               
                job_children=$(eval echo \$${name}_${job}_children)

Update bon, on est jamais mieux servi que par soi-même toussa, j’ai donc corrigé le package dans pkgsrc current. Un ptit cvs up -dP -rHEAD et tout devrait rouler.
Nous pouvons alors démarrer spawnfcgi comme n’importe quel autre service:

$ sudo /etc/rc.d/spawnfcgi start

Et de constater:

$ ps axuww|grep php
nginx     795  0.0  0.8  26412  8012 ?       Is    5:16PM  0:00.17 /usr/pkg/libexec/cgi-bin/php 
nginx   18322  0.0  0.7  26412  7816 ?       Is    5:16PM  0:00.14 /usr/pkg/libexec/cgi-bin/php 
nginx   22540  0.0  0.8  26412  8012 ?       Is    5:16PM  0:00.18 /usr/pkg/libexec/cgi-bin/php 

Eeeeeexcellent Smithers.

Il ne reste alors plus qu’à configurer nginx pour qu’il passe à PHP en mode fastCGI les pages de script à interpréter:

        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /home/user/www$fastcgi_script_name;
            include        /usr/pkg/etc/nginx/fastcgi_params;
        }

Il faudra evidemment prendre soin de remplacer /home/user/www par le chemin de votre documentroot. Il doit d’ailleurs certainement y avoir une variable pour s’épargner cela…

On oublie pas le petit phpinfo() qui va bien:

Jouons à cache-cache

Tags: , , ,
4 Comments »

Aujourd’hui, en raison des diverses lois liberticides mises en oeuvre pour controler l’activité des usagers sur Internet dans notre beau pays de la plainte, je me suis abonné à un très bon service de VPN fourni par la société Suédoise VPNtunnel.

Le service est impeccable, la conf OpenVPN fonctionne out-of-the-box, et ainsi la route par defaut de ma machine client prend le chemin de la Suède. Nickel.

Mais vous me connaissez, j’aime bien me compliquer la vie.
Le service en question ne fournit pas d’IP fixe, et c’est bien normal au vu de l’objectif même de l’offre; seulement voila, la machine que j’ai raccordé à ce service n’est pas une bête workstation, mais plutot un serveur situé “quelque part”. Évidemment, je me connecte via ssh à cette machine, et il m’est fort désagréable de devoir retrouver son IP en permanence. Pas question de bidouiller un truc à base de dynamic DNS, on est pas des sauvages tout de même.

Le problème, je vous le donne en mille, c’est que lorsque je ssh vers l’IP publique habituelle de cette machine, le paquet de retour emprunte la route par défaut, le tunnel donc, et que le serveur en question, c’est une machine virtuelle, dont le port SSH est translaté par le dom0. Oui je sais ça commence à donner mal à la tête. En un mot comme en cent, la connexion SSH n’aboutit jamais, passant par un endroit et sortant par un autre.

La solution: PF le magnifique !

Je vous entretenais il y a quelques temps déjà de la fabuleuse directive route-to, mais cette dernière ne s’applique pas au cas présent. Fort heureusement, sa soeur jumelle, reply-to réalise exactement le travail voulu, et ce en 2 coups de cuiller à pot. Démonstration:

Sur mon dom0, une machine Debian/GNU Linux, je redirige le traffic du port 2323 sur le port 22 de ma machine virtuelle NetBSD de cette façon:

-A PREROUTING -i eth0 -p tcp -m tcp --dport 2323 -j DNAT --to-destination 192.168.0.8:22
-A POSTROUTING -s 192.168.0.8/32 -j MASQUERADE # ici, on NAT la sortie de sorte que le domU puisse répondre au client

Mais lorsque le domU souhaite répondre à l’IP qui le sollicite sur le port 22, il emprunte sa route par défaut, et nous nous retrouvons dans un bon vieux cas de routage asymétrique, la lose.
On peut lire dans le man de pf.conf la prose suivante:

     reply-to
           The reply-to option is similar to route-to, but routes packets that
           pass in the opposite direction (replies) to the specified inter-
           face.  Opposite direction is only defined in the context of a state
           entry, and reply-to is useful only in rules that create state.  It
           can be used on systems with multiple external connections to route
           all outgoing packets of a connection through the interface the
           incoming connection arrived through (symmetric routing enforce-
           ment).

Et j’ai envie de dire “pile poil”. Voyons ce que cela nous donne:

real_if="xennet0"
gateway="192.168.0.254"

direct_ports="{ 22,80,443 }"

pass in quick log on $real_if reply-to ($real_if $gateway) proto tcp \
        from any to any port $direct_ports

Wooooh, trop balèse Watson !

Moyennant ces quelques lignes, nous pouvons constater, heureux:

imil@tatooine:~$ telnet foobar.imil.net 2323
Trying 1.2.3.4...
Connected to foobar.imil.net.
Escape character is '^]'.
SSH-2.0-OpenSSH_5.0 NetBSD_Secure_Shell-20080403-hpn13v1

C’est la classe ou bien ?

Les mecs en noir

Tags: , , , ,
No Comments »

Puisqu’on en parle, voici la liste de quelques MIBs nécessaires à l’utilisation d’OIDs “textuels” lors de l’interrogation via SNMP d’un Juniper J-Series, en particulier ceux relatifs à l’obtention d’informations sur le chassis et la pile BGP:

  • mib-SNMPv2-SMI.txt
  • mib-SNMPv2-TC.txt
  • mib-jnx-bgpmib2.txt
  • mib-jnx-chassis.txt
  • mib-jnx-exp.txt
  • mib-jnx-smi.txt
  • mib-rfc2571.txt
  • mib-rfc2575.txt
  • mib-rfc2851.txt

Ces derniers se téléchargent à partir de cette adresse.

Afin de les utiliser avec snmpwalk, il vous suffira de les déposer dans le repertoire ${HOME}/.snmp/mibs de votre machine UNIX; il est alors possible d’interroger votre équipement de cette façon:

imil@unixbox:~$ snmpwalk -v1 -m all -c public adresse.du.routeur jnxBgpM2PrefixInPrefixesAccepted
BGP4-V2-MIB-JUNIPER::jnxBgpM2PrefixInPrefixesAccepted.0.ipv4.1 = Gauge32: 359798
BGP4-V2-MIB-JUNIPER::jnxBgpM2PrefixInPrefixesAccepted.1.ipv4.1 = Gauge32: 296945

De la même façon, il faudra indiquer à votre NMS les differentes MIB à charger si vous souhaitez utiliser des noms lisibles au lieu de leur expression numerique. Par exemple, avec MRTG, à l’aide de la variable LoadMIBs.

Wesh bien ou bien ?

Tags: , ,
3 Comments »

Ça cause pas des masses ici hein… ouais ouais je sais, mais nan j’ai rien laché, je suis juste très accaparé par ma boite, beaucoup d’activité, beaucoup de clients, beaucoup de R&D. Difficile de trouver un instant libre ces temps cis.

Je profite de ce long week end pour noter ici un boût de conf pour lequel j’ai mis quelques heures à rassembler les pièces.
Comme vous vous en rappelez peut-être, ce sont des Juniper J2350 qui routent les paquets magiques de mon réseau pro, et comme l’activité s’accélère, je vais certainement passer au modèle supérieur, possiblement J6350 ou MX5, plus puissants, tant en terme de CPU que de quantité de mémoire.

Mais avant d’annoncer la facture, il me faut des données tangibles, et en particulier, justement, la mémoire et le CPU utilisés pour router 500Mbps par datacenter. Naturellement, ces routeurs supportent le protocole SNMP, l’activation de ce dernier est simplissime:

[edit]
foo@routeur# set snmp community public authorization  read-only 

On réduit l’accessibilité à ce protocole à une seule machine

[edit snmp]
foo@routeur# set community public clients 10.0.0.1/32

Enfin, on renseigne quelques valeurs de base

[edit snmp]
foo@routeur# set description "JUNOS J2350 - Equinix"
foo@routeur# set location "Equinix - Saint Denis"
foo@routeur# set contact "NBS-System - AS51335"

Moyennant quoi, gràce à la commande snmpwalk disponible dans la totalité de nos UNIX libres, nous pouvons visualiser l’ensemble de l’arbre des informations:

bar@unixbox$ snmpwalk -v1 -c public addresse.du.routeur

Ceci fait, il m’a fallu naviguer sur plusieurs sites officiels et non-officiels pour trouver les OID corresponsants au CPU et l’utilisation mémoire de ces équipements. Finalement, voici les 2 valeurs en question:

  • CPU load: 1.3.6.1.4.1.2636.3.1.13.1.8.9.1.0.0
  • Occuppation mémoire: 1.3.6.1.4.1.2636.3.1.13.1.11.9.1.0.0

Muni de ces valeurs, il est alors possible d’écrire un petit cfg MRTG. Pour le CPU:

WorkDir: /var/www/mrtg
Target[routeur.cpu]: 1.3.6.1.4.1.2636.3.1.13.1.8.9.1.0.0&1.3.6.1.4.1.2636.3.1.13.1.8.9.1.0.0:public@routeur
RouterUptime[routeur.cpu]: public@routeur
MaxBytes[routeur.cpu]: 100
Title[routeur.cpu]: routeur CPU Load
PageTop[routeur.cpu]: routeur CPU Load %
Unscaled[routeur.cpu]: ymwd
ShortLegend[routeur.cpu]: %
YLegend[routeur.cpu]: CPU Utilization
Legend1[routeur.cpu]: Active CPU in % (Load)
Legend2[routeur.cpu]:
Legend3[routeur.cpu]:
Legend4[routeur.cpu]:
LegendI[routeur.cpu]:  Active
LegendO[routeur.cpu]:
Options[routeur.cpu]: growright,gauge,integer,nopercent

Et pour la RAM:

WorkDir: /var/www/mrtg
Target[routeur.memory]: 1.3.6.1.4.1.2636.3.1.13.1.11.9.1.0.0&1.3.6.1.4.1.2636.3.1.13.1.11.9.1.0.0:public@routeur
RouterUptime[routeur.memory]: public@routeur
MaxBytes[routeur.memory]: 100
Title[routeur.memory]: routeur Memory usage
PageTop[routeur.memory]: routeur Memory usage %
Unscaled[routeur.memory]: ymwd
ShortLegend[routeur.memory]: %
YLegend[routeur.memory]: Memory usage
Legend1[routeur.memory]: Memory usage %
Legend2[routeur.memory]:
Legend3[routeur.memory]:
Legend4[routeur.memory]:
LegendI[routeur.memory]:  Active
LegendO[routeur.memory]:
Options[routeur.memory]: growright,gauge,integer,nopercent

Quelques minutes plus tard, voici un argumentaire imparable pour munir votre backbone de routeurs d’une capacité supérieure !




Comme dirait quelqun que je connais… “Y’A PAS ASSEZ’D'MÉMOAAAAAAAAAAAAAAAR !”

WP Theme & Icons based on GlossyBlue by N.Design Studio
Banner from www.trynthlas.com
Entries RSS Comments RSS Log in
Performance Optimization WordPress Plugins by W3 EDGE