Nous allons ici étudier les differentes méthodes de tunneling disponibles avec FreeBSD. Le tunneling nous permet d'encapsuler des sessions applicatives parfois dangeureuses comme la manipulation de courrier (POP/SMTP), l'IRC, la navigation web, FTP ou tout autre transmissions qui peut voir passer des mots de passe, au sein d'un tunnel crypté. Nous en avons retenus 2 méthodes : OpenSSH et OpenSSL/Stunnel.

SSH signifie Secure Shell. A l'origine SSH est un remplacement des Berkeley r* commandes tels que rsh, rlogin ou rcp considérées comme très peu sûres. SSH utilise pour sécuriser la transmission un tunnel crypté entre les 2 machines. SSH a rapidement dépassé toutes les attentes et il est devenu un remplacement intéressant pour telnet ou ftp lorsqu'ils sont nécessaires pour des utilisateurs réguliers possédant un compte sur la machine en leur offrant une méthode d'accès à distance hautement sécurisée et très bien supportée. En particulier OpenSSH est une version libre et recodée du protocole SSH et fournit un client et un serveur pour des nombreuses plate-formes unix. C'est lui que nous allons maintenant utiliser pour la configuration de SSH.

Tout d'abord nous allons éditer le fichier de configuration du daemon sshd.

huyhuy# ee /etc/ssh/sshd_config
------------------------------------ SNiP -------------------------------------
# This is ssh server systemwide configuration file.

Port 22
Protocol 2
ListenAddress IP # lorsque vous copierez ce fichier pour votre jail user
		 # pensez à mettre ici l'alias de votre jail.

HostKey
HostDsaKey /etc/ssh/ssh_host_dsa_key
ServerKeyBits 768
Ciphers AES128, blowfish, 3des
LoginGraceTime 60
KeyRegenerationInterval 3600
RhostsAuthentication no
RSAAuthentication yes
PermitRootLogin no

# Pour eviter les simili-flooding du a des tentatives de connexion repetees,
# nous installons une sorte de quotas au niveau de la gestion des connexions.
# 10 pour le nombre de connexions non auhentifiees, 40 pour le pourcentage de
# refus apres le premier nombre atteint, et 50 signifiant qu'au bout de 50
# connexions tout est refuse.
MaxStartups 10:40:50

# ici nous eliminons les vulnerabilites lies aux fichiers ~/.rhosts et
# ~/.shosts et a leurs relations de confiance.
IgnoreRhosts yes

# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
StrictModes yes
X11Forwarding no
X11DisplayOffset 10
PrintMotd yes
KeepAlive yes

# Syslog
SyslogFacility AUTH
LogLevel DEBUG

# ici nous empechons l'utilisation de passwords en texte clair même dans une
# communication tunnelee, prevenant ainsi les attaques mitm.
PasswordAuthentication no
PermitEmptyPasswords no

# Uncomment to disable s/key passwords
#SkeyAuthentication no
#KbdInteractiveAuthentication yes

# ces blocs sont relatifs a l'authentification kerberos
#KerberosAuthentication no
#KerberosOrLocalPasswd yes
#AFSTokenPassing no
#KerberosTicketCleanup no
#Kerberos TGT Passing does only work with the AFS kaserver
#KerberosTgtPassing yes

CheckMail yes
UseLogin yes

# nous ne le recommandons pas du fait de sa relative experimentalite mais cette
# ligne vous permet le cas echeant d'utiliser sftp.
#Subsystem sftp /usr/libexec/sftp-server
------------------------------------ SNiP -------------------------------------

Il ne nous reste plus maintenant qu'a editer encore une fois le fichier rc.conf afin de s'assurer que sshd se lancera bien au demarrage. Nous transformons donc la ligne sshd_enable=“NO” en sshd_enable=“YES” et nous lui adjoinions egalement la ligne sshd_flags=“-4” afin de limiter l'utilisation a des connexions IPv4.

Pour générer vos clés il vous suffira alors d'exécuter ssh-keygen.

Vous pourrez enfin décider de ne pas offrir de shell à vos utilisateurs distants. Ceci peut être effectuer à l'aide de chpass ou de chsh en précisant comme shell /sbin/nologin.

huyhuy# chsh -s /sbin/nologin user

Nous allons maintenant développer une option tres intéressante de SSH qui est le tunneling. Nous exécutons la commande suivante:

huyhuy# ssh -N -f -L localport:localhost:remoteport user@remotehost

L'option -N nous met en tunnel only, l'option -f permet de faire tourner ssh en tache de fond et -L permet de preciser les donnees du tunnel qui sont le port local puis le port distant entre lesquels s'effectuera le tunnel. Puis il n'y a plus qu'à rentrer l'hôte distant comme d'habitude. Une fois le tunnel établit, toute connexion avec comme source le port local indiqué dans le tunnel et comme destination le port distant indiqué dans le tunnel, transitera au sein du tunnel SSH mis en place.

