Filtrage des conteneurs Docker sur Debian avec Firewalld et Salt

Sommaire

L'objectif est de filtrer, en entrée et sortie, l'accès aux conteneurs Docker déployés sur une Debian disposant de Firewalld.

Via les "zones" et "policies" de Firewalld il est maintenant possible de filtrer en entrée et en sortie de nos interfaces : https://firewalld.org/2020/09/policy-objects-introduction

1. Introduction

Sur mes conteneurs LXC Debian 12, j'utilise "firewalld" avec le backend "nftables".

La problématique est que l'intégration "firewalld" de Docker ne permet pas de filtrer de manière granulaire l'accès à ses conteneurs : https://github.com/firewalld/firewalld/issues/869#issuecomment-1246740576

L'équipe Firewalld documente une méthode pour contourner ce problème : https://firewalld.org/2024/04/strictly-filtering-docker-containers
L'idée est de désactiver l'intégration "iptables" dans Docker et de configurer "firewalld" pour gérer la publication des conteneurs.

Avec les zones et "policies" de Firewalld il sera ainsi possible de filtrer en entrée et en sortie de nos conteneurs : https://www.kartzone.fr/post/salt-firewalld-output-filter/

2. Prérequis

Dans un premier temps, vous devez disposer d'un serveur Salt : https://www.kartzone.fr/post/salt-masterless/
Disposant des formules Salt suivantes :

3. Configuration de Salt

Voici un exemple de "pillars" Salt permettant de déployer une image Docker de Shaarli et de filtrer en entrée et en sortie du conteneur (target : DROP):

Exemple de pillars Salt pour "docker-formula" :

 1docker:
 2  wanted:
 3    - docker
 4
 5  pkg:
 6    docker:
 7      use_upstream: repo
 8      daemon_config:
 9        iptables: false
10        data-root: "/srv/docker"
11        bridge: "none"
12    compose:
13      use_upstream: repo
14
15  networks:
16    - frontend
17
18  compose:
19    ng:
20      shaarli:
21        image: 'ghcr.io/shaarli/shaarli:latest'
22        container_name: 'shaarli'
23        networks:
24          - frontend
25        ports:
26          - '8000:80'
27        restart: unless-stopped
28        volumes:
29          - shaarli-data:/var/www/shaarli/data
30          - shaarli-cache:/var/www/shaarli/cache

Exemple de pillars Salt pour firewalld-formula :

 1firewalld:
 2  enabled: true
 3  IndividualCalls: 'no'
 4  LogDenied: 'all'
 5  AutomaticHelpers: 'system'
 6  FirewallBackend: 'nftables'
 7  FlushAllOnReload: 'yes'
 8  default_zone: public
 9  
10  zones:
11    public:
12      target: DROP
13      rich_rules:
14        - family: ipv4
15          source:
16            # change with your network or load balancer address
17            address: 192.168.5.0/24
18          port:
19            portid: 8000
20            protocol: tcp
21          accept: true    
22    docker:
23      description: "zone for docker bridge network interfaces"
24      target: ACCEPT
25      sources:
26        - 172.17.0.1/16
27
28  policies:
29    docker-output:
30      target: DROP
31      description: 'give the container internet access'
32      ingress_zone: docker
33      egress_zone: ANY
34      masquerade: true
35      services:
36        - http
37        - https
38        - dns
39    docker-forwarding:
40      target: ACCEPT
41      description: 'allow forwarding to the docker zone'
42      ingress_zone: ANY
43      egress_zone: docker
44      forward_ports:
45        - portid: 8000
46          protocol: tcp
47          to_port: 80
48          to_addr: 172.17.0.2

Pour déployer les états Salt, vous pouvez utiliser les commandes suivantes :

1salt-call state.apply firewalld,docker,docker.compose.ng

On vérifie que le backend de firewalld est "nftables" :

1grep FirewallBackend /etc/firewalld/firewalld.conf

On peut aussi en profiter pour vérifier que le backend d'iptables est "nf_tables" :

1iptables -V

Et vérifier que la commande iptables redirige vers "iptables-nft" :

1update-alternatives --query iptables

4. Commandes utiles

  • Lister les zones firewalld :

    1firewall-cmd --list-all-zones
    
  • Lister les zones firewalld actives

    1firewall-cmd --get-active-zones
    
  • Lister les règles sur les zones firewalld actives

    1for zone in $(firewall-cmd --get-active-zones | awk 'NR % 2 == 1'); do echo "==== Zone: $zone ===="; firewall-cmd --zone=$zone --list-all; done
    
  • Lister les "policies" firewalld

    1firewall-cmd --list-all-policies
    
  • Lister les "policies" firewalld actives

    1firewall-cmd --get-active-policies
    
  • Lister les règles sur les "policies" firewalld actives

    1for policy in $(firewall-cmd --get-policies); do echo "==== Policy: $policy ===="; firewall-cmd --policy=$policy --list-all; done
    
  • Lister les règles nftables:

    1nft list ruleset
    
  • Debug nftables : https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing