Skip to content

Instantly share code, notes, and snippets.

@9seconds
Last active March 12, 2026 23:10
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 argparse
import gzip
import json
import urllib.request
def main():
options = get_options()
req = urllib.request.Request(
options.url,
headers={"Accept-Encoding": "gzip"}
)
with urllib.request.urlopen(req, timeout=60) as resp:
if resp.headers.get("Content-Encoding", "") == "gzip":
resp = gzip.open(resp)
data = json.load(resp)
configs = [make_config(idx, cfg) for idx, cfg in enumerate(data)]
configs = [cfg for cfg in configs if cfg]
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 make_config(idx, element):
for defn in element["outbounds"]:
if defn["protocol"] == "vless":
found = defn
break
else:
return None
vnext = found["settings"]["vnext"][0]
users = vnext["users"][0]
reality = found["streamSettings"]["realitySettings"]
return {
"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"],
},
},
}
def get_options():
parser = argparse.ArgumentParser(
description="Parse subscription lists and generate sing-box config",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
"url",
help="URL to use"
)
return parser.parse_args()
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment