Installation du parefeu pf avec FreeBSD 10.1


Où l’on va sécuriser nos accès et ajouter un firewall Pour l’instant notre machine est un poil vulnérable. ssh écoute sur le port par défaut, nous avons autorisé la connexion de l’utilisateur root via ssh, nous n’avons pas de firewall.

Nous allons donc maintenant rationaliser tout cela. Tout d’abord en faisant en sorte qu’un utilisateur désigné (sans doute le vôtre) pourra devenir root en utilisant la commande sudo. Nous allons ensuite changer le port d’écoute de ssh et enfin nous allons installer un firewall en l’occurrence pf (packet filter).

Installation et configuration de sudo

L’installation de sudo se fait une fois de plus avec pkg :

1
# pkg install sudo

Ici pas d’instruction à la fin de l’installation. Il va falloir lire les pages de manuel de sudo (ou lire la suite de cet article).

Le fichier de configuration de sudo est /usr/local/etc/sudoers. Nous allons éditer ce fichier pour faire en sorte que les utilisateurs du groupe wheel puissent devenir root.

Attention : il est préférable de ne pas éditer ce fichier directement, mais d’utiliser la commande visudo qui lance votre éditeur préféré et réalise des vérifications au moment de la sauvegarde. Cela évite d’avoir un fichier sudoers complètement inutilisable qui risquerait de bloquer toute tentative de passer root et obligerait à lancer la console d’administration pour réparer les dégâts.

Assurons-nous que notre utilisateur existe et fait partie du groupe wheel :

1
2
#  id jacques
uid=5001(jacques) gid=5001(jacques) groups=5001(jacques),6002(macdev),7005(foucry)

L’utilisateur existe, mais n’appartient pas au groupe wheel. Nous allons donc l’ajouter à ce groupe. Que ce groupe ne soit pas un groupe géré par LDAP n’a pas d’importance, c’est même plus simple puisque nous n’avons pas à modifier le LDAP.

1
2
3
# pw group mod wheel -m jacques
# id jacques
uid=5001(jacques) gid=5001(jacques) groups=5001(jacques),0(wheel),6002(macdev),7005(foucry)

Cette fois-ci c’est bon notre utilisateur jacques appartient bien au groupe wheel. Toutefois, il ne peut toujours pas devenir root avec la commande sudo :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
% sudo -s

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

Password:
Sorry, try again.
Password:
Sorry, try again.
Password:
sudo: 3 incorrect password attempts

Nous devons configurer sudo. Sa configuration est extrêmement simple dans notre cas (on peut faire bien plus compliqué, mais je vous laisserais le découvrir par vous même). Il faut éditer le fichier /usr/local/etc/sudoers. Souvenez-vous, on utilise la commande visudo qui lance l’éditeur pas défaut (souvent, c’est vi). Recherche la ligne # %wheel ALL=(ALL) ALL et decommentez là (enlevez le # et l’espace en début de ligne) et sauvegardez le fichier.

  Il existe une ligne similaire à celle que nous venons de traiter (# %wheel ALL=(ALL) NOPASSWD: ALL) qui accorde les mêmes droits au membre de wheel, mais sans qu’il soit nécessaire de taper le mot de passe de l’utilisateur. Je n’aime pas du tout ce genre de choses qui sont beaucoup trop dangereuses.

Après avoir sauvegardé le fichier, si vous refaites une tentative vous verrez que cela ne fonctionne toujours pas. Il manque quelque chose, la comfiguration de PAM. En effet, PAM est sollicité par sudo pour vérifier le mot de passe. Si le module sudo de PAM n’est pas configuré, la vérification échoue à chaque fois. Nous allons donc dans le répertoire /etc/pam.d et nous y éditons le fichier sudo (et nous le créons s’il n’existe pas) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#
# $FreeBSD: release/10.0.0/etc/pam.d/su 219663 2011-03-15 10:13:35Z des $
#
# PAM configuration for the "su" service

auth            sufficient      pam_opie.so                     no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so               no_warn allow_local
#auth           sufficient      pam_krb5.so                     no_warn try_first_pass
#auth           sufficient      pam_ssh.so                      no_warn try_first_pass
#auth           optional        /usr/lib/pam_echo.so            test
auth            sufficient      pam_unix.so                     no_warn try_first_pass
auth            optional        /usr/lib/pam_echo.so            openldap alive ??? wrong local passwd ???
auth            required        /usr/local/lib/pam_ldap.so      no_warn try_first_pass
#auth           sufficient      /usr/lib/pam_radius.so          no_warn

# account
account         required        pam_nologin.so
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        /usr/local/lib/pam_ldap.so      ignore_unknown_user ignore_authinfo_unavail
account         required        pam_unix.so

# session
session         required        pam_permit.so

# password

Après la sauvegarde de ce fichier, nous pouvons à nouveau tester la commande sudo avec notre utilisateur :

1
2
3
4
% sudo -s
Password:
# id
# uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)

La différence est subtile (au niveau du prompt surtout), mais l’utilisateur jacques est bien devenu root.

Changement du port d’écoute de ssh

Cette configuration est bien plus simple à faire. Toutefois vous risquez fort de perdre les connexions établies. En cas de pépin, il sera nécessaire d’utiliser la console IDRAC. Nous devons modifier le fichier /etc/ssh/sshd_config.

Sous la ligne # Port 22 nous allons en ajouter une, similaires, à part le numéro de port que je vous laisse choisir (sans vous dévoilez le mien):

1
Port 22022 # ceci est un exemple, ne compter pas dessus pour vous connecter à ma machine

Nous allons aussi à nouveau interdire les connexions directes de root en changeant le paramètre PermitRootLogin. Il suffit de supprimer la ligne que nous avions ajoutée. Sauvegardez le fichier. Ensuite, il faut relancer le service ssh :

1
# service sshd restart

Tentons une connexion sur le nouveau port avec l’utilisateur autorisé à faire un sudo (j’ai masqué quelques informations qui permettraient d’identifier ma machine) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
% ssh -p 22022 jacques@_mon_adresse_ip_
The authenticity of host '[_mon_adresse_ip_]:22022 ([_mon_adresse_ip_]:22022)' can't be established.
RSA key fingerprint is 66:08:bd:b7:89:f2:a0:1a:55:fb:20:1b:2d:ad:f3:39.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[_mon_adresse_ip_]:22022' (RSA) to the list of known hosts.
Last login: Tue Apr 21 15:50:43 2015 from 00-00-00-00.dsl.ovh.fr
FreeBSD 10.1-RELEASE (GENERIC) #0 r274401: Tue Nov 11 21:02:49 UTC 2014

Welcome to FreeBSD!

Release Notes, Errata: https://www.FreeBSD.org/releases/
Security Advisories:   https://www.FreeBSD.org/security/
FreeBSD Handbook:      https://www.FreeBSD.org/handbook/
FreeBSD FAQ:           https://www.FreeBSD.org/faq/
Questions List: https://lists.FreeBSD.org/mailman/listinfo/freebsd-questions/
FreeBSD Forums:        https://forums.FreeBSD.org/

Documents installed with the system are in the /usr/local/share/doc/freebsd/
directory, or can be installed later with:  pkg install en-freebsd-doc
For other languages, replace "en" with a language code like de or fr.

Show the version of FreeBSD installed:  freebsd-version ; uname -a
Please include that output and any error messages when posting questions.
Introduction to manual pages:  man man
FreeBSD directory layout:      man hier

Edit /etc/motd to change this login announcement.

On dirait que cela fonctionne.

Configuration du firewall

Sous FreeBSD le firewall se nomme pf (Packet Filter). Il est accompagné d’un autre logiciel chargé de gérer les traces, pflog. Nous allons installer ces deux éléments et voir comment les configurer pour continuer à autoriser les connexions ssh sur notre port personnalisé et interdire le reste. Nous autoriserons ensuite au fur et à mesure des besoins. Nous n’avons rien à installer, pf et pflog sont installés avec le système. En revanche, nous avons besoin d’indiquer au système que nous voulons voir ces services démarrer au lancement de la machine. Cela se fait, comme pour slapd, dans le fichier /etc/rc.conf. Souvenez-vous, dans ce fichier on indique aussi les paramètres des services :

1
2
3
4
pf_enable="YES"
pf_rules="/etc/pf.conf"
pflog_enable="YES"
pflog_logfile="/var/log/pflog"

Le fichier de configuration

Le point le plus important est le fichier de configuration. Il ne faut pas se tromper dans son écriture.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
if="bce0"

# ok loopback
set skip on lo0

# allow DNS (without UDP state)
pass out quick proto udp from any to any port = 53 no state
pass in quick proto udp from any port = 53 to any no state
pass out quick proto tcp from any to any port = 53 flags S/SA keep state
pass in quick proto tcp from any to any port = 53 flags S/SA keep state

# Allow ssh in
pass in log quick on $if proto tcp from any to any port = 22022 flags S/SA keep state

# I can get out
pass out quick proto tcp from any to any flags S/SA keep state
pass out quick inet proto { udp, icmp } from any to any keep state
pass in quick inet proto { udp, icmp } from any to any keep state

# block everything else
block log quick all

Ce que cela signifie :

  • On défini les interfaces réseau (ici il n’y en a qu’une, bce0) ;
  • On laisse tranquille l’interface de loopback, lo0 ;
  • On autorise les flux DNS (sur le port 53) en UDP et en TCP. On UDP on ne gére pas l’état de la connexion, en TCP on conserve l’état. Ces flux ne sont pas mis dans le fichier de trace (quick) ;
  • On autorise les connexions qui viennent sur l’interface définie ($if), en tcp depuis n’importe où (from any) vers n’importe où (to any) sur le port 22022 (le port ssh que nous avons défini plus haut). Nous conservons l’état (pour maintenir les connexions) et les flux seront mis dans les traces (log).
  • On autorise la sortie (out) en tcp, depuis n’importe où (from any) vers n’importe où (to any) en conservant l’état et les flux ne sont pas tracés ;
  • On autorise le ping (ICMP) en udp, dans les deux sens, en conservant l’état ;
  • Enfin, on bloque tout le reste, sans le mettre dans le fichier de trace.

Soyez prudent à la mise en route de votre firewall, vous pourriez perdre toutes vos connexions établies et risquer de ne pas pouvoir en établir de nouvelle. C’est alors avec la console que vous vous sortiriez d’affaire. pf dispose d’une commande de contrôle, pfctl qui permet, entre autres, de vérifier la syntaxe des règles (mais pas leur bien fondés).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# pfctl -vnf /etc/pf.conf
if = "bce0"
set skip on { lo0 }
pass out quick proto udp from any to any port = domain no state
pass in quick proto udp from any port = domain to any no state
pass out quick proto tcp from any to any port = domain flags S/SA keep state
pass in quick proto tcp from any to any port = domain flags S/SA keep state
pass in log quick on bce0 proto tcp from any to any port = 22022 flags S/SA keep state
pass out quick inet proto udp all keep state
pass out quick inet proto icmp all keep state
pass in quick inet proto udp all keep state
pass in quick inet proto icmp all keep state
pass out quick proto tcp all flags S/SA keep state
block drop log quick all

À première vue, tout va bien, je tente le démarrage du firewall et de sa trace :

1
2
# service pf start
# service pflog start

Lecture du fichier de trace

Le fichier de trace de pf, /var/log/pflog est assez particulier. Ce n’est en fait pas un fichier que l’on peux parcourir comme on le désire, mais plutôt une interface réseau spéciale. C’est pourquoi la commande more /var/log/pf.log est inopérante et qu’on utilise la commande tcpdump :

1
# tcpdump -n -e -ttt -r /var/log/pflog

De même, pour voir les traces au fil de l’eau on n’utilisera pas tail -f, mais à nouveau tcpdump :

1
# tcpdump -n -e -ttt -i pflog0

Regardez pendant une dizaine de minutes la trace de votre pflog, vous serez effarés par ce qu’il peut contenir et ce qui arrive sur votre machine.

powered by FreeBSD