# 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](https://lwn.net/Articles/484506/)
* [How to get started with Firewalld](https://www.certdepot.net/rhel7-get-started-firewalld/)
* [tutorial points](https://www.tutorialspoint.com/network_security/network_security_firewalls.htm)
* [la documentation officielle](https://firewalld.org/documentation/zone/predefined-zones.html)
* [introduction-to-firewalld](https://linuxconfig.org/introduction-to-firewalld-and-firewall-cmd-command-on-linux)
* [La documentation de Fedora](https://doc.fedora-fr.org/wiki/Parefeu_-_firewall_-_FirewallD)
* [it connect](https://www.it-connect.fr/centos-7-utilisation-et-configuration-de-firewalld/)

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](https://www.it-connect.fr/centos-7-utilisation-et-configuration-de-firewalld/)

### 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.
