Created
March 6, 2020 03:29
-
-
Save moycat/74f422be38366b5575f2218b862b019e to your computer and use it in GitHub Desktop.
Utils for port forwarding using iptables on a single NIC Proxmox VE machine. Suppose your intranet subnet is 192.168.0.0/24, the public IP is 1.2.3.4 & the NIC is vmbr0.
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 python3 | |
import argparse | |
import ipaddress | |
import os | |
INTERNAL_SUBNET = "192.168.0.0/24" | |
INTERNET_ADDRESS = "1.2.3.4" | |
INTERFACE = "vmbr0" | |
def get_args(): | |
parser = argparse.ArgumentParser(description="Add a port forwarding rule.") | |
parser.add_argument("--port", type=int, metavar="{1...65535}", help="Host port where traffic comes from.", | |
required=True) | |
parser.add_argument("--protocol", type=str, help="Port protocol to use.", choices=("tcp", "udp", "all"), | |
default="tcp") | |
parser.add_argument("internal_address", type=str, help="Internal address to be forwarded to.") | |
args = parser.parse_args() | |
listen_port = args.port | |
if not 0 < listen_port < 65536: | |
parser.error("invalid host port") | |
protocols = (args.protocol,) if args.protocol != "all" else ("tcp", "udp") | |
internal_address = args.internal_address | |
ip, separator, port = internal_address.rpartition(":") | |
try: | |
assert separator | |
assert ipaddress.ip_address(ip) in ipaddress.ip_network(INTERNAL_SUBNET) | |
port = int(port) | |
assert 0 < port < 65536 | |
except Exception as _: | |
parser.error("invalid internal address") | |
return listen_port, ip, port, protocols | |
def main(): | |
listen_port, internal_ip, internal_port, protocols = get_args() | |
print("executing iptables commands...") | |
for protocol in protocols: | |
commands = ( | |
f"iptables -t nat -A PREROUTING -d {INTERNET_ADDRESS}/32 -i {INTERFACE} -p {protocol} " | |
f"--dport {listen_port} -j DNAT --to-destination {internal_ip}:{internal_port}", | |
f"iptables -A FORWARD -d {internal_ip}/32 -p {protocol} --dport {internal_port} " | |
f"-m state --state NEW,ESTABLISHED,RELATED -j ACCEPT", | |
) | |
for c in commands: | |
print(c) | |
os.system(c) | |
if __name__ == "__main__": | |
main() |
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 python3 | |
import argparse | |
import ipaddress | |
import os | |
INTERNAL_SUBNET = "192.168.0.0/24" | |
INTERNET_ADDRESS = "1.2.3.4" | |
INTERFACE = "vmbr0" | |
def get_args(): | |
parser = argparse.ArgumentParser(description="Delete a port forwarding rule.") | |
parser.add_argument("--port", type=int, metavar="{1...65535}", help="Host port where traffic comes from.", | |
required=True) | |
parser.add_argument("--protocol", type=str, help="Port protocol to use.", choices=("tcp", "udp", "all"), | |
default="tcp") | |
parser.add_argument("internal_address", type=str, help="Internal address to be forwarded to.") | |
args = parser.parse_args() | |
listen_port = args.port | |
if not 0 < listen_port < 65536: | |
parser.error("invalid host port") | |
protocols = (args.protocol,) if args.protocol != "all" else ("tcp", "udp") | |
internal_address = args.internal_address | |
ip, separator, port = internal_address.rpartition(":") | |
try: | |
assert separator | |
assert ipaddress.ip_address(ip) in ipaddress.ip_network(INTERNAL_SUBNET) | |
port = int(port) | |
assert 0 < port < 65536 | |
except Exception as _: | |
parser.error("invalid internal address") | |
return listen_port, ip, port, protocols | |
def main(): | |
listen_port, internal_ip, internal_port, protocols = get_args() | |
print("executing iptables commands...") | |
for protocol in protocols: | |
commands = ( | |
f"iptables -t nat -D PREROUTING -d {INTERNET_ADDRESS}/32 -i {INTERFACE} -p {protocol} " | |
f"--dport {listen_port} -j DNAT --to-destination {internal_ip}:{internal_port}", | |
f"iptables -D FORWARD -d {internal_ip}/32 -p {protocol} --dport {internal_port} " | |
f"-m state --state NEW,ESTABLISHED,RELATED -j ACCEPT", | |
) | |
for c in commands: | |
print(c) | |
os.system(c) | |
if __name__ == "__main__": | |
main() |
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
#!/bin/sh | |
echo "reloading IPv4 rules from iptables-persistent..." | |
iptables --flush | |
iptables --table nat --flush | |
iptables --delete-chain | |
iptables --table nat --delete-chain | |
iptables -F | |
iptables -X | |
iptables-restore < /etc/iptables/rules.v4 |
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
# Initial iptables config for NAT. | |
*nat | |
:PREROUTING ACCEPT [0:0] | |
:INPUT ACCEPT [0:0] | |
:OUTPUT ACCEPT [0:0] | |
:POSTROUTING ACCEPT [0:0] | |
-A POSTROUTING -s 192.168.0.0/24 -o vmbr0 -j SNAT --to-source 1.2.3.4 | |
COMMIT | |
*raw | |
:PREROUTING ACCEPT [0:0] | |
:OUTPUT ACCEPT [0:0] | |
COMMIT | |
*filter | |
:INPUT ACCEPT [0:0] | |
:FORWARD ACCEPT [0:0] | |
:OUTPUT ACCEPT [0:0] | |
-A FORWARD -s 192.168.0.0/24 -i vmbr0 -o vmbr0 -j ACCEPT | |
-A FORWARD -i vmbr0 -o vmbr0 -m state --state RELATED,ESTABLISHED -j ACCEPT | |
COMMIT |
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
#!/bin/sh | |
echo "saving IPv4 rules for iptables-persistent..." | |
iptables-save > /etc/iptables/rules.v4 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment