zarya/lib/kontur_secrets.py
2026-10-31 14:30:03 +03:00

105 lines
3.7 KiB
Python

import base64
import json
import os
import secrets
import sys
import urllib.error
import urllib.request
import uuid
from cryptography.hazmat.primitives.asymmetric import x25519
action = sys.argv[1] if len(sys.argv) > 1 else "ensure"
node = sys.argv[2] if len(sys.argv) > 2 else ""
if not node:
sys.stderr.write("Node name required\n")
sys.exit(1)
vault_addr = os.environ.get("VAULT_ADDR", "http://10.0.10.12:8200").rstrip("/")
vault_token = os.environ.get("VAULT_TOKEN", "")
if not vault_token:
sys.stderr.write("VAULT_TOKEN not found in environment\n")
sys.exit(1)
endpoint = f"{vault_addr}/v1/secret/data/kontur/{node}"
existing_data = None
req_get = urllib.request.Request(endpoint, headers={"X-Vault-Token": vault_token})
try:
with urllib.request.urlopen(req_get) as resp:
body = json.loads(resp.read().decode())
existing_data = body.get("data", {}).get("data", {})
except urllib.error.HTTPError as e:
if e.code != 404:
sys.stderr.write(f"Vault error: {e.code} {e.reason}\n")
sys.exit(1)
if action == "show":
if not existing_data:
sys.stderr.write(f"No secrets found for {node}\n")
sys.exit(1)
public_view = {
"vless_uuid": existing_data.get("vless_uuid"),
"reality_public_key": existing_data.get("reality_public_key"),
"reality_short_id": existing_data.get("reality_short_id"),
"reality_server_name": existing_data.get("reality_server_name"),
"awg_server_public_key": existing_data.get("awg_server_public_key"),
"awg_router_public_key": existing_data.get("awg_router_public_key"),
"awg_h1": existing_data.get("awg_h1"),
"awg_h2": existing_data.get("awg_h2"),
"awg_h3": existing_data.get("awg_h3"),
"awg_h4": existing_data.get("awg_h4")
}
sys.stdout.write(json.dumps(public_view, indent=2) + "\n")
sys.exit(0)
if action == "ensure" and existing_data:
sys.stdout.write(f"Secrets for {node} already exist in Vault (idempotent, skipped)\n")
sys.exit(0)
v_srv = x25519.X25519PrivateKey.generate()
v_priv = base64.urlsafe_b64encode(v_srv.private_bytes_raw()).decode().rstrip("=")
v_pub = base64.urlsafe_b64encode(v_srv.public_key().public_bytes_raw()).decode().rstrip("=")
awg_srv = x25519.X25519PrivateKey.generate()
awg_s_priv = base64.b64encode(awg_srv.private_bytes_raw()).decode()
awg_s_pub = base64.b64encode(awg_srv.public_key().public_bytes_raw()).decode()
awg_rtr = x25519.X25519PrivateKey.generate()
awg_r_priv = base64.b64encode(awg_rtr.private_bytes_raw()).decode()
awg_r_pub = base64.b64encode(awg_rtr.public_key().public_bytes_raw()).decode()
payload = {
"data": {
"vless_uuid": str(uuid.uuid4()),
"reality_private_key": v_priv,
"reality_public_key": v_pub,
"reality_short_id": secrets.token_hex(4),
"reality_server_name": "sss.svoo.tech",
"awg_server_private_key": awg_s_priv,
"awg_server_public_key": awg_s_pub,
"awg_router_private_key": awg_r_priv,
"awg_router_public_key": awg_r_pub,
"awg_jc": 4,
"awg_jmin": 40,
"awg_jmax": 70,
"awg_s1": 15,
"awg_s2": 25,
"awg_h1": secrets.randbelow(4000000000) + 100000000,
"awg_h2": secrets.randbelow(4000000000) + 100000000,
"awg_h3": secrets.randbelow(4000000000) + 100000000,
"awg_h4": secrets.randbelow(4000000000) + 100000000
}
}
req_post = urllib.request.Request(
endpoint,
data=json.dumps(payload).encode(),
headers={"X-Vault-Token": vault_token, "Content-Type": "application/json"}
)
with urllib.request.urlopen(req_post) as resp:
if resp.status in (200, 204):
sys.stdout.write(f"Successfully initialized and stored secrets for {node} in Vault\n")