Firewall.md 19 KB

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 et de Firewalld

pi@raspi:~ $ sudo apt install firewalld  

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 :

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.