Sécurité réseau

Le framework netfilter est utilisé pour les opérations de trafic réseau (filtrage paquets, traduction d’adresses, traduction de ports).
La structure netfilter comprend des hooks (scripts automatiques) pour interagir avec les paquets réseau entrants. Ces hooks sont des routines noyau qui interceptent les
événements et lancent d’autres routines connexes (règles de pare-feu).

Achitecture du pare-feu firewalld

nftables

La structure nftables s’appuie sur netfilter pour appliquer les règles de pare-feu au trafic réseau.
Maintenant nftables remplace iptables (obsolète). Il est malgré tout possible de convertir les anciens fichiers de configuration iptable en équivalents
nftables via les utilitaires iptables-translate et ip6tables-translate.

firewalld

Le service firewalld est un gestionnaire dynamique de pare-feu. Il classifie le trafic réseau en zones.
Une zone attribuée à un paquet dépend de critères (adresse IP source, interface réseau entrante, etc.) et chaque zone peut avoir sa propre liste de ports et services ouverts
fermés.
Le service firewalld vérifie l’adresse source de chaque paquet entrant dans le système :

  • Si l’adresse source est liée à une zone spécifique : les règles de cette zone s’appliquent
  • Si l’adresse source n’est pas attribuée à une zone : firewalld associe le paquet à la zone de l’interface réseau entrante et les règles de cette zone s’appliquent.
  • Si l’interface réseau n’est associée à aucune zone : firewalld envoie le paquet à la zone par défaut
    La zone par défaut est une désignation affectée à une zone existante : la zone public, correspond à l’interface loopback lo associée à la zone trusted, qui
    autorise tout le trafic par défaut.

Zones prédéfinies

Le service firewalld utilise des zones prédéfinies. Par défaut, toutes les zones autorisent tout trafic entrant et sortant s’il a été initié par le système.

Zone Configuration par défaut
block Rejette la totalité du trafic entrant sauf les connexions déjà initiées dans le système
dmz Seules les connections entrantes sélectionnées sont acceptés
drop Tous les paquets sont supprimés sans réponse
Seul les connexions sortantes sont possibles
external Pour les réseaux externes avec le masquerading activé
Pas de confiance aux autres machines
Seules les connexions entrantes sélectionnées sont acceptées
home Pour les réseaux personnels
Fait confiance aux autres machines du réseau
Seules les connections entrantes sélectionnées sont acceptées
internal Pour les réseaux interne
Fait confiance aux autres machines dans le réseaux non liés à la machine
Seules les connections entrantes séléctionnées sont acceptées
public Pour les zones publiques
Ne pas faire confiance aux autres machines
Seules les connections entrantes séléctionnées sont acceptés
trusted Toutes les connections réseaux sont acceptées
work Pour les zones de travail
Fait confiance aux autres machines dans les réseaux de la machine
Seules les connexions entrantes sélectionnées sont acceptées

Services prédéfinis

Le service firewalld inclut des configurations prédéfinies pour les services courants :

  • ssh : Serveur SSH local (22/tcp)
  • dhcpv6-client : Client DHCPv6 local (546/udp sur le réseau IPv6 fe80::/64)
  • ipp-client : Impression IPP locale (631/udp)
  • samba-client : Client de partage local de fichiers et d’imprimantes Windows (137/udp et 138/udp)
  • mdns : Protocole de résolution de noms sur liaison locale appelée multidiffusion DNS (mDNS, Multicast DNS) (353/udp pour les adresses de multidiffusion 224.0.0.251 (IPv4) ou
    ff02::fb (IPv6))
  • cockpit : Interface Web Red Hat Enterprise Linux pour la gestion et la surveillance de votre système local et distant (port 9090)

Paquetage

Le paquetage firewalld inclut de nombreuses configurations de service prédéfinies, la commande firewall-cmd --get-services permet de les lister :

# firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client
[...]

