Last active
December 22, 2021 01:30
-
-
Save shimarin/11652af3853dd32641c376b4e76f0bfd to your computer and use it in GitHub Desktop.
Python script to build VPN config files for wireguard gateay server
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/python | |
import argparse,ipaddress,subprocess,re | |
import qrcode | |
def generate_privkey(): | |
return subprocess.check_output(["wg","genkey"]).decode("UTF-8").strip() | |
def get_pubkey(privkey): | |
return subprocess.check_output(["wg","pubkey"], input=privkey.encode("UTF-8")).decode("UTF-8").strip() | |
def octets(ipv4address): | |
i = int(ipv4address) | |
return (i >> 24, i >> 16 & 0xff, i >> 8 & 0xff, i & 0xff) | |
def main(global_v4_address, private_v4_address_start, private_v4_address_end, endpoint, port, mtu, conf_format, route_v4, route_v6, dns=None, privkey=None): | |
global_v4_address_in_octets = octets(global_v4_address) | |
if privkey is None: privkey = generate_privkey() | |
pubkey = get_pubkey(privkey) | |
if route_v4 == 'all': route_v4 = "0.0.0.0/0" | |
elif route_v4 == 'nolocal': route_v4 = "1.0.0.0/8, 2.0.0.0/8, 3.0.0.0/8, 4.0.0.0/6, 8.0.0.0/7, 11.0.0.0/8, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4" | |
if route_v6 == 'all': route_v6 = "::/0" | |
elif route_v6 == 'nolocal': route_v6 = "2000::/3" | |
allowedips = [] | |
if route_v4 is not None: allowedips.append(route_v4) | |
if route_v6 is not None: allowedips.append(route_v6) | |
with open("wg0.conf", "w") as f: | |
print("[Interface]", file=f) | |
print("ListenPort=%d" % port, file=f) | |
print("MTU=%d" % mtu, file=f) | |
print("PrivateKey=%s" % privkey, file=f) | |
print("", file=f) | |
for i in range(int(private_v4_address_start),int(private_v4_address_end) + 1): | |
peer_privkey = generate_privkey() | |
peer_ipv4_address = ipaddress.IPv4Address(i) | |
peer_ipv4_address_in_octets = octets(peer_ipv4_address) | |
peer_ipv6_address = "fd%02x:%d:%d:%d:%d:%d:%d:%d" % (global_v4_address_in_octets[0], global_v4_address_in_octets[1], global_v4_address_in_octets[2], global_v4_address_in_octets[3], peer_ipv4_address_in_octets[0], peer_ipv4_address_in_octets[1], peer_ipv4_address_in_octets[2], peer_ipv4_address_in_octets[3]) | |
print("[peer]", file=f) | |
print("PublicKey=%s" % get_pubkey(peer_privkey), file=f) | |
print("AllowedIPs=%s/32,%s/128" % (peer_ipv4_address, peer_ipv6_address), file=f) | |
print("", file=f) | |
peer_conf = conf_format.format(peer_ipv4_address_in_octets[0], peer_ipv4_address_in_octets[1], peer_ipv4_address_in_octets[2], peer_ipv4_address_in_octets[3]) | |
with open(peer_conf, "w") as f2: | |
print("[Interface]", file=f2) | |
print("Address=%s/32,%s/128" % (peer_ipv4_address, peer_ipv6_address), file=f2) | |
print("PrivateKey=%s" % peer_privkey, file=f2) | |
if dns is not None: print("DNS=%s" % dns, file=f2) | |
print("", file=f2) | |
print("[peer]", file=f2) | |
print("PublicKey=%s" % pubkey, file=f2) | |
if len(allowedips) > 0: | |
print("AllowedIPs=%s" % (",".join(allowedips)), file=f2) | |
print("Endpoint=%s:%d" % (endpoint, port), file=f2) | |
print("PersistentKeepalive=25", file=f2) | |
with open(peer_conf) as f2: | |
qrcode.make(f2.read()).save(re.sub('\\.conf$', '.png', peer_conf)) | |
print("Done.") | |
print("# for IPv4") | |
print("iptables -t nat -A POSTROUTING -s 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 -j MASQUERADE") | |
print("iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu") | |
print("# for IPv6") | |
print("ip6tables -t nat -A POSTROUTING -s fc00::/7 -j MASQUERADE") | |
print("ip6tables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu") | |
print("# sysctl.conf") | |
print("net.ipv4.ip_forward=1") | |
print("net.ipv6.conf.default.forwarding=1") | |
print("net.ipv6.conf.all.forwarding=1") | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument("--port", type=int, default=51820, help="WireGuard listen port") | |
parser.add_argument("--mtu", type=int, default=1280, help="Interface MTU") | |
parser.add_argument("--dns", help="DNS server to make peers use") | |
parser.add_argument("--privkey", default=None, help="Endpoint private Key(default: generate)") | |
parser.add_argument("--route-v4", default=None, help="AllowedIPs for IPv4. 'all' for all, 'nolocal' = for local addresses") | |
parser.add_argument("--route-v6", default=None, help="AllowedIPs for IPv6. 'all' for all, 'nolocal' = for local addresses") | |
parser.add_argument("--conf-format", default="wg-{0:03d}-{1:03d}-{2:03d}-{3:03d}.conf", help="conf filename format for peers") | |
parser.add_argument("global_v4_address") | |
parser.add_argument("private_v4_address_start") | |
parser.add_argument("private_v4_address_end") | |
parser.add_argument("endpoint") | |
args = parser.parse_args() | |
global_v4_address = ipaddress.IPv4Address(args.global_v4_address) | |
private_v4_address_start = ipaddress.IPv4Address(args.private_v4_address_start) | |
private_v4_address_end = ipaddress.IPv4Address(args.private_v4_address_end) | |
main(global_v4_address, private_v4_address_start, private_v4_address_end, args.endpoint, args.port, args.mtu, args.conf_format, args.route_v4, args.route_v6, args.dns, args.privkey) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment