# Le pare-feu

Il nous faut installer un pare-feu sur notre raspi pour éviter les intrusions.

Nous allons limiter les machines susceptibles de se connecter à celles de notre réseau local, et également limiter les ports accessibles sur notre réseau.

Nous allons utiliser IPtables et Firewalld.

J'aurai préféré utiliser nftables qui est le successeur de iptables, mais j'ai eu quelques soucis à l'utilisation. Peut-être est-ce pour ça que la distribution RaspiOS a configuré firewalld avec IPtables...

## Installation de IPtables

IPtables est installé par défaut : rien à faire ici.

## Test

Si on tape :

    pi@raspberrypi:~ $ sudo iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination

    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    pi@raspberrypi:~ $

On voit que c'est iptables qui a été chosi par RaspiOS.

D'abord, il faut comprendre comment fonctionne Firewalld. Je me suis basé sur les sites suivant :

- lw.net
- How to get started with Firewalld
- tutorial points
- la documentation officielle
- introduction-to-firewalld
- La documentation de Fedora
- it connect

La documentation de Fedora est la plus compréhensible.

### La notion de zones

Firewalld définit 9 zones qui sont en fait des règles de pare-feux par défaut. Une zone va par exemple bloquer toute entrée sauf SSH, une autre permettre l'accès en HTTP et HTTPS. Ces zones correspondent à des utilisations types, comme un serveur dans une DMZ, ou un serveur chez soi, un serveur public, etc.

On peut imaginer une zone émail qui ne laisserait passer que les ports spécifiques à l'émail et DNS bien sûr.

Il est possible de créer des zones personnelles.

Un certain nombre de zones sont prédéfinies. Voyons leur contenu.

### Les différentes zones

Les différentes zones sont :

- trusted: non modifiable
- home: modifiable
- work: modifiable
- internal: modifiable
- dmz: modifiable
- public: modifiable
- external: modifiable
- block: non modifiable
- drop: non modifiable

Une très bonne présentation des zones est ici : it connect

### Les fichiers de configuration

Ils sont situés à 2 endroits :

- /usr/lib/firewalld/ : il ne faut pas toucher au contenu de ce répertoire
- /etc/firewalld/ : c'est là que nous mettrons notre configuration, en copiant les fichiers de /usr/lib/firewalld si besoin est.

Dans le répertoire /etc/firewalld, le fichier firewalld.conf permet de configurer la zone par défaut, ainsi que le backend (iptables, nftables et autre).

La zone par défaut est public : pas de confiance, mais possibilité d'ajuster au cas par cas les règles. Le seul accès autorisé est l'accès ssh et dhcp.

### Quelques commandes

- Démarrer Firewalld:$ sudo systemctl start firewalld
- Stopper Fireawalld:$ sudo systemctl stop firewalld
- Tester le fonctionnement de Firewalld:$ sudo firewall-cmd --state
- Connaître les zones prédéfinies : $ sudo firewall-cmd --get-zones
- Connaître la zone par défaut :$ sudo firewall-cmd --get-default-zone
- Connaître la zone active :$ sudo firewall-cmd --get-active-zones

Exemples :

    pi@piras:~ $ sudo firewall-cmd --state
    running
    pi@piras:~ $

Le service tourne.

    pi@piras:~ $ sudo firewall-cmd --get-default-zone
    public
    pi@piras:~ $

La zone par défaut est : public

    pi@piras:~ $ sudo firewall-cmd --get-zones
    block dmz drop external home internal public trusted work
    pi@piras:~ $

Les zones prédéfinies sont : block dmz drop external home internal public trusted work

Quelle est la zone active : aucune !

    pi@piras:~ $ sudo firewall-cmd --get-active-zones
    pi@piras:~ $

Nous pouvons vérifier la zone en fonctionnement et l'interface réseau qui y est attachée :

    pi@piras:~ $ sudo firewall-cmd --list-all
    public
    target: default
    icmp-block-inversion: no
    interfaces:
    sources:
    services: dhcpv6-client ssh
    ports:
    protocols:
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:

    pi@piras:~ $

Aucune interface n'est attachée. Les seuls services autorisé sont : dhcp et ssh.

### Première étape de configuration

Nous allons utiliser les commandes en ligne de commande pour configurer Firewalld, mais il existe une GUI pour le faire graphiquement. Référez-vous aux liens que j'ai indiqués au-dessus.

- Définition de la zone par défaut : (public)

      pi@piras:~ $ sudo firewall-cmd --set-default-zone=public
      Warning: ZONE_ALREADY_SET: public
      success
      pi@piras:~ $

- Attribution de l'interface réseau à cette zone :

      pi@piras:~ $ sudo firewall-cmd --zone=public --change-interface=eth0
      success
      pi@piras:~ $

  Attention, ce changement n'est pas permanent ! (voir ci-dessous)

