{"id":13929146,"url":"https://github.com/atenart/sniproxy","last_synced_at":"2026-01-16T22:27:51.178Z","repository":{"id":39969900,"uuid":"166848833","full_name":"atenart/sniproxy","owner":"atenart","description":"TLS proxy routing TCP connections to backends based on the TLS SNI in the TLS handshake","archived":false,"fork":false,"pushed_at":"2025-11-17T09:36:29.000Z","size":266,"stargazers_count":49,"open_issues_count":1,"forks_count":18,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-11-17T11:24:23.750Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/atenart.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-01-21T16:54:11.000Z","updated_at":"2025-11-17T09:36:32.000Z","dependencies_parsed_at":"2024-05-14T09:52:09.362Z","dependency_job_id":"94e7eb6d-def1-4a7c-9f80-9c42f2dd320d","html_url":"https://github.com/atenart/sniproxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/atenart/sniproxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atenart%2Fsniproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atenart%2Fsniproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atenart%2Fsniproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atenart%2Fsniproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/atenart","download_url":"https://codeload.github.com/atenart/sniproxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/atenart%2Fsniproxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28485316,"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":[],"created_at":"2024-08-07T18:02:08.972Z","updated_at":"2026-01-16T22:27:51.153Z","avatar_url":"https://github.com/atenart.png","language":"Rust","readme":"# SNIProxy\n\n_SNIProxy_ is a TLS proxy, based on the TLS\n[Server Name Indication (SNI)](https://en.wikipedia.org/wiki/Server_Name_Indication).\nThe SNI is contained in TLS handshakes and _SNIProxy_ uses it to route\nconnections to backends. _SNIProxy_ does not need the TLS encryption keys and\ncannot decrypt the TLS traffic that goes through.\n\n_SNIProxy_ is meant to be simple to use and configure, with sane defaults and\nfew parameters.\n\nThis is developed and maintained as time allows on a best effort basis, please\nhave realistic expectations.\n\nA first version was written in [Go](https://go.dev) and can be found in the\n[archive/go](https://github.com/atenart/sniproxy/tree/archive/go) branch. It was\nlatter rewritten in [Rust](https://www.rust-lang.org).\n\n## Container image\n\n```shell\n$ podman run --name sniproxy -p 80:80/tcp -p 443:443/tcp \\\n     -v $(pwd)/sniproxy.yaml:/sniproxy.yaml:ro \\\n     ghcr.io/atenart/sniproxy:latest\n```\n\nThe above works with Docker too, just replace `podman` with `docker`.\n\n_SNIProxy_ handles HTTP connections and redirects those to their HTTPS\ncounterparts. If this is not needed, the above `-p 80:80/tcp` can be omitted.\n\n## Parameters\n\nThe log level can be controlled using the `--log-level` CLI parameter. By\ndefault `INFO` and above levels are reported. The configuration file can be\nselected by the `--config` CLI parameter, and defaults to `sniproxy.yaml`.\n\nSee `sniproxy --help` for a list of available parameters.\n\n## Configuration file\n\n_SNIProxy_'s configuration file is written in the\n[YAML](https://en.wikipedia.org/wiki/YAML) format.\n\n```text\n---\nbind_https: \u003caddress:port to bind to for HTTPS requests (default: \"[::]:443)\"\u003e\nbind_http: \u003caddress:port to bind to for HTTP requests (default: \"[::]:80)\"\u003e\nroutes:\n  - domains:\n      - \u003cdomain to match in the SNI\u003e\n      - \u003cdomain to match in the SNI\u003e\n    backend:\n      address: \u003caddress:port of the backend; address can be a resolvable hostname\u003e\n      proxy_protocol: \u003coptional; HAProxy protocol version (1 or 2)\u003e\n    alpn_challenge_backend:\n      address: \u003coptional; address:port for the ALPN challenge backend\u003e\n      proxy_protocol: \u003coptional; HAProxy protocol version (1 or 2)\u003e\n    alpn_challenge_bypass_acl: \u003coptional; boolean\u003e\n    denied_ranges:\n      - \u003coptional; ip/cidr range to block\u003e\n      - \u003coptional; ip/cidr range to block\u003e\n    allowed_ranges:\n      - \u003coptional; ip/cidr range to allow\u003e\n  - domains:\n    ...\n```\n\nA configuration for a single route can be as simple as:\n\n```yaml\n---\nroutes:\n  - domains:\n      - \"example.net\"\n    backend:\n      address: \"1.2.3.4:443\"\n```\n\nDomain names can be a regular expression:\n\n```yaml\n---\nroutes:\n  - domains:\n      # Matches example.net and all its subdomains.\n      - \"example.net\"\n      - \"*.example.net\"\n    backend:\n      address: \"1.2.3.4:443\"\n```\n\nDomains are matched against routes in the order they are defined in the\nconfiguration file, from top to bottom. The first route matching a domain is\nused even if a later one also matches, which can be the case with regular\nexpressions.\n\n### Optional parameters\n\n_SNIProxy_ has a built-in ACL logic and can block and allow connections based on\nthe client IP address. When at least one range is explicitly allowed, all other\nranges are automatically denied (0.0.0.0/0 \u0026 ::/0). When an address can be found\nin two ranges, the most specific wins. If the exact same range is both allowed\nand denied, the deny rule wins.\n\n```yaml\n---\nroutes:\n  - domains:\n      - \"example.net\"\n    backend:\n      address: \"1.2.3.4:8080\"\n    denied_ranges:\n      - \"10.0.0.42/32\"\n  - domains:\n      - \"foo.example.com\"\n    backend:\n      address: \"5.6.7.8:443\"\n    denied_ranges:\n      - \"10.0.0.42/32\"\n      - \"10.0.0.43/32\"\n      - \"192.168.0.0/24\"\n    allowed_ranges:\n      - \"192.168.0.42/32\"\n```\n\n_SNIProxy_ can use a different backend for ALPN requests:\n\n```yaml\n---\nroutes:\n  - domains:\n      - \"example.net\"\n    backend:\n      address: \"[1111::1]:8080\"\n    alpn_challenge_backend:\n      address: \"alpn-backend:8080\"\n```\n\nThe ACL rules can be bypassed for ALPN challenge requests:\n\n```yaml\n---\nroutes:\n  - domains:\n      - \"example.net\"\n    backend:\n      address: \"[1111::1]:8080\"\n    alpn_challenge_backend:\n      address: \"alpn-backend:8080\"\n    alpn_challenge_bypass_acl: true\n    allowed_ranges:\n      - \"192.168.0.0/24\"\n```\n\n[HAProxy PROXY protocol](https://www.haproxy.org/download/2.0/doc/proxy-protocol.txt)\nv1 and v2 are supported for backend connections:\n\n```yaml\n---\nroutes:\n  - domains:\n      - \"example.net\"\n    backend:\n      address: \"[1111::1]:8080\"\n      proxy_protocol: 2\n    alpn_challenge_backend:\n      address: \"alpn-backend:8080\"\n      proxy_protocol: 1\n```\n\n## Contribution guidelines\n\nThank you for considering contributing to _SNIProxy_! :tada:\n\n- Make sure all commits are\n  [signed off](https://www.kernel.org/doc/html/latest/process/submitting-patches.html?highlight=signed%20off#developer-s-certificate-of-origin-1-1).\n- We strictly follow the Rust coding style as enforced by `rustfmt`.\n- Please document new code (functions, structures, members, etc).\n- Add unit tests if applicable.\n- Pull requests require the [CI](.github/workflows/ci.yaml) to pass to be\n  merged.\n","funding_links":[],"categories":["others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatenart%2Fsniproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatenart%2Fsniproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatenart%2Fsniproxy/lists"}