# Le pare-feux Il nous faut installer un pare-feux 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 suivants: * [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éfnit 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 ont 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 backtend (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 auorisé 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 acuellement 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 mon desktop 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 0.0.0.0:55853 0.0.0.0:* 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:~ $ ### Etat 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 Public 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. 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 reboot 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.