La seconde solution consiste à créer des tunnels SSL avec stunnel, c'est notamment la solution utilisée dans le cadre d'IRCS, le reseau IRC securisé. Pour ce faire, nous avons besoin d'OpenSSL qui est installé dans le catalogue cvsup src-all et de Stunnel que nous trouverons dans /usr/ports/security. En passant, en lieu et place du classique make install clean, vous pouvez essayer make all && make install qui effectue des vérifications supplémentaires …

huyhuy# cd /usr/ports/security/stunnel && make install clean

Puis pour lancer une connexion distante en mode client, nous executons la commande suivante

huyhuy# stunnel -c -r remotehost:remoteservice

L'option -c precise que nous sommes en mode client effectuant ainsi un tunneling, et l'option -r permet de preciser les données de l'hôte distant que sont l'adresse distante - qui peut etre une IP ou un domaine - et le service distant qui peut aussi bien être un port qu'un nom de service contenu dans /etc/services (en passant vous pouvez faire un copier/coller depuis http://www.iana.org/assignments/port-numbers). Vous pouvez également preciser un certificat permettant d'authentifier l'hôte distant (recommandé) et le verifier en ajoutant les options -v2 et -A path/to/ca.pem.

Nous abordons maintenant une dernière méthode de tunneling mais qui nous servira beaucoup plus à la mise en place d'un Virtual Private Network entre 2 LAN distants qu'on veut réunir par 2 passerelles IPSec - supposant que vous diposez à la fois d'une adresse publique et privée - plutôt qu'à une communication end-to-end. Nous allons donc maintenant aborder la mise en place des options de sécurité IPSec avec IPv4. Sous FreeBSD, nous nous servons pour se faire de la dual stack TCP/IP développée dans le cadre du projet KAME et qui supporte parfaitement IPv6 et IPSec. Vous pouvez obtenir plus d'information sur KAME à http://www.kame.net.

Nous devons tout d'abord configurer l'interface gif0 pour le tunneling IPv6/4 over IPv6/4 afin de créer le tunnel IPSec.

huyhuy# ifconfig gif0 create tunnel localhost_public_IP remote_public_IP

A ajouter également à rc.conf avec une entrée ifconfig_gif0.

Pour utiliser IPSec, le kernel manipule 2 bases de données à savoir la Security Policy Database (SPD) qui permet de définir les règles d'application du tunnel IPSec avec notemment la spécification des associations de sécurité (SA) ; et la Security Association Database (SAD) qui contient les clés des SA correspondantes. L'administrateur doit tout d'abord configurer la policy de la SPD par l'intermediare de la commande setkey, le kernel se réfère ensuite à la SPD pour vérifier si un paquet requiert IPSec, si c'est le cas, il utilise la SA spécifiée dans la SAD. En cas d'erreur ou d'impossibilité d'obtenir la clé, le kernel fait appelle au daemon IKE racoon qui va effectuer l'échange de clés afin de permettre la SA normalement en modifiant directement la SAD. Avec une syntaxe et une utilisation similaire à ipfw, nous utilisons setkey pour vider les databases avant d'y ajouter nos nouvelles policy.

huyhuy# setkey -FP
huyhuy# setkey -F

Puis nous entrons notre policy dans la SPD sous la forme action net_src net_dst upperspec -P direction action \ protocol/mode/gw_src-gw_dst/level

Ensuite vient le mode qui peut être transport dans lequel IPSec intervient entre la couche OSI 4 et 3 ainsi le paquet final utilise les adresses IP claires, ou tunnel dans lequel IPSec intervient après la couche OSI 3 en rajoutant un header et en encryptant la totalité du paquet jusqu'à la passerelle de destination. Nous avons ensuite l'adresse de la passerelle source et de la passerelle de destination et pour finir le level qui peut avoir comme valeur default pour utiliser les variables kernel par défaut, use pour utiliser une SA sinon continuer normalement ou require pour imposer l'utilisation d'une SA. Ci-dessous les variables sysctl que nous mettons toutes à default. Suivi d'une dernière variable qui nous permet de rejeter (discard) les paquets tentant d'utiliser le VPN sans IPSec parce que ne correspondant pas à la policy ; et enfin nous activons la compatibilité Explicit Congestion Notification pour IPSec facilitant la gestion active de queues de routage et récemment ajouté à IP par la RFC 3168.

huyhuy# sysctl -w net.inet.ipsec.esp_trans_deflev=1
huyhuy# sysctl -w net.inet.ipsec.esp_net_deflev=1
huyhuy# sysctl -w net.inet.ipsec.ah_trans_deflev=1
huyhuy# sysctl -w net.inet.ipsec.ah_net_deflev=1
huyhuy# sysctl -w net.inet.ipsec.def_policy=0
huyhuy# sysctl -w net.inet.ipsec.ecn=1

huyhuy# setkey -c << EOF
spdadd internal_range/24 remote_internal_range/24 any -P out ipsec \
       esp/tunnel/localhost_public_IP-remote_public_IP/default;
spdadd remote_internal_range/24 internal_range/24 any -P in ipsec \
       esp/tunnel/remote_public_IP-localhost_public_IP/default;

Maintenant que notre tunnel IPSec est prêt à servir, il nous reste à configurer Racoon afin d'assurer l'échange des clés symmétriques et SAs. Pour obtenir notre configuration IPSec, nous modifions rc.conf pour exécuter setkey au démarrage avec le fichier ipsec.conf en argument.

ipsec_enable="YES"
ipsec_file="/etc/ipsec.conf"
------------------------------------ SNiP -------------------------------------
flush
spdflush

# SAD entry
add localhost_public_IP remote_public_IP ah 1500 -A hmac-sha1 123ABC456EFG789HIJ10
add remote_public_IP localhost_public_IP ah 1600 -A hmac-sha1 123ABC456EFG789HIJ10
add localhost_public_IP remote_public_IP esp 1500 -E blowfish-cbc 123ABC456EFG789H
add remote_public_IP localhost_public_IP esp 1600 -E blowfish-cbc 123ABC456EFG789H

# SPD entry
spdadd internal_range/24 remote_internal_range/24 any -P out ipsec \
       esp/tunnel/localhost_public_IP-remote_public_IP/default;
spdadd remote_internal_range/24 internal_range/24 any -P in ipsec \
       esp/tunnel/remote_public_IP-localhost_public_IP/default;
------------------------------------ SNiP -------------------------------------

Nous définissons ensuite pour la configuration de racoon un fichier psk.txt contenant les clés utilisées pour l'identification dans la première phase de l'échange de clés.

huyhuy# ee /etc/racoon/psk.txt
remote_public_IP	shared_key

Puis nous nous occupons de racoon.conf lui-même que nous éditons à partir du fichier de configuration par défaut.

huyhuy# cp /usr/local/etc/racoon/racoon.conf.dist /etc/racoon.conf
huyhuy# ee racoon.conf
------------------------------------ SNiP -------------------------------------
path pre_shared_key "/etc/racoon/psk.txt" ;

# Padding options
padding
{
	maximum_length 20;
	randomize off;
	strict_check on;
	exclusive_tail off;
}

# Timing Options. Elles peuvent être modifiées par l'hôte distant.
timer
{
	counter 5;
	interval 10 sec;
	persend 1;
	phase1 30 sec;
	phase2 15 sec;
}

# Phase 1. anonymous signifie que cette phase est appliquée à tous les hôtes.
# Vous pouvez configurer des phases 1 et 2 pour des hôtes particuliers.
remote anonymous
{
	exchange_mode aggressive,main ;
	doi ipsec_doi;
	situation identity_only;
	nonce_size 16;
	lifetime time 1 min;    # sec,min,hour
	lifetime byte 5 MB;     # B,KB,GB
	initial_contact on;
	proposal_check obey;

	proposal
	{
		encryption_algorithm blowfish;
		hash_algorithm sha1;
		authentication_method pre_shared_key ;
		# groupe Diffie-Hellman
		dh_group 2 ;
	}
}

# Phase 2.
sainfo anonymous
{
	pfs_group 2;
	# temps de vie en seconde, minutes ou heures puis en bytes, kb, mb ou tb
	lifetime time 2 hour ;
	lifetime byte 100 MB ;
	encryption_algorithm 3des, blowfish, rijndael, twofish ;
	authentication_algorithm hmac_sha1, hmac_md5 ;
	# compression IPCOMP
	compression_algorithm deflate ;
}
------------------------------------ SNiP -------------------------------------

huyhuy# racoon -f /etc/racoon.conf

Nous ajoutons finalement une entrée dans la crontab afin que racoon se lance à chaque reboot :

@reboot racoon -f /etc/racoon.conf

PS : non abordé dans ce tips mais tout de même intéressant, l'outil vtun qui a l'intérêt d'encapsuler à peu près tout et n'importe quoi. Voir http://vtun.sf.net

PPS : ce tips est un constitué d'extrait d'un texte sur la sécurisation freebsd. Une version complète peut être trouvé sur http://minithins.net

– eberkut

freebsd/tunneling.txt · Last modified: 2010/01/12 13:29 (external edit)