- Test :

      pi@piras:~ $ sudo firewall-cmd --list-all
      public (active)
      target: default
      icmp-block-inversion: no
      interfaces: eth0
      sources:
      services: dhcpv6-client ssh
      ports:
      protocols:
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:
      rich rules:

      pi@piras:~ $

Nous voyons que l'interface eth0 a bien été attribuée à la zone public.

### Les services

Il est possible de configurer les services accessibles (ou pas) attribués à la zone active.

Pour connaître les différents services disponibles, tapez la commande suivante :

    pi@piras:~ $ sudo firewall-cmd --get-services
    RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph
    ceph-mon cfengine cockpit condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client
    etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps
    ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network
    llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn
    ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio
    puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps
    snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client
    tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local
    xmpp-server zabbix-agent zabbix-server
    pi@piras:~ $

Chaque détail des services est détaillé dans un fichier xml dans /usr/lib/firewalld.

Voyons quels services sont actuellement activés sur notre raspi :

    pi@piras:~ $ ss -t -u -l -a
    Netid          State           Recv-Q          Send-Q                     Local Address:Port                          Peer Address:Port
    udp            UNCONN          0               0                                0.0.0.0:55853                              0.0.0.0:*
    udp            UNCONN          0               0                              127.0.0.1:domain                             0.0.0.0:*
    udp            UNCONN          0               0                                0.0.0.0:bootpc                             0.0.0.0:*
    udp            UNCONN          0               0                                0.0.0.0:mdns                               0.0.0.0:*
    udp            UNCONN          0               0                                  [::1]:domain                                   *:*
    udp            UNCONN          0               0                                      *:59578                                    *:*
    udp            UNCONN          0               0                                      *:mdns                                     *:*
    tcp            LISTEN          0               511                            127.0.0.1:domain-s                           0.0.0.0:*
    tcp            LISTEN          0               511                            127.0.0.1:domain                             0.0.0.0:*
    tcp            LISTEN          0               128                              0.0.0.0:ssh                                0.0.0.0:*
    tcp            ESTAB           0               0                        192.168.111.170:ssh                        192.168.111.150:59092
    tcp            LISTEN          0               511                                [::1]:domain-s                              [::]:*
    tcp            LISTEN          0               511                                [::1]:domain                                [::]:*
    tcp            LISTEN          0               128                                 [::]:ssh                                   [::]:*
    pi@piras:~ $

Nous voyons notre connexion ssh établie entre ma machine de travail en ip 192.168.111.150 et piras 192.168.111.170.

Notre raspi écoute également le port 22 sur toutes les interfaces présentes.

Liste des ports en écoute (TCP) :

    pi@piras:~ $ ss -ltn
    State              Recv-Q             Send-Q                           Local Address:Port                           Peer Address:Port
    LISTEN             0                  511                                  127.0.0.1:853                                 0.0.0.0:*
    LISTEN             0                  511                                  127.0.0.1:53                                  0.0.0.0:*
    LISTEN             0                  128                                    0.0.0.0:22                                  0.0.0.0:*
    LISTEN             0                  511                                      [::1]:853                                    [::]:*
    LISTEN             0                  511                                      [::1]:53                                     [::]:*
    LISTEN             0                  128                                       [::]:22                                     [::]:*
    pi@piras:~ $

Les ports 22 (ssh), 53 (dns), 853 (dns) sont à l'écoute en IPV4 et IPV6.

Liste des ports en écoute (UDP) :

    pi@piras:~ $ ss -lun
    State              Recv-Q             Send-Q                          Local Address:Port                            Peer Address:Port
    UNCONN             0                  0                                   127.0.0.1:53                                   0.0.0.0:*
    UNCONN             0                  0                                     0.0.0.0:68                                   0.0.0.0:*
    UNCONN             0                  0                                     0.0.0.0:5353                                 0.0.0.0:*
    UNCONN             0                  0                                       [::1]:53                                         *:*
    UNCONN             0                  0                                           *:59578                                      *:*
    UNCONN             0                  0                                           *:5353                                       *:*
    pi@piras:~ $

### État des lieux

Vérifions le fonctionnement de Firewalld. Souvenez-vous qu'il était configuré pour fonctionner avec Iptables.

Vérifions les règles établies :

    pi@piras:~ $ sudo iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    ACCEPT     all  --  anywhere             anywhere
    INPUT_direct  all  --  anywhere             anywhere
    INPUT_ZONES_SOURCE  all  --  anywhere             anywhere
    INPUT_ZONES  all  --  anywhere             anywhere
    DROP       all  --  anywhere             anywhere             ctstate INVALID
    REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
    ACCEPT     all  --  anywhere             anywhere
    FORWARD_direct  all  --  anywhere             anywhere
    FORWARD_IN_ZONES_SOURCE  all  --  anywhere             anywhere
    FORWARD_IN_ZONES  all  --  anywhere             anywhere
    FORWARD_OUT_ZONES_SOURCE  all  --  anywhere             anywhere
    FORWARD_OUT_ZONES  all  --  anywhere             anywhere
    DROP       all  --  anywhere             anywhere             ctstate INVALID
    REJECT     all  --  anywhere             anywhere             reject-with icmp-host-prohibited

    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    OUTPUT_direct  all  --  anywhere             anywhere

    Chain INPUT_direct (1 references)
    target     prot opt source               destination

    Chain INPUT_ZONES_SOURCE (1 references)
    target     prot opt source               destination

    Chain INPUT_ZONES (1 references)
    target     prot opt source               destination
    IN_public  all  --  anywhere             anywhere            [goto]
    IN_public  all  --  anywhere             anywhere            [goto]

    Chain FORWARD_direct (1 references)
    target     prot opt source               destination

    Chain FORWARD_IN_ZONES_SOURCE (1 references)
    target     prot opt source               destination

    Chain FORWARD_IN_ZONES (1 references)
    target     prot opt source               destination
    FWDI_public  all  --  anywhere             anywhere            [goto]
    FWDI_public  all  --  anywhere             anywhere            [goto]

    Chain FORWARD_OUT_ZONES_SOURCE (1 references)
    target     prot opt source               destination

    Chain FORWARD_OUT_ZONES (1 references)
    target     prot opt source               destination
    FWDO_public  all  --  anywhere             anywhere            [goto]
    FWDO_public  all  --  anywhere             anywhere            [goto]

    Chain OUTPUT_direct (1 references)
    target     prot opt source               destination

    Chain IN_public (2 references)
    target     prot opt source               destination
    IN_public_log  all  --  anywhere             anywhere
    IN_public_deny  all  --  anywhere             anywhere
    IN_public_allow  all  --  anywhere             anywhere
    ACCEPT     icmp --  anywhere             anywhere

    Chain IN_public_log (1 references)
    target     prot opt source               destination

    Chain IN_public_deny (1 references)
    target     prot opt source               destination

    Chain IN_public_allow (1 references)
    target     prot opt source               destination
    ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh ctstate NEW,UNTRACKED

    Chain FWDI_public (2 references)
    target     prot opt source               destination
    FWDI_public_log  all  --  anywhere             anywhere
    FWDI_public_deny  all  --  anywhere             anywhere
    FWDI_public_allow  all  --  anywhere             anywhere
    ACCEPT     icmp --  anywhere             anywhere

    Chain FWDI_public_log (1 references)
    target     prot opt source               destination

    Chain FWDI_public_deny (1 references)
    target     prot opt source               destination

    Chain FWDI_public_allow (1 references)
    target     prot opt source               destination

    Chain FWDO_public (2 references)
    target     prot opt source               destination
    FWDO_public_log  all  --  anywhere             anywhere
    FWDO_public_deny  all  --  anywhere             anywhere
    FWDO_public_allow  all  --  anywhere             anywhere

    Chain FWDO_public_log (1 references)
    target     prot opt source               destination

    Chain FWDO_public_deny (1 references)
    target     prot opt source               destination

    Chain FWDO_public_allow (1 references)
    target     prot opt source               destination
    pi@piras:~ $

Les règles Iptables ont bien été configurées par Firewalld.

Après reboot, nous voyons que rien n'a été conservé !

Il va falloir investiguer ...

Bien : voilà la procédure à suivre :

sudo firewall-cmd --permanent --zone=public --change-interface=eth0

Permet de changer de façon permanente l'interface associée à la zone public.

    Test :
    pi@piras:~ $ sudo firewall-cmd --permanent --zone=public --change-interface=eth0
    success

    pi@piras:~ $ sudo cat /etc/firewalld/zones/public.xml
    <?xml version="1.0" encoding="utf-8"?>
    <zone>
    <short>Public</short>
    <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
    <interface name="eth0"/>
    <service name="ssh"/>
    <service name="dhcpv6-client"/>
    </zone>
    pi@piras:~ $

    Nous voyons que firewalld a créé des répertoires et un fichier dans le répertoire **zones** dont le contenu correspond à ce que nous avons demandé.

    pi@piras:~ $ sudo firewall-cmd --list-all
    public (active)
    target: default
    icmp-block-inversion: no
    interfaces: eth0
    sources:
    services: dhcpv6-client ssh
    ports:
    protocols:
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:

    pi@piras:~ $

Test après redémarrage :

Cette fois-ci, ça marche ! (Yes !)

    pi@piras:~ $ sudo firewall-cmd --list-all
    public (active)
    target: default
    icmp-block-inversion: no
    interfaces: eth0
    sources:
    services: dhcpv6-client ssh
    ports:
    protocols:
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:

    pi@piras:~ $

Nous verrons ensuite comment ajouter des règles suivant les services que nous voudrons déployer.

« Previous Next »