Configuration du daemon firewalld

La commande firewall-cmd s’interface avec le daemon firewalld.
La plupart des commandes fonctionnent avec la configuration runtime.
Si l’option --permanent est spécifiée il faut l’activer avec firewall-cmd --reload.
De nombreuses commandes listées utilisent l’option –zone=ZONE pour identifier la zone sur laquelle elles portent. Lorsqu’un masque de réseau est requis, utilisez la notation
CIDR, telle que 192.168.1/24.

Commandes

Commandes de bases :

Commandes
Explication
--get-default-zone Indique l’actuelle zone par défaut
--set-default-zone=ZONE Définit la zone par défaut
--get-zones Répertorie toutes les zones disponibles
--get-active-zones Liste toutes les zones en cours d’utilisation ainsi que leurs informations
--add-source=CIDR [--zone=ZONE] Achemine l’ensemble du trafic provenant de l’adresse IP ou du réseau/masque de réseau vers la zone spécifiée
--remove-source=CIDR [--zone=ZONE] Supprime la règle qui achemine, à partir de la zone, l’ensemble du trafic provenant de l’adresse IP ou du réseau
--add-interface=INTERFACE [--zone=ZONE] Achemine l’ensemble du trafic de INTERFACE vers ZONE
--change-interface=INTERFACE [--zone=ZONE] Associe l’interface à la ZONE
--list-all [--zone=ZONE] Liste l’ensemble des interfaces, sources, services et ports configurés pour la ZONE
--list-all-zones Récupère toutes les informations de toutes les zones
--add-service=SERVICE [--zone=ZONE] Autorise le trafic vers le SERVICE
--add-port=PORT/PROTOCOL [--zone=ZONE] Autorise le trafic vers les ports PORT/ PROTOCOL
--remove-service=SERVICE [--zone=ZONE] Supprime le SERVICE de la liste autorisée pour la zone
--remove-port=PORT/PROTOCOL [--zone=ZONE] Supprime les ports PORT/PROTOCOL pour la zone
--reload Applique la configuration permanente

Si aucune option --zone= n’est spécifiée = utilise la zone par défaut.

Exemples

Définir :

  • la zone par défaut sur la dmz
  • ajouter l’ensemble du trafic provenant du réseau 192.168.11.0/24 à la zone internal
  • ouvre les ports réseau pour le service mysql dans la zone internal
# firewall-cmd --set-default-zone=dmz
# firewall-cmd --permanent --zone=internal --add-source=192.168.11.0/24
# firewall-cmd --permanent --zone=internal --add-service=mysql
# firewall-cmd --reload

Ajouter tout le trafic entrant de l’adresse IPv4 192.168.10.0 à la zone public :

# firewall-cmd --permanent --zone=public --add-source=192.168.10.0/24
# firewall-cmd --reload

/!\ Résumé des commandes

Commandes :

# firewall-cmd

Cas pratiques

Gestion de pare-feu serveur

Installation des paquets httpd et mod_ssl :

[root@ ~]# dnf install httpd mod_ssl
[...]
Is this ok [y/N]: y
[...]
Complete!

Création du fichier /var/www/html/index.html contenant “I am SERVER01” :

[root@SERVER01 ~]# echo ‘Hello ! We are Cats ! ! I am SERVER01 :3’ > /var/www/html/index.html

Lancement et activation du service httpd :

[root@SERVER01 ~]# systemctl enable –now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/
lib/systemd/system/httpd.service.

À partir de HOST42 la commande curl doit échouer :

[aline@HOST42 ~]$ curl http://SERVER01.my.company.org
curl: (7) Failed to connect to SERVER01.my.company.org port 80: No route to host
Avec l’option -k (connexions non sécurisées) :
[aline@HOST42 ~]$ curl -k https://SERVER01.my.company.org
curl: (7) Failed to connect to SERVER01.my.company.org port 443: No route to host

Vérification de l’activation du service firewalld sur SERVER01 :

root@SERVER01 ~]# systemctl status firewalld

● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2022-04-13 11:22:50 EDT; 7min ago
Docs: man:firewalld(1)
Main PID: 768 (firewalld)
Tasks: 2 (limit: 10798)
Memory: 39.9M
CPU: 584ms
CGroup: /system.slice/firewalld.service
└─768 /usr/bin/python3 -s /usr/sbin/firewalld –nofork –nopid
Apr 13 11:22:49 SERVER01.my.company.org systemd[1]: Starting firewalld - dynamic firewall daemon…
Apr 13 11:22:50 SERVER01.my.company.org systemd[1]: Started firewalld - dynamic firewall daemon.

Ajout du service https à la zone de pare-feu public :

[root@SERVER01 ~]# firewall-cmd –set-default-zone public
[root@SERVER01 ~]# firewall-cmd –get-default-zone
public

Ajout du service https à la configuration permanente de la zone de réseau public :

[root@SERVER01 ~]# firewall-cmd –permanent –add-service=https
success
[root@SERVER01 ~]# firewall-cmd –reload
success
[root@SERVER01 ~]# firewall-cmd –permanent –zone=public –list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client https ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Vérification de l’accès au serveur Web http://SERVER01.my.company.org :

[aline@HOST42 ~]$ curl http://SERVER01.my.company.org
curl: (7) Failed to connect to SERVER01.my.company.org port 80: No route to host

Vérification de l’accès au serveur Web http://SERVER01.my.company.org via le port 443 :

[aline@HOST42 ~]$ curl -k https://SERVER01.my.company.org
Hello ! We are Cats ! ! I am SERVER01 :3

Contrôle de l’étiquetage de ports (non standards) SELinux

Résoudre un problème de contenu Web en redémarrant le service httpd :

[root@SERVER01 ~]# systemctl restart httpd.service
Job for httpd.service failed because the control process exited with error code.
See “systemctl status httpd.service” and “journalctl -xe” for details.

Affichage de l’état du service httpd :

[root@SERVER01 ~]# systemctl status -l httpd.service
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2019-04-08 14:23:29 CEST; 3min 33s ago
Docs: man:httpd.service(8)
Process: 28078 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 28078 (code=exited, status=1/FAILURE)
Status: “Reading configuration…”
Apr 08 14:23:29 SERVER01.my.company.org systemd[1]: Starting The Apache HTTP Server…
Apr 08 14:23:29 SERVER01.my.company.org httpd[28078]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:82
Apr 08 14:23:29 SERVER01.my.company.org httpd[28078]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:82
Apr 08 14:23:29 SERVER01.my.company.org httpd[28078]: no listening sockets available, shutting down
Apr 08 14:23:29 SERVER01.my.company.org httpd[28078]: AH00015: Unable to open logs
Apr 08 14:23:29 SERVER01.my.company.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 08 14:23:29 SERVER01.my.company.org systemd[1]: httpd.service: Failed with result ‘exit-code’.
Apr 08 14:23:29 SERVER01.my.company.org systemd[1]: Failed to start The Apache HTTP Server.

Vérification si SELinux empêcherait httpd de se lier au port 82/TCP :

[root@SERVER01 ~]# sealert -a /var/log/audit/audit.log
100% done
found 1 alerts in /var/log/audit/audit.log

SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 82.

***** Plugin bind_ports (99.5 confidence) suggests ************************
If you want to allow /usr/sbin/httpd to bind to network port 82
Then you need to modify the port type.
Do
semanage port -a -t PORT_TYPE -p tcp 82 where PORT_TYPE is one of the following:

http_cache_port_t, http_port_t, jboss_management_port_t, jboss_messaging_port_t,
ntop_port_t, puppet_port_t.
[...]

