{"id":13337956,"url":"https://github.com/jcodybaker/snip","last_synced_at":"2026-03-03T03:04:49.451Z","repository":{"id":109221723,"uuid":"85437619","full_name":"jcodybaker/snip","owner":"jcodybaker","description":"TLS SNIp - Rule based proxy for routing/filtering TLS/SSL protocols.","archived":false,"fork":false,"pushed_at":"2017-05-03T01:55:39.000Z","size":1656,"stargazers_count":14,"open_issues_count":0,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-06-11T01:11:42.743Z","etag":null,"topics":["https","proxy","sni","sniproxy","ssl","tls"],"latest_commit_sha":null,"homepage":"","language":"C++","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/jcodybaker.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}},"created_at":"2017-03-18T23:03:15.000Z","updated_at":"2023-08-05T13:19:15.000Z","dependencies_parsed_at":"2023-03-07T07:45:37.258Z","dependency_job_id":null,"html_url":"https://github.com/jcodybaker/snip","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jcodybaker/snip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcodybaker%2Fsnip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcodybaker%2Fsnip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcodybaker%2Fsnip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcodybaker%2Fsnip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jcodybaker","download_url":"https://codeload.github.com/jcodybaker/snip/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jcodybaker%2Fsnip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30030839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-03T00:31:48.536Z","status":"online","status_checked_at":"2026-03-03T02:00:07.650Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["https","proxy","sni","sniproxy","ssl","tls"],"created_at":"2024-07-29T19:15:16.462Z","updated_at":"2026-03-03T03:04:49.414Z","avatar_url":"https://github.com/jcodybaker.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TLS SNIp - An SNI Based Proxy\n\n## Note:\nThis product is pre-1.0 and in active development as of April 2017.  See the Compatibility section for full status \nmore information\n\n## What is TLS?\nTransport Layer Security (TLS), known as SSL (Secure Socket Layer) in previous protocol versions, is used to secure \nnetwork communications between two application end-points (generally client and server software).  TLS provides\nmechanisms to verify the identity of each endpoint as well as the privacy and integrity of communicated data.  Because \nTLS maintains the semantics of the underlying duplex-stream protocol (TCP in most cases) it is well suited to retro-fit \nexisting stream based protocols. For example, Secure HTTP (HTTPS) is the common HTTP Protocol streamed over a TLS\nconnection.\n\n\n## What is SNI?\nServer Name Indication (SNI) is a TLS extension proposed in RFC 4366 (dated April 2006).  SNI provides for an optional\nclear-text indication of the target server's address in the opening phase of communication.  SNI allows TLS servers with \ncredentials for multiple identities to select and transmit a client-requested identity instead of blindly providing a \nsingle identity. As an example, virtual website hosting providers can use an SNI-enabled HTTPS servers to host multiple\nsecure website certificate identities on the same IP address and port.  Without SNI HTTPS servers can only effectively \nserve one certificate identity per IP address.  In practice this results in wastes IPv4 addresses which have non-trivial\ncosts and are in short demand. SNI support is commonly enabled in modern web browsers; see below for more details.\n\n## SNI Proxying\nIn SNI Proxying we use the client's Server Name Indication not to select an identity locally, but instead to select a\ntarget server which can provide that identity.  Once the target has been determined, the proxy server connects and\nbegins relaying data between the client and target.  The TLS negotiation occurs between the client and target server; \nthe proxy relays the handshake and encrypted data, but is not a party to the unencrypted communication.  \n\n## Use Cases\n\n### Mixed Platform HTTPS Hosting\nSmall and medium businesses are often allocated a single static IPv4 address for on-premise internet connectivity.\nTLS SNIp allows these businesses to host multiple HTTPS services on a single IPv4 address.  Communication between \nthe client browser and end service application is secured end-to-end.  The end HTTPS applications require no special\nconfiguration and can be hosted on the same server, or traverse the local network.\n![Mixed Platform Network Diagram](docs/MixedPlatformDiagram.png)\n\n## Building and Installing TLS SNIp\nTLS SNIp uses the cmake build system.  Cmake can generate build projects/scripts for unix make, xcode, and MS Visual\nStudio, among others.\n\n### Requirements\n- LibEvent 2.1\n- LibYAML\n\n## Configuration\nTLS SNIp uses [YAML 1.1](http://yaml.org/spec/1.1/) to describe its configuration.  YAML is a superset of JSON, meaning\nconfigurations can also be specified in JSON.  YAML permits comments on lines which start with \"#\".\n\n### Command Line Arguments\n\n```\n   -c FILE, --conf FILE       Specify an alternative config file.\n                              Default: snip.yml\n   -t, --test-config          Evaluate the config file and then exit. Exit code 0 for success.\n   -h, --help                 Display this help message.\n```\n\n### Reloading Configuration\nConfigurations can be reloaded by signaling HUP.  \n```\nkillall -HUP snip\n```\n\nTo be safe, you should test the configuration before reloading it.  Loading an invalid configuration can cause the\napplication to exist with an error. \n\n```\nif ./snip -t -c ../example.yml; then killall -HUP snip; fi\n```\n\nIf the 'user' configuration value is specified, TLS SNIp drops privileges after it binds to ports during launch. \nPrivileges cannot be regained after they have been dropped.  Adding an additional privileged listener and reloading,\nwill cause a fatal error when SNIp tries to bind the port with its reduced privileges.  \n\n### Configuration\n* \"**listeners**\" (**Required**) *List* - A list of listener objects, specified in the format listed below.\n* \"**routes**\" *(Optional) List|Dictionary* - A list of route objects, specified in the format listed below.\n* \"**disable_ipv4**\" *(Optional) Boolean* - Don't use IPv4 for outbound connections and don't bind IPv4 listeners for\n wildcard 'bind's. It is invalid to specify both \"disable_ipv4\" and \"disable_ipv6\"\n *Note: explicitly ipv6 listeners (ex. \"[::]:443\") will still bind.*\n* \"**disable_ipv6**\" *(Optional) Boolean* - Don't use IPv4 for outbound connections and don't bind IPv4 listeners for\n wildcard 'bind's.  \n *Note: explicitly ipv4 listeners (ex. \"0.0.0.0:443\") will still bind.*\n* \"**user**\" *(Optional, required if \"group\" is specified) String* - After binding the listeners, drop privileges and \n switch to the specified user.\n* \"**group**\" *(Optional) String* - After binding the listeners, drop privileges and switch to the specified group.\n* \"**default_route**\" *(Optional) Route Object* - Route used when the client handshake includes an SNI, but no targets\n match. Must NOT contain \"sni_hostname\" property. *Default: {\"action\": \"tls-unrecognized-name\"}*.\n* \"**no_sni_route**\" *(Optional) Route Object* - Route used when the client handshake does NOT include an SNI, but no\n targets match. Must NOT contain \"sni_hostname\" property. *Default: {\"action\": \"tls-unrecognized-name\"}*.\n* \"**tls_error_route**\" *(Optional) Route Object* - Route used when the client handshake is invalid or the TLS protocol\n is otherwise violated. Must NOT contain \"sni_hostname\" property. *Default: {\"action\": \"tls-decode-error\"}*.\n* \"**http_fallback_route**\" *(Optional) Route Object* - Route used when client does not send TLS data, but instead sends\n something that looks similar to HTTP. Must NOT contain \"sni_hostname\" property. *Default: {\"action\": \"hangup\"}*.\n* \"**proxy_connect_failure**\" *(Optional) Route Object* - Route used when we fail to connect to the specified target. \n Must NOT contain \"sni_hostname\" property. *Default: {\"action\": \"tls-internal-error\"}*.\n\n#### Listeners\nListeners describe a configuration for a specific port which TLS SNIp will proxy. The configuration must specify at \nleast one listener.\n\n* \"**bind**\" (**Required**) *String|Number* - A port and optional address TLS SNIp should listen on.  \n The following formats are valid\n  * \"port\" or \"*:port\" (ex. \"443\" or \"*:443\") - TLS SNIp will listen at the specified port on all IPv4 and IPv6 sockets\n    unless \"disable_ipv4\" or \"disable_ipv6\" are specified.\n  * \"0.0.0.0:port\" (ex. \"0.0.0.0:443\") - TLS SNIp will listen at the specified port on all IPv4 sockets.\n  * \"[::]:port\" (ex. \"[::]:443\") - TLS SNIp will listen at the specified port on all IPv6 sockets.\n  * \"IPv4:port\" (ex. \"10.0.0.1:443\") - TLS SNIp will listen at the specified port on the interface which has the \n    specified address.\n  * \"[IPv6]:port\" (ex. \"[::1]:443\") - TLS SNIp will listen at the specified port on the interface which has the\n    specified address.\n* \"**routes**\" *(Optional) List|Dictionary* - A list of route objects, specified in the format listed below. \n\nAdditionally, listeners may override the \"**default_route**\", \"**no_sni_route**\", \"**tls_error_route**\", \n \"**http_fallback_route**\", \"**proxy_connect_failure**\" properties specified in the root.\n\n\n#### Routes\nRoutes can be specified globally or on specific listeners. Routes are matched in the order of they are listed.  Routes\nspecified on the listener will be attempted first, followed by global routes. Routes can be specified in a long format\nand a shortcut format.\n\n##### Long Format\n* \"action\" *(Optional - Default: \"proxy\" if target specified, \"hangup\" otherwise.)* - Action which should be performed if the route matches.  The value must be one of the\n following.\n  * \"hangup\" - Immediately disconnect the client connection.\n  * \"proxy\" - Make an outbound connection to \"target\" and proxy reads and writes. \"target\" is a required \n     parameter.\n  * \"tls-close-notify\" - Send a \"close_notify\" TLS fatal alert to the client and then immediately disconnect. \n  * \"tls-handshake-failure\" - Send a \"handshake_failure\" TLS fatal alert to the client and then immediately disconnect. \n  * \"tls-protocol-version\" - Send a \"protocol_version\" TLS fatal alert to the client and then immediately disconnect. \n  * \"tls-decode-error\" - Send a \"decode_error\" TLS fatal alert to the client and then immediately disconnect. \n  * \"tls-internal-error\" - Send a \"internal_error\" TLS fatal alert to the client and then immediately disconnect. \n  * \"tls-unrecognized-name\" - Send a \"unrecognized_name\" TLS fatal alert to the client and then immediately disconnect. \n  \n* \"sni_hostname\" *(Required in \"routes\" section) String* - Matched against the SNI hostname transmitted in the client's\n connection header.  This comparison is case-insensitive.\n* \"target\" *(Required if action=\"proxy\") String* - An IP Address (ex. \"192.168.1.1\" and \"192.168.1.1:443\") or hostname \n (ex. \"www.github.com\" \"www.github.com:443\") proxy destination.  If a port is not specified, one will be inferred from\n the listener's bind port.  Hostnames will be resolved at the time of connection.\n  \n##### Shortcut Format\nThe \"routes\" section can be specified as dictionary where the key is the \"sni_hostname\" (see above) and the value maps\n to the \"target\" field (see above).\n \nFor example:\n```\nroutes:\n  \"www.example.com\": \"internal.example.com\"\n  \"www.foo.com\": \"bar.com:443\"\n  \"github.com\": \"192.168.1.1:443\"\n```\n\n#### Examples\n```yaml\n# Example snip configuration file.\nlisteners:\n- bind: \"0.0.0.0:443\"\n  routes:\n    - sni_hostname: \"www.bing.com\"\n      target: \"bing.com:443\"\n- bind: 8443\n  routes:\n    \"www.bing.com\": \"bing.com\"\n- bind: \"*:9443\"\n- bind: \"[::]:10443\"\nroutes:\n  \"www.google.com\": \"google.com\"\n  \"www.yahoo.com\": \"yahoo.com:443\"\n```\n\n```yaml\n# Example snip configuration file, encoded as JSON.  Note: comments are still valid.\n{\n  \"listeners\": [\n    {\n      \"bind\": \"0.0.0.0:443\",\n      \"routes\": [\n        {\n          \"sni_hostname\": \"www.bing.com\",\n          \"target\": \"bing.com:443\"\n        }\n      ]\n    },\n    {\n      \"bind\": \"0.0.0.0:8443\",\n      \"routes\": {\n        \"www.bing.com\": \"bing.com\"\n      }\n    }\n  ],\n  \"routes\": {\n    \"www.google.com\": \"google.com\",\n    \"www.yahoo.com\": \"yahoo.com:443\"\n  }\n}\n\n```\n\n## Todo / Bugs / Feature Requests\nThis software is currently pre-1.0, meaning that while it works, the feature set is non-complete.  If you desire \n additional functionality or want to nominate one of the below-listed items for higher priority, please file an issue on\n this project or contact me at cody@codybaker.com.\n\n* Regex matching / targets\n* Improve Windows support - \n  + Provide support for installing / running as we Windows Service\n  + Investigate minimum permissions necessary.\n  + Provide option for hot-reloading configuration.\n* International URLs\n* DNS caching - On some platforms the DNS resolver used may issue DNS requests for each connection instead of internally\n  caching or using the systems own cache.\n* Clear-text endpoints, where TLS SNIp uses OpenSSL/BoringSSL to provide encryption.\n* On-Demand Certificates for clear-text end-points.\n* On-Demand Recertification for TLS-endpoints. We intercept the ServerHello, pull the public key from the certificate,\n  and sub-in an alternative certificate signed against the same key.\n* Ability to filter requests for insecure ciphers/protocol versions from TLS/SSL endpoints which don't offer those\n  configuration options.\n* Docker container  \n* Client stickiness based on session id.\n* End-point health checking\n* Multiple targets / balancing.\n* Binary packages.\n* Init scripts for system v, systemd, launchd\n* Route matching based on TLS version.\n* Ability to filter unsafe client versions and/or avoid vulnerabilities.\n* Better control of buffers.\n\n## Compatibility\nThis product is still pre-1.0 and as such still has some features / glitches.  As of May 2017 the following\n compatibility/completeness issues are known.\n\n### OSX\nSupports all features.  Given that most environments don't provide libevent-2.1 or libyaml by default, building with \n\"-D SNIP__DOWNLOAD_AND_BUILD_DEPENDENCIES=on\" is recommended.\n\n### Windows\nIn progress.  Compiles and runs, but not well tested.  Known issues: does not take command line arguments, or support hot reloads.  \n\n### Linux\nSupports all features.  Most environments currently only provide libevent-2.0.  Work will be done to support libevent \n2.0 in the future.\n\n## Copyright \u0026 License\nTLS SNIp is copyright 2017 J Cody Baker. All rights reserved.  The project is licensed for use under an MIT-style\nlicense which can be found in the LICENSE file.  ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcodybaker%2Fsnip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjcodybaker%2Fsnip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjcodybaker%2Fsnip/lists"}