I need to make sure only specific services can access my vpn's virtual interface. From what I can tell, using iptables to filter based on process cgroup membership is the cleanest way to do that.
So, I put my sshd service in the vpn.slice
cgroup using systemd, and I made a chain and added it to both INPUT and OUTPUT:
iptables -N vpn
iptables -A vpn -m cgroup --path /vpn.slice -j ACCEPT
iptables -A vpn -j DROP
iptables -A INPUT -i $INTERFACE -j vpn
iptables -A OUTPUT -o $INTERFACE -j vpn
iptables -L output:
[root@sh ~]# iptables -L -v
Chain INPUT (policy ACCEPT 287K packets, 17M bytes)
pkts bytes target prot opt in out source destination
106 5160 vpn all -- homeforward any anywhere anywhere
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 476K packets, 673M bytes)
pkts bytes target prot opt in out source destination
78 10062 vpn all -- any homeforward anywhere anywhere
Chain vpn (2 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all -- any any anywhere anywhere cgroup /vpn.slice
184 15222 DROP all -- any any anywhere anywhere
I can't connect to the ssh server when these rules are applied, and same for netcat on other ports. Manually changing a shell's cgroup membership and trying to ping other nodes in the vpn also doesn't work. I've also tried using --path vpn.slice
instead of --path /vpn.slice
, it doesn't make a difference.
Am I missing something here?
man iptables-extensions
below cgroup: "IMPORTANT: when being used in the INPUT chain" – A.B Feb 20 at 8:16