Implementing an OpenVPN “kill switch” with iptables
I'm trying to implement a set of iptables rules for OpenVPN:
- Everything (without exception) goes through OpenVPN
- If OpenVPN is down or inaccessible everything (without exception) cannot access the internet
- Local access is always possible, irrespective of the status of OpenVPN
The best (out of six examples) I've seen so far is this, however it still allows access to the internet when the VPN is down through ipv6:
# Clean down existing rules
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -F
ip6tables -X
# Allow loopback device (internal communication)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow VPN establishment
iptables -A OUTPUT -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
# Set default policies to drop all communication unless specifically allowed
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
If I try to blanket block all ipv6 traffic (which is what a number of examples suggest) then I cannot connect to anything:
# Set default policies to drop all communication unless specifically allowed
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP
If I try to mirror what is in the ipv4 section then I have this:
# Allow loopback device (internal communication)
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
# (Skipped as I don't know how to do this)
# Allow VPN establishment
ip6tables -A OUTPUT -p udp --dport 1194 -j ACCEPT
ip6tables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
ip6tables -A OUTPUT -o tun+ -j ACCEPT
ip6tables -A INPUT -i tun+ -j ACCEPT
Now I'm unable to connect to anywhere and curl https://ipinfo.io/ip
just hangs.
How can I fix this?
networking vpn openvpn iptables ipv6
add a comment |
I'm trying to implement a set of iptables rules for OpenVPN:
- Everything (without exception) goes through OpenVPN
- If OpenVPN is down or inaccessible everything (without exception) cannot access the internet
- Local access is always possible, irrespective of the status of OpenVPN
The best (out of six examples) I've seen so far is this, however it still allows access to the internet when the VPN is down through ipv6:
# Clean down existing rules
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -F
ip6tables -X
# Allow loopback device (internal communication)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow VPN establishment
iptables -A OUTPUT -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
# Set default policies to drop all communication unless specifically allowed
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
If I try to blanket block all ipv6 traffic (which is what a number of examples suggest) then I cannot connect to anything:
# Set default policies to drop all communication unless specifically allowed
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP
If I try to mirror what is in the ipv4 section then I have this:
# Allow loopback device (internal communication)
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
# (Skipped as I don't know how to do this)
# Allow VPN establishment
ip6tables -A OUTPUT -p udp --dport 1194 -j ACCEPT
ip6tables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
ip6tables -A OUTPUT -o tun+ -j ACCEPT
ip6tables -A INPUT -i tun+ -j ACCEPT
Now I'm unable to connect to anywhere and curl https://ipinfo.io/ip
just hangs.
How can I fix this?
networking vpn openvpn iptables ipv6
add a comment |
I'm trying to implement a set of iptables rules for OpenVPN:
- Everything (without exception) goes through OpenVPN
- If OpenVPN is down or inaccessible everything (without exception) cannot access the internet
- Local access is always possible, irrespective of the status of OpenVPN
The best (out of six examples) I've seen so far is this, however it still allows access to the internet when the VPN is down through ipv6:
# Clean down existing rules
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -F
ip6tables -X
# Allow loopback device (internal communication)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow VPN establishment
iptables -A OUTPUT -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
# Set default policies to drop all communication unless specifically allowed
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
If I try to blanket block all ipv6 traffic (which is what a number of examples suggest) then I cannot connect to anything:
# Set default policies to drop all communication unless specifically allowed
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP
If I try to mirror what is in the ipv4 section then I have this:
# Allow loopback device (internal communication)
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
# (Skipped as I don't know how to do this)
# Allow VPN establishment
ip6tables -A OUTPUT -p udp --dport 1194 -j ACCEPT
ip6tables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
ip6tables -A OUTPUT -o tun+ -j ACCEPT
ip6tables -A INPUT -i tun+ -j ACCEPT
Now I'm unable to connect to anywhere and curl https://ipinfo.io/ip
just hangs.
How can I fix this?
networking vpn openvpn iptables ipv6
I'm trying to implement a set of iptables rules for OpenVPN:
- Everything (without exception) goes through OpenVPN
- If OpenVPN is down or inaccessible everything (without exception) cannot access the internet
- Local access is always possible, irrespective of the status of OpenVPN
The best (out of six examples) I've seen so far is this, however it still allows access to the internet when the VPN is down through ipv6:
# Clean down existing rules
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t nat -F
iptables -t mangle -F
iptables -F
iptables -X
ip6tables -P INPUT ACCEPT
ip6tables -P FORWARD ACCEPT
ip6tables -P OUTPUT ACCEPT
ip6tables -t nat -F
ip6tables -t mangle -F
ip6tables -F
ip6tables -X
# Allow loopback device (internal communication)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow VPN establishment
iptables -A OUTPUT -p udp --dport 1194 -j ACCEPT
iptables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
iptables -A OUTPUT -o tun+ -j ACCEPT
iptables -A INPUT -i tun+ -j ACCEPT
# Set default policies to drop all communication unless specifically allowed
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
If I try to blanket block all ipv6 traffic (which is what a number of examples suggest) then I cannot connect to anything:
# Set default policies to drop all communication unless specifically allowed
ip6tables -P INPUT DROP
ip6tables -P OUTPUT DROP
ip6tables -P FORWARD DROP
If I try to mirror what is in the ipv4 section then I have this:
# Allow loopback device (internal communication)
ip6tables -A INPUT -i lo -j ACCEPT
ip6tables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic.
# (Skipped as I don't know how to do this)
# Allow VPN establishment
ip6tables -A OUTPUT -p udp --dport 1194 -j ACCEPT
ip6tables -A INPUT -p udp --sport 1194 -j ACCEPT
# Accept all TUN connections (tun = VPN tunnel)
ip6tables -A OUTPUT -o tun+ -j ACCEPT
ip6tables -A INPUT -i tun+ -j ACCEPT
Now I'm unable to connect to anywhere and curl https://ipinfo.io/ip
just hangs.
How can I fix this?
networking vpn openvpn iptables ipv6
networking vpn openvpn iptables ipv6
edited Dec 31 '18 at 20:21
Richard
asked Dec 31 '18 at 19:50
RichardRichard
3,41042656
3,41042656
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Your example script cleans all rules for IPv4 and IPv6 rulesets... but doesn't add any rules for IPv6.
Notice how the "Clean down existing rules" section calls both iptables
and ip6tables
, resetting both firewalls to their default "wide open" state. The remaining sections, however, do nothing with ip6tables at all.
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
add a comment |
It turns out that I'd not whitelisted the DNS servers of the VPN service. Once I did that, I was able to blacklist ipv6 without an issue.
For the sake of completeness, this is what I finally got to work. Three things to bear in mind:
- You should replace
[Primary DNS IP here]
and[Secondary DNS IP here]
with the IP addresses of the DNS servers you're planning to use - Don't forget to edit
/etc/resolvconf.conf
to add the IP addresses in #1 as nameservers and blacklist your own to avoid DNS leakages. - This assumes your local traffic has an IP range starting
192.168
. If not, you'll need to change this.
Code as follows:
# Remove any existing rules
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
# Allow loopback device (internal communication)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow DNS (could be VPN provider or someone like Cloudflare's 1.1.1.1)
iptables -A OUTPUT -d [Primary DNS IP here] -j ACCEPT
iptables -A OUTPUT -d [Secondary DNS IP here] -j ACCEPT
# Allow related and established connections
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Allow VPN establishment
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 1198 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 1198 -j ACCEPT
# Accept all tun0 (VPN tunnel) connections
sudo iptables -A OUTPUT -o tun0 -j ACCEPT
sudo iptables -A INPUT -i tun0 -j ACCEPT
# Drop everything else (ipv4)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
# Drop everything (ipv6)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P OUTPUT DROP
sudo ip6tables -P FORWARD DROP
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "3"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1389368%2fimplementing-an-openvpn-kill-switch-with-iptables%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your example script cleans all rules for IPv4 and IPv6 rulesets... but doesn't add any rules for IPv6.
Notice how the "Clean down existing rules" section calls both iptables
and ip6tables
, resetting both firewalls to their default "wide open" state. The remaining sections, however, do nothing with ip6tables at all.
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
add a comment |
Your example script cleans all rules for IPv4 and IPv6 rulesets... but doesn't add any rules for IPv6.
Notice how the "Clean down existing rules" section calls both iptables
and ip6tables
, resetting both firewalls to their default "wide open" state. The remaining sections, however, do nothing with ip6tables at all.
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
add a comment |
Your example script cleans all rules for IPv4 and IPv6 rulesets... but doesn't add any rules for IPv6.
Notice how the "Clean down existing rules" section calls both iptables
and ip6tables
, resetting both firewalls to their default "wide open" state. The remaining sections, however, do nothing with ip6tables at all.
Your example script cleans all rules for IPv4 and IPv6 rulesets... but doesn't add any rules for IPv6.
Notice how the "Clean down existing rules" section calls both iptables
and ip6tables
, resetting both firewalls to their default "wide open" state. The remaining sections, however, do nothing with ip6tables at all.
answered Dec 31 '18 at 19:55
grawitygrawity
237k37503557
237k37503557
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
add a comment |
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Yep, I alluded to that in the question. If I blanket block all ipv6 (which is what a couple of examples I've found suggest) then nothing works.
– Richard
Dec 31 '18 at 20:13
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Then don't blanket block it – do the same as the IPv4 rules do!
– grawity
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
Point taken, I'll update the question :)
– Richard
Dec 31 '18 at 20:16
add a comment |
It turns out that I'd not whitelisted the DNS servers of the VPN service. Once I did that, I was able to blacklist ipv6 without an issue.
For the sake of completeness, this is what I finally got to work. Three things to bear in mind:
- You should replace
[Primary DNS IP here]
and[Secondary DNS IP here]
with the IP addresses of the DNS servers you're planning to use - Don't forget to edit
/etc/resolvconf.conf
to add the IP addresses in #1 as nameservers and blacklist your own to avoid DNS leakages. - This assumes your local traffic has an IP range starting
192.168
. If not, you'll need to change this.
Code as follows:
# Remove any existing rules
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
# Allow loopback device (internal communication)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow DNS (could be VPN provider or someone like Cloudflare's 1.1.1.1)
iptables -A OUTPUT -d [Primary DNS IP here] -j ACCEPT
iptables -A OUTPUT -d [Secondary DNS IP here] -j ACCEPT
# Allow related and established connections
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Allow VPN establishment
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 1198 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 1198 -j ACCEPT
# Accept all tun0 (VPN tunnel) connections
sudo iptables -A OUTPUT -o tun0 -j ACCEPT
sudo iptables -A INPUT -i tun0 -j ACCEPT
# Drop everything else (ipv4)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
# Drop everything (ipv6)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P OUTPUT DROP
sudo ip6tables -P FORWARD DROP
add a comment |
It turns out that I'd not whitelisted the DNS servers of the VPN service. Once I did that, I was able to blacklist ipv6 without an issue.
For the sake of completeness, this is what I finally got to work. Three things to bear in mind:
- You should replace
[Primary DNS IP here]
and[Secondary DNS IP here]
with the IP addresses of the DNS servers you're planning to use - Don't forget to edit
/etc/resolvconf.conf
to add the IP addresses in #1 as nameservers and blacklist your own to avoid DNS leakages. - This assumes your local traffic has an IP range starting
192.168
. If not, you'll need to change this.
Code as follows:
# Remove any existing rules
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
# Allow loopback device (internal communication)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow DNS (could be VPN provider or someone like Cloudflare's 1.1.1.1)
iptables -A OUTPUT -d [Primary DNS IP here] -j ACCEPT
iptables -A OUTPUT -d [Secondary DNS IP here] -j ACCEPT
# Allow related and established connections
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Allow VPN establishment
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 1198 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 1198 -j ACCEPT
# Accept all tun0 (VPN tunnel) connections
sudo iptables -A OUTPUT -o tun0 -j ACCEPT
sudo iptables -A INPUT -i tun0 -j ACCEPT
# Drop everything else (ipv4)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
# Drop everything (ipv6)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P OUTPUT DROP
sudo ip6tables -P FORWARD DROP
add a comment |
It turns out that I'd not whitelisted the DNS servers of the VPN service. Once I did that, I was able to blacklist ipv6 without an issue.
For the sake of completeness, this is what I finally got to work. Three things to bear in mind:
- You should replace
[Primary DNS IP here]
and[Secondary DNS IP here]
with the IP addresses of the DNS servers you're planning to use - Don't forget to edit
/etc/resolvconf.conf
to add the IP addresses in #1 as nameservers and blacklist your own to avoid DNS leakages. - This assumes your local traffic has an IP range starting
192.168
. If not, you'll need to change this.
Code as follows:
# Remove any existing rules
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
# Allow loopback device (internal communication)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow DNS (could be VPN provider or someone like Cloudflare's 1.1.1.1)
iptables -A OUTPUT -d [Primary DNS IP here] -j ACCEPT
iptables -A OUTPUT -d [Secondary DNS IP here] -j ACCEPT
# Allow related and established connections
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Allow VPN establishment
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 1198 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 1198 -j ACCEPT
# Accept all tun0 (VPN tunnel) connections
sudo iptables -A OUTPUT -o tun0 -j ACCEPT
sudo iptables -A INPUT -i tun0 -j ACCEPT
# Drop everything else (ipv4)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
# Drop everything (ipv6)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P OUTPUT DROP
sudo ip6tables -P FORWARD DROP
It turns out that I'd not whitelisted the DNS servers of the VPN service. Once I did that, I was able to blacklist ipv6 without an issue.
For the sake of completeness, this is what I finally got to work. Three things to bear in mind:
- You should replace
[Primary DNS IP here]
and[Secondary DNS IP here]
with the IP addresses of the DNS servers you're planning to use - Don't forget to edit
/etc/resolvconf.conf
to add the IP addresses in #1 as nameservers and blacklist your own to avoid DNS leakages. - This assumes your local traffic has an IP range starting
192.168
. If not, you'll need to change this.
Code as follows:
# Remove any existing rules
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -t nat -F
sudo iptables -t mangle -F
sudo iptables -F
sudo iptables -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
sudo ip6tables -t nat -F
sudo ip6tables -t mangle -F
sudo ip6tables -F
sudo ip6tables -X
# Allow loopback device (internal communication)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
# Allow all local traffic
sudo iptables -A INPUT -s 192.168.0.0/16 -j ACCEPT
sudo iptables -A OUTPUT -d 192.168.0.0/16 -j ACCEPT
# Allow DNS (could be VPN provider or someone like Cloudflare's 1.1.1.1)
iptables -A OUTPUT -d [Primary DNS IP here] -j ACCEPT
iptables -A OUTPUT -d [Secondary DNS IP here] -j ACCEPT
# Allow related and established connections
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Allow VPN establishment
sudo iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 53 -j ACCEPT
sudo iptables -A OUTPUT -p udp --dport 1198 -j ACCEPT
sudo iptables -A INPUT -p udp --sport 1198 -j ACCEPT
# Accept all tun0 (VPN tunnel) connections
sudo iptables -A OUTPUT -o tun0 -j ACCEPT
sudo iptables -A INPUT -i tun0 -j ACCEPT
# Drop everything else (ipv4)
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT DROP
sudo iptables -P FORWARD DROP
# Drop everything (ipv6)
sudo ip6tables -P INPUT DROP
sudo ip6tables -P OUTPUT DROP
sudo ip6tables -P FORWARD DROP
answered Dec 31 '18 at 23:26
RichardRichard
3,41042656
3,41042656
add a comment |
add a comment |
Thanks for contributing an answer to Super User!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1389368%2fimplementing-an-openvpn-kill-switch-with-iptables%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown