Skip to content

Instantly share code, notes, and snippets.

@9seconds
Last active March 18, 2026 21:54
Show Gist options
  • Select an option

  • Save 9seconds/2b530664a98ffed7497169d4e67044cd to your computer and use it in GitHub Desktop.

Select an option

Save 9seconds/2b530664a98ffed7497169d4e67044cd to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import base64
import json
import re
import sys
import urllib.parse
def main():
data = sys.stdin.read()
try:
configs = json.loads(data)
except json.JSONDecodeError:
configs = list(parse_base64(data))
else:
configs = list(parse_json(configs))
if not configs:
sys.exit("Cannot find any configs")
singbox_config = {
"log": {
"level": "info"
},
"dns": {
"servers": [
{
"type": "tls",
"server": "1.1.1.1",
},
],
},
"inbounds": [
{
"type": "socks",
"tag": "socks-in",
"listen": "127.0.0.1",
"listen_port": 1080,
"sniff": False
}
],
"outbounds": [
{
"type": "urltest",
"tag": "auto",
"outbounds": [cfg["tag"] for cfg in configs],
"interrupt_exist_connections": False,
"interval": "10m",
}
] + configs,
"route": {
"rules": [],
"final": "auto"
}
}
print(json.dumps(singbox_config, indent=2, sort_keys=True))
def parse_base64(data):
value = base64.b64decode(data).decode()
for idx, url in enumerate(value.splitlines()):
parsed = urllib.parse.urlparse(url)
if parsed.scheme != "vless":
continue
matcher = re.fullmatch(r"(.+?)\@(.+?)\:(\d+)", parsed.netloc)
if not matcher:
continue
qs = urllib.parse.parse_qs(parsed.query)
if 'reality' not in qs.get('security', []):
continue
yield {
"type": "vless",
"tag": f"proxy-{idx}",
"server": matcher.group(2),
"server_port": int(matcher.group(3)),
"uuid": matcher.group(1),
"flow": qs["flow"][0],
"tls": {
"enabled": True,
"server_name": qs["sni"][0],
"utls": {
"enabled": True,
"fingerprint": qs["fp"][0]
},
"reality": {
"enabled": True,
"public_key": qs["pbk"][0],
"short_id": qs["sid"][0],
},
},
}
def parse_json(data):
for idx, element in enumerate(data):
for defn in element["outbounds"]:
if defn["protocol"] == "vless":
found = defn
break
else:
continue
vnext = found["settings"]["vnext"][0]
users = vnext["users"][0]
reality = found["streamSettings"]["realitySettings"]
yield {
"type": "vless",
"tag": f"proxy-{idx}",
"server": vnext["address"],
"server_port": vnext["port"],
"uuid": users["id"],
"flow": users["flow"],
"tls": {
"enabled": True,
"server_name": reality["serverName"],
"utls": {
"enabled": True,
"fingerprint": "random"
},
"reality": {
"enabled": True,
"public_key": reality["publicKey"],
"short_id": reality["shortId"],
},
},
}
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment