Created
March 16, 2018 13:56
-
-
Save smarnach/2c82e43738c1c2a64eb1e391d4a9bc9a to your computer and use it in GitHub Desktop.
Setting up netfilter rules to forward traffic targetted at a local port to a Consul service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Run with | |
# sudo consul watch -type=service -service=redis ./consul-iptables.py | |
import json | |
import subprocess | |
import sys | |
def main(): | |
data = json.load(sys.stdin) | |
service = data[0]["Service"] | |
destination = "{}:{}".format(service["Address"], service["Port"]) | |
print destination | |
# Allow routing packages for localhost | |
subprocess.call(["sysctl", "-w", "net.ipv4.conf.all.route_localnet=1"]) | |
# Create REDIS chain; fails if chain already exists, so no check_call(). | |
subprocess.call([ | |
"iptables", "-t", "nat", | |
"-N", "REDIS", | |
]) | |
# Delete rule first to avoid dupes – will fail if it doesn't exist yet. | |
subprocess.call([ | |
"iptables", "-t", "nat", | |
"-D", "OUTPUT", | |
"-o", "lo", | |
"-p", "tcp", | |
"--dport", "6379", | |
"-j", "REDIS", | |
]) | |
# Recreate rule to capture traffic to the Redis port on lo. | |
subprocess.check_call([ | |
"iptables", "-t", "nat", | |
"-A", "OUTPUT", | |
"-o", "lo", | |
"-p", "tcp", | |
"--dport", "6379", | |
"-j", "REDIS", | |
]) | |
# Flush all rulles in the REDIS chain. | |
subprocess.check_call([ | |
"iptables", "-t", "nat", | |
"-F", "REDIS", | |
]) | |
# Forward all traffic entering the REDIS chain to the destination. | |
subprocess.check_call([ | |
"iptables", "-t", "nat", | |
"-A", "REDIS", | |
"-p", "tcp", | |
"-j", "DNAT", | |
"--to-destination", destination, | |
]) | |
# Delete masquerading rule to avoid dupes. | |
subprocess.call([ | |
"iptables", "-t", "nat", | |
"-D", "POSTROUTING", | |
"-p", "tcp", | |
"-s", "localhost/8", | |
"-j", "MASQUERADE", | |
]) | |
# Add masquerading rule to correctly set the source IP of outgoing packets. | |
subprocess.check_call([ | |
"iptables", "-t", "nat", | |
"-A", "POSTROUTING", | |
"-p", "tcp", | |
"-s", "localhost/8", | |
"-j", "MASQUERADE", | |
]) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment