Avant de migrer le firewall du routeur principal, j'ai voulu commencer par plus petit. C'est donc la première partie d'une série de 2 ou 3 articles. Une des machines de mon LAN utilise de la masquarade pour donner accès à une machine distante à travers un VPN. Ce qui tombe assez bien, la masquarade vient d'être ajoutée dans la version 3.18 du noyau et cettte configuration simple est un bon exercice pour commencer.

iptables

Voici le script précédent que je vais remplacer, c'est de la masquarade simple :

#!/bin/sh

# On efface les règles définies :
iptables -t filter -F
iptables -t nat -F

# Efface les chaînes définies :
iptables -X

# Politique par défaut :
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT

# forward entre interfaces réseau
echo "1" > /proc/sys/net/ipv4/ip_forward

# nat VPN (for jabber client on hyperion)
iptables -t nat -o tun0 -A POSTROUTING -j MASQUERADE

nftables

On trouve un peu de documentation sur le net, en particulier sur le wiki de nftables, ainsi que celui de gentoo et d'archlinux Parmis les changements notables dès que l'on commence à se documenter, il y a le fait que les tables et les chaînes classiques d'iptables ne sont pas créées par défaut. Il faut donc les déclarer, et comme il n'y a pas de chaînes, il n'y a pas non plus de politique par défaut.

La masquarade est un cas particulier de source NAT, l'adresse source n'est pas définie explicitement dans la règle. C'est l'adresse de l'interface de sortie qui va remplacer à la volée celle d'origine des paquets. Le choix est donc fait une fois la décision de routage prise, et s'opère donc en postrouting. Pour rappel, voici le schémas du parcours d'un paquet réseau au travers de netfilter. Comme les chaînes n'existent pas par défault, il faut aussi rajouter celle qui va venir s'accrocher au hook prerouting de netfilter, pour que le remplacement inverse soit effectué lorsque les paquets reviendront.

Voici donc ce que ça donne :

#!/bin/sh
# activate masquerade

IF_OUTPUT=tun0

# ensure iptable_nat is not loaded
lsmod | grep -q iptable_nat
ret=$?

if [ ${ret} -eq 0 ]; then
        echo "nft usage is not compatible with iptables_nat"
        echo "please remove iptable_nat module"
        exit 1
fi

# remove existing rules
nft flush ruleset

# masquerade
nft add table nat
# add prerouting to translate back the address when packets returns
nft add chain nat prerouting { type nat hook prerouting priority 0\; }

# postrouting to translate source address
nft add chain nat postrouting { type nat hook postrouting priority 0\; }

# masquerade effective rule
nft add rule nat postrouting oif ${IF_OUTPUT} masquerade

# active packet forwarding between interfaces (routing)
echo "1" > /proc/sys/net/ipv4/ip_forward
# ipv6
# /proc/sys/net/ipv6/conf/all/forwarding = 1