Raw Audit Messages
type=AVC msg=audit(1554726569.188:852): avc: denied { name_bind } for
pid=28393 comm=”httpd” src=82 scontext=system_u:system_r:httpd_t:s0
tcontext=system_u:object_r:reserved_port_t:s0 tclass=tcp_socket permissive=0
[...]

Chercher un type de port qui conviendrait pour le port 82/TCP (Le type http_port_t inclut les ports HTTP 80/TCP et 443/TCP) :

[root@SERVER01 ~]# semanage port -l | grep http
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989

Attribution du type http_port_t au port 82/TCP :

[root@SERVER01 ~]# semanage port -a -t http_port_t -p tcp 82

Redémarreage de httpd.service :

[root@SERVER01 ~]# systemctl restart httpd.service

Vérification de l’accès au serveur Web exécuté via le port 82/TCP :

[root@SERVER01 ~]# curl http://SERVER01.my.company.org:82
Hello ! We are Cats !

Cependant, cette erreur signifie qu’il n’est pas possible d’accéder au service Web à partir de HOST42 :

[aline@HOST42 ~]$ curl http://SERVER01.my.company.org:82
curl: (7) Failed to connect to SERVER01.example.com:82; No route to host

Ouverture du port 82/TCP dans la configuration permanente de la zone par défaut du pare-feu, sur SERVER01 :

[root@SERVER01 ~]# firewall-cmd –permanent –add-port=82/tcp
success

Application des modifications du pare-feu sur SERVER01 :

[root@SERVER01 ~]# firewall-cmd –reload
success

Test d’accès au service Web à partir de HOST42 :

[aline@HOST42 ~]$ curl http://SERVER01.my.company.org:82
Hello ! We are Cats !

Gestion de la sécurité réseau - Configuration des paramètres de pare-feu et de SELinux sur un hôte ayant un serveur Web

Test d’accès à http://SERVER02.my.company.org et http://SERVER02.my.company.org:1001 :

[aline@HOST42 ~]$ curl http://SERVER02.my.company.org
curl: (7) Failed to connect to SERVER02.my.company.org port 80: Connection refused
[aline@HOST42 ~]$ curl http://SERVER02.my.company.org:1001
curl: (7) Failed to connect to SERVER02.my.company.org port 1001: No route to host

Vérification si le service httpd est actif :

[aline@SERVER02 ~]$ systemctl is-active httpd
inactive

Activation et démarrage du service httpd :

[aline@SERVER02 ~]$ sudo systemctl enable –now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.
Job for httpd.service failed because the control process exited with error code.
See “systemctl status httpd.service” and “journalctl -xeu httpd.service” for details.

Recherche de la raison pour laquelle le service httpd n’a pas pu démarrer :

[aline@SERVER02 ~]$ systemctl status httpd.service
× httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Wed 2022-04-13 06:55:01 EDT; 2min 52s ago
Docs: man:httpd.service(8)
Process: 1640 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
Main PID: 1640 (code=exited, status=1/FAILURE)
Status: “Reading configuration…”
CPU: 31ms
Apr 13 06:55:01 SERVER02.my.company.org systemd[1]: Starting The Apache HTTP Server…
Apr 13 06:55:01 SERVER02.my.company.org httpd[1640]: (13)Permission denied: AH00072: make_sock: could not bind to address [::]:1001
Apr 13 06:55:01 SERVER02.my.company.org httpd[1640]: (13)Permission denied: AH00072: make_sock: could not bind to address 0.0.0.0:1001
Apr 13 06:55:01 SERVER02.my.company.org httpd[1640]: no listening sockets available, shutting down
Apr 13 06:55:01 SERVER02.my.company.org httpd[1640]: AH00015: Unable to open logs
Apr 13 06:55:01 SERVER02.my.company.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 13 06:55:01 SERVER02.my.company.org systemd[1]: httpd.service: Failed with result ‘exit-code’.
Apr 13 06:55:01 SERVER02.my.company.org systemd[1]: Failed to start The Apache HTTP Server.

Vérification si SELinux empêche le service httpd de se lier au port 1001/TCP :

[aline@SERVER02 ~]$ sudo sealert -a /var/log/audit/audit.log
100% done
found 1 alerts in /var/log/audit/audit.log

SELinux is preventing /usr/sbin/httpd from name_bind access on the tcp_socket port 1001.
***** Plugin bind_ports (99.5 confidence) suggests ************************
If you want to allow /usr/sbin/httpd to bind to network port 1001
Then you need to modify the port type.
Do
semanage port -a -t PORT_TYPE -p tcp 1001

where PORT_TYPE is one of the following: http_cache_port_t, http_port_t,
jboss_management_port_t, jboss_messaging_port_t, ntop_port_t, puppet_port_t.

***** Plugin catchall (1.49 confidence) suggests **************************
[...]

Configuration de SELinux pour autoriser le service httpd à écouter sur le port 1001/TCP. Pour trouver dans un 1er temps le type de port correct :

[aline@SERVER02 ~]$ sudo semanage port -l | grep ‘http’
http_cache_port_t tcp 8080, 8118, 8123, 10001-10010
http_cache_port_t udp 3130
http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t tcp 5988
pegasus_https_port_t tcp 5989

Liaison du port 1001/TCP au type http_port_t :

[aline@SERVER02 ~]$ sudo semanage port -a -t http_port_t -p tcp 1001

Vérification que le port 1001/TCP est bien lié au type de port http_port_t :

[aline@SERVER02 ~]$ sudo semanage port -l | grep ‘^http_port_t’
http_port_t tcp 1001, 80, 81, 443, 488, 8008, 8009, 8443, 9000

Activation et démarrage du service httpd :

[aline@SERVER02 ~]$ sudo systemctl enable –now httpd

Vérificat de httpd :

[aline@SERVER02 ~]$ systemctl is-active httpd
active
[aline@SERVER02 ~]$ systemctl is-enabled httpd
enabled

Test de la configuration :

[aline@HOST42 ~]$ curl http://SERVER02.my.company.org
SERVER B
[aline@HOST42 ~]$ curl http://SERVER02.my.company.org:1001
curl: (7) Failed to connect to SERVER02.my.company.org port 1001: No route to host

Vérification que la zone de pare-feu par défaut soit définie sur la zone public :

[aline@SERVER02 ~]$ firewall-cmd –get-default-zone
public

Sinon, l’appliquer :

[aline@SERVER02 ~]$ sudo firewall-cmd –set-default-zone public

Vérification des ports ouverts listés dans la zone de réseau public :

[aline@SERVER02 ~]$ sudo firewall-cmd –zone=public –list-all
[sudo] password for aline: aline
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client http ssh
ports:
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Ajout du port 1001/TCP à la configuration permanente de la zone de réseau public :

[aline@SERVER02 ~]$ sudo firewall-cmd –permanent –zone=public –add-port=1001/tcp
success

Reload de la configuration du pare-feu :

[aline@SERVER02 ~]$ sudo firewall-cmd –reload
success

Vérification de la configuration :

[aline@SERVER02 ~]$ sudo firewall-cmd –zone=public –list-all
public
target: default
icmp-block-inversion: no
interfaces:
sources:
services: cockpit dhcpv6-client http ssh
ports: 1001/tcp
protocols:
forward: yes
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

Vérification de l’accès à http://SERVER02.my.company.org et à http://SERVER02.my.company.org:1001 :

[aline@HOST42 ~]$ curl http://SERVER02.my.company.org
SERVER B
[aline@HOST42 ~]$ curl http://SERVER02.my.company.org:1001
VHOST 1

Documentation

MAN firewall-cmd(1)
MAN firewalld(1)
MAN firewalld.zone(5)
MAN firewalld.zones(5)
MAN nft(8)
https://uubu.fr/?page=00001282

> Partager <