wireguard-setup/scripts/rotate.py

78 lines
1.8 KiB
Python
Raw Normal View History

2021-09-21 11:52:17 +00:00
#!/usr/bin/env python3
2022-07-23 21:03:20 +00:00
from typing import Optional
2022-07-23 21:17:06 +00:00
import sys
2021-09-21 11:52:17 +00:00
import subprocess
2021-11-03 07:51:41 +00:00
import requests
2022-07-23 21:03:20 +00:00
import pydantic
class Server(pydantic.BaseModel):
public_key: str
endpoint: str
class ServerConfig(pydantic.BaseModel):
servers: list[Server]
current: Server
private_key: str
2021-09-21 11:52:17 +00:00
def offline():
2021-11-03 07:51:41 +00:00
try:
requests.head("https://1.1.1.1", timeout=1)
2022-07-23 21:03:20 +00:00
except IOError:
2021-11-03 07:51:41 +00:00
return True
else:
2022-07-23 21:09:51 +00:00
return False
2022-07-23 21:03:20 +00:00
2021-09-21 11:52:17 +00:00
2022-07-23 21:03:20 +00:00
def select_server() -> Optional[ServerConfig]:
2021-09-21 11:52:17 +00:00
try:
2022-07-23 21:03:20 +00:00
servers = ServerConfig.parse_file(
"/snacks/wireguard/servers.json", encoding="utf-8"
)
except (IOError, pydantic.ValidationError):
return None
servers.servers.append(servers.current)
servers.current = servers.servers.pop(0)
return servers
def write_json(servers: ServerConfig):
2021-09-21 11:52:17 +00:00
try:
2022-07-23 21:03:20 +00:00
with open("/snacks/wireguard/servers.json", mode="w", encoding="utf-8") as f:
f.write(servers.json(indent=4))
except IOError:
pass
def write_wg(server: Server, private_key: str):
wg_conf = (
"[Interface]\n"
f"privatekey = {private_key}\n\n"
"[Peer]\n"
f"publickey = {server.public_key}\n"
f"endpoint = {server.endpoint}\n"
"persistentkeepalive = 20\n"
"allowedips = 0.0.0.0/0, ::/0\n"
)
try:
with open("/snacks/wireguard/wg.conf", mode="w", encoding="utf-8") as f:
f.write(wg_conf)
except IOError:
pass
def main():
2022-07-23 21:17:06 +00:00
if ((len(sys.argv) == 2 and sys.argv[1] == "--force") or offline()) and (
servers := select_server()
):
2022-07-23 21:03:20 +00:00
write_json(servers)
write_wg(servers.current, servers.private_key)
subprocess.run(["systemctl", "restart", "vpnclient-wg"], check=False)
if __name__ == "__main__":
main()