IPtables is linear and it reads the rules from top to bottom until it reaches a ACCEPT, REJECT, or DROP target, and then it stops reading the rules. In your case, you want to have iptables -I DOCKER-USER -j DROP
as the very last rule in your chain, otherwise every packet will be dropped. Also, there is no need for the RETURN rule at the end, because IPtables will stop reading rules once it reaches the DROP rule right above it. Those IPtables rules with tun0 look fine, but makes sure you have these rules as well:
iptables -t filter -I INPUT 1 -i tun0 -j DOCKER-USER
iptables -t filter -I OUTPUT 2 -o tun0 -j DOCKER-USER
For good practice, make sure you accept all loopback traffic, which will never reach the internet nor will it leave the machine:
iptables -t filter -I INPUT 3 -i tun0 -j ACCEPT
Let's go through your requirements one-by-one:
- Any services assigned to this node exclusively use the VPN connection
You would not use IPtables to do this. Run these commnds on the servers:
ip route add default via ${LOCAL_VPN_IP}
I think OpenVPN typically uses 10.8.0.0/16, so the default gateway would probably be 10.8.0.1 or something like that. IProute2 (ip command) is built into the kernel, just like IPtables.
- No leaks (i.e., DNS or other traffic)
You should first redirect all traffic through the VPN by putting this in your OpenVPN's server config:
push "redirect-gateway autolocal"
This makes the clients put all of their traffic through the VPN, even DNS and such. If the OpenVPN server goes down, the internet will stop working on the clients.
- If the VPN disconnects, all traffic gets dropped
See step 2
- Allow service discovery and connections to other containers in the Swarm
I believe OpenVPN does this by default. I am able to ping/arp from one client to other clients that are on the OpenVPN server. You should definitely be able to access services that are on other clients.
I hope this answers your questions!