{"id":13592153,"url":"https://github.com/monsterxx03/snet","last_synced_at":"2026-01-16T19:56:17.210Z","repository":{"id":88381136,"uuid":"174795209","full_name":"monsterxx03/snet","owner":"monsterxx03","description":"transparent proxy works on linux desktop, MacOS, router","archived":false,"fork":false,"pushed_at":"2023-02-25T00:00:30.000Z","size":13704,"stargazers_count":73,"open_issues_count":11,"forks_count":11,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-08T23:31:36.687Z","etag":null,"topics":["linux","macos","transparent-proxy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/monsterxx03.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-03-10T08:10:46.000Z","updated_at":"2024-12-05T09:17:20.000Z","dependencies_parsed_at":"2023-07-28T08:15:21.613Z","dependency_job_id":null,"html_url":"https://github.com/monsterxx03/snet","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/monsterxx03/snet","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monsterxx03%2Fsnet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monsterxx03%2Fsnet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monsterxx03%2Fsnet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monsterxx03%2Fsnet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/monsterxx03","download_url":"https://codeload.github.com/monsterxx03/snet/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/monsterxx03%2Fsnet/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28482136,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linux","macos","transparent-proxy"],"created_at":"2024-08-01T16:01:06.311Z","updated_at":"2026-01-16T19:56:17.194Z","avatar_url":"https://github.com/monsterxx03.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"[![codecov](https://codecov.io/gh/monsterxx03/snet/branch/master/graph/badge.svg)](https://codecov.io/gh/monsterxx03/snet)\n![](https://github.com/monsterxx03/snet/workflows/Go/badge.svg)\n\n# SNET\n\nSystemwide transparent tcp proxy works on linux, MacOS, router.\n\nIt's a solution like: (redsocks + ss-local)/ss-redir + ChinaDNS. But all in one binary, don't depend on dnsmasq.\n\n## Features\n\n- ss/go-ss2/http-tunnel/tls-tunnel/socks5 as upstream server\n- Bypass traffic in China\n- Handle DNS in the way like ChinaDNS, so website have CDN out of China won't be redirected to their overseas site\n- Local DNS cache based on TTL\n- block by domain name\n- hostname map\n- DNS prefetch\n- stats api and a top like terminal UI\n\n## Usage\n\n\n### As client\n\nFor linux: ensure **iptables** and **ipset** installed in your system.\n\nFor macos: pfctl is included by default, no extra dependences.\n\nExample config.json:\n\n    {\n        \"as-upstream\": false,\n        \"listen-host\": \"127.0.0.1\",\n        \"listen-port\": 1111,\n        \"proxy-type\": \"ss\",\n        \"proxy-timeout\":  30,\n        # `bypassCN` or `global`, default to `bypassCN`\n        \"proxy-scope\": \"bypassCN\",\n        # target host list will bypass snet\n        \"bypass-hosts\": [\"a.com\"],\n        # only work on \"mode\": \"router\", traffic from those ips will bypass snet, use case: home NAS\n        \"bypass-src-ips\": [\"192.168.1.100\"],\n\n        # config used when proxy-type is \"http\"\n        \"http-proxy-host\": \"\",\n        \"http-proxy-port\": 8080,\n        \"http-proxy-auth-user\": \"\",\n        \"http-proxy-auth-password\": \"\",\n\n        # config used when proxy-type is \"ss\"\n        \"ss-host\": \"ss.example.com\",\n        \"ss-port\": 8080,\n        # https://github.com/shadowsocks/shadowsocks-go/blob/1.2.1/shadowsocks/encrypt.go#L159\n        \"ss-chpier-method\": \"aes-256-cfb\",\n        \"ss-passwd\": \"passwd\",\n    \n        # config used when proxy-type is \"ss2\"\n        \"ss2-host\": \"\",\n        \"ss2-port\": 8080,\n        # https://github.com/shadowsocks/go-shadowsocks2/blob/v0.1.3/core/cipher.go#L29\n        \"ss2-cipher-method\": \"AEAD_CHACHA20_POLY1305\",\n        \"ss2-key\": \"\",\n        \"ss2-password\": \"passwd\"\n\n        # config used when proxy-type is \"tls\"\n        \"tls-host\": \"\",\n        \"tls-port\": 443,\n        \"tls-token\": \"tlstoken\",\n\n        # config used when proxy-type is \"socks5\"\n        \"socks5-host\": \"\",\n        \"socks5-port\": 1080,\n        \"socks5-auth-user\": \"\",\n        \"socks5-auth-password\": \"\",\n\n        \"cn-dns\": \"114.114.114.114\",  # dns in China\n        \"fq-dns\": \"8.8.8.8\",  # clean dns out of China\n        \"enable-dns-cache\": true,\n        \"enforce-ttl\": 3600,  # if \u003e 0, will use this value otherthan A record's TTL\n        \"disable-qtypes\": [\"AAAA\"], # return empty dns msg for those query types\n        \"force-fq\": [\"*.cloudfront.net\"], # domain pattern matched will skip cn-dns query\n        \"dns-logging-file\": \"dns.log\",  # dns query will be logged in this file\n\n        \"dns-prefetch-enable\": true,\n        \"dns-prefetch-count\":  100,  # prefetch top 10 freq used domains in cache.\n        \"dns-prefetch-interval\": 60, \n\n        \"host-map\": {\n            \"google.com\": \"2.2.2.2\"  # map host and ip\n        },\n        \"block-host-file\": \"\", # if set, domain name in this file will return 127.0.0.1 to client\n        \"block-hosts\": [\"*.hpplay.cn\"], # support block hosts with wildcard\n        \"mode\": \"local\",   # run on desktop: local, run on router: router\n\n        \"active-eni\": \"\"   # only used on Mac, if multi network interface is active, snet try to use the one with highest priority, use this option to override this behavior\n    }\n\n**proxy-type**:\n\n- ss: use ss as upstream server\n- ss2: use go-ss2(https://github.com/shadowsocks/go-shadowsocks2) as upstream server\n- http: use http proxy server as upstream server(should support `CONNECT` method, eg: squid)\n- tls: use snet tls tunnel as upstream server, see: https://github.com/monsterxx03/snet#as-upstream-server\n- socks5: use socks5 as upstream server. Note: if your socks5 proxy server is running on same host with snet, ensure to add socks5's upstream server address to snet's `bypass-hosts` list, or socks5's traffic to upstream server will be hijacked by snet, being a loop.\n\n`snet` will modify iptables/pf, root privilege is required. \n\n`sudo ./snet -config config.json`\n\nTest (proxy-scope = bypassCN):\n\n- curl `ifconfig.me`, ip should be your ss server ip.\n- curl `myip.ipip.net`, ip should be your local ip in China.\n\nIf proxy-scope is `global`, both should return ss server ip.\n\nIf you use it on router, change `mode` to `router`, and listen-host should be your router's ip or `0.0.0.0`\n\n### Stats api and terminal top UI\n\nIn config.json:\n\n- \"enable-stats\": true  // enable stats api\n- \"stats-port\": 8810 // stats api listen port\n- \"stats-enable-tls-sni-sniffer\": true  // parse server name from tls sni(for traffic to port 443)\n- \"stats-enable-http-host-sniffer\": true // parse server from from http header(for traffic to port 80)\n\nsnet server will serve stats api on  port 8810 \n\ncurl http://localhost:8810/stats\n\n    \n        {\n            \"Uptime\": \"26m42s\",\n            \"Total\": {\n                \"RxSize\": 161539743,\n                \"TxSize\": 1960171\n            },\n            \"Hosts\": [\n                {\n                    \"Host\": \"github.com\",\n                    \"Port\": 443,\n                    \"RxRate\": 0,\n                    \"TxRate\": 0,\n                    \"RxSize\": 840413,\n                    \"TxSize\": 172528\n                },\n                {\n                    \"Host\": \"live.github.com\",\n                    \"Port\": 443,\n                    \"RxRate\": 0,\n                    \"TxRate\": 0,\n                    \"RxSize\": 25710,\n                    \"TxSize\": 12218\n                },\n                {\n                    \"Host\": \"encrypted-tbn0.gstatic.com\",\n                    \"Port\": 443,\n                    \"RxRate\": 0,\n                    \"TxRate\": 0,\n                    \"RxSize\": 25418,\n                    \"TxSize\": 960\n                },\n                {\n                    \"Host\": \"ogs.google.com\",\n                    \"Port\": 443,\n                    \"RxRate\": 0,\n                    \"TxRate\": 0,\n                    \"RxSize\": 38138,\n                    \"TxSize\": 2198\n                }\n                ...\n            ]\n        }\n\n\nTop like UI: ./snet -top\n\n\n![top](images/top.gif)\n\n\n### As upstream server\n\nexample config.json:\n\n    {\n        \"as-upstream\": true,\n        \"upstream-type\": \"tls\",\n        \"upstream-tls-server-listen\": \"0.0.0.0:9999\",\n        \"upstream-tls-key\": \"server.key\", # created by: openssl genrsa -out server.key 2048\n        \"upstream-tls-crt\": \"server.pem\", # created by: openssl req -new -x509 -key server.key -out server.pem -days 3650\n        \"upstream-tls-token\": \"xxxx\"  # random string\n    }\n\nOnly support tls tunnel when run as upstream server\n\nupstream-type:\n\n- tls: run as tls tunnel server\n\nRun:\n\n    ./snet -config config.json\n\n## For traffic from docker container\n\nSolution 1:\n\n- Change `listen-host` to `0.0.0.0`, `mode` to `router`.\n- Traffic from docker container's src ip is 172.17.0.1/16, it will go through `nat prerouting chain` -\u003e `filter foward chain` -\u003e `nat postrouting chain`, not `nat output chain`.\n- The main reason I need a `client mode` and `router mode` is handling DNS redirct, don't know how to make it work for `PREROUTING chain` and `OUTPUT chain` at the same time.\n\nSolution 2:\n\n- Use host network: `docker run --network host ...`\n\n## Hot reload\n\nIf config.json is changed, use HUP signal to reload.\n\n    kill -HUP $(pgrep snet)\n\nDuring hot reload:\n\n- dns cache will be reserved.\n- all tcp connections will be closed.\n\nsnet will try to find active network interface current using on starting, you can use `active-eni` option (eg: en4) to override it.\n\n## Tested on:\n\nDesktop:\n\n- manjaro\n- ubuntu 18.04\n- MacOS 10.15.1\n\nRouter:\n\n- hiwifi2\n- ubnt er-x\n\n## Known issue:\n\n- Manjaro's NetworkManager will create a ipv6 dns nameserver in /etc/resolv.conf, eg: `nameserver fe80::1%enp51s0`.\nIf it's first nameserver, dns query will bypass `snet`(since I didn't handle ipv6), you need to disable ipv6 or put it on second line.\n- Chrome's cache for google.com is wired.If you can visit youtube.com or twitter.com, but can't open google.com, try to restart chrome to clean dns cache.\n- cn-dns should be different with the one in your /et/resolv.conf, otherwise dns lookup will by pass snet (iptable rules in SNET chain)\n\n## artilces:\n\n- https://blog.monsterxx03.com/tags/snet/ \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonsterxx03%2Fsnet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmonsterxx03%2Fsnet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmonsterxx03%2Fsnet/lists"}