#!/sbin/nft -f

# Profil vpn du firewall.
# Profil particulier, qui vient se rajouter au profil présent précédemment. Il faut le voir comme une surcouche.
# Cette distinction est importante : c'est le seul profil qui ne fonctionne pas en mode "drop all, but whitelist these"
# Celui-ci fonctionne plutôt en mode "whitelist these, and let next profile decide what to do with remaining packets".
# Le whitelist par le vpn est fait en marquant les paquets acceptés. Si le profil sur lequel repose le vpn voit un paquet
# marqué, il l'acceptera.
# Le profil vpn ne fait donc pas de drop/accept, il se base sur le marquage.
# Cela permet au profil VPN de venir se "plugguer" aux profils external, external captive, edf-wifi ou wired :
# edf-vpn applique les règles propres au vpn, sans déranger les spécificités de la connexion sur laquelle il repose

# On se trouve dans cet état lorsque le client Pulse Secure crée la passerelle tun0. Cela peut se produire lorsqu'on est déja sur le profil :
# - external
# - external-captive
# - edf-wifi
# - edf-wired
# edf-wifi et edf-wired sont possibles car pour acceder au vpnadmin, il faut être connecté au RIN depuis un site EDF

# Entrée
# Les paquets entrants venant d'une connexion initiée par le poste sont autorisés sur l'interface vpn
# Les connexions ssh entrantes sont autorisées si elles proviennent de l'interface vpn
# Les autres accès sortants ne sont pas refusés, c'est au profil suivant de les gérer

# Sortie
# Les accès sortants sont ouverts sur la passerelle vpn
# Les autres accès sortants ne sont pas refusés, c'est au profil suivant de les gérer

# Ne surtout pas faire un flush ruleset

include "/etc/scibian-firewall/utils/variables"

# TODO : gérer l'ipv6

table inet edf-vpn {
    chain input {
        # Le profil vpn venant se greffer à un autre profil, on doit d'abord passer dans les règles du profil vpn
        # avant d'aller dans celles de l'autre profil. On a donc une priorité à -1.
        # Le profil vpn marque les paquets comme valides, plutot que de les accept/drop. Si le profil suivant voit
        # un paquet marqué par le vpn, il l'acceptera
        type filter hook input priority -1; policy accept;

        # On accepte les paquets des connexions initiées par le poste sur l'interface vpn
        iifname $vpn_interface ct state established,related mark set $packet_accepted_by_vpn

        # On accepte les connexions ssh entrantes sur l'interface vpn
        iifname $vpn_interface tcp dport ssh mark set $packet_accepted_by_vpn

        # On accepte les connexions icmp entrantes sur l'interface vpn
        iifname $vpn_interface ip protocol icmp mark set $packet_accepted_by_vpn
    }

    chain output {
        # Le profil vpn venant se greffer à un autre profil, on doit d'abord passer dans les règles du profil vpn
        # avant d'aller dans celles de l'autre profil. On a donc une priorité à -1.
        # Le profil vpn marque les paquets comme valides, plutot que de les accept/drop. Si le profil suivant voit
        # un paquet marqué par le vpn, il l'acceptera
        type filter hook output priority -1; policy accept;

        # On marque les paquets sortants sur l'interface vpn comme valides
        # Ainsi, ils ne seront pas rejetés plus loin par le profil firewall sur lequel repose le profil vpn
        oifname $vpn_interface mark set $packet_accepted_by_vpn
    }
}
