{"id":20181386,"url":"https://github.com/ac000/sprotly","last_synced_at":"2025-04-10T05:10:21.603Z","repository":{"id":58125528,"uuid":"95167083","full_name":"ac000/sprotly","owner":"ac000","description":"Simple transparent https proxy forwarder using splice(2)","archived":false,"fork":false,"pushed_at":"2023-12-31T19:17:45.000Z","size":95,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-24T06:22:12.710Z","etag":null,"topics":["c","networking","splice","transparent-https-proxy"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ac000.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2017-06-23T00:13:53.000Z","updated_at":"2024-09-19T11:45:14.000Z","dependencies_parsed_at":"2023-10-01T19:51:49.063Z","dependency_job_id":null,"html_url":"https://github.com/ac000/sprotly","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac000%2Fsprotly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac000%2Fsprotly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac000%2Fsprotly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ac000%2Fsprotly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ac000","download_url":"https://codeload.github.com/ac000/sprotly/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248161274,"owners_count":21057555,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["c","networking","splice","transparent-https-proxy"],"created_at":"2024-11-14T02:35:23.604Z","updated_at":"2025-04-10T05:10:21.582Z","avatar_url":"https://github.com/ac000.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Overview\n\nWhat's in a name? *sprotly*; *proxy* -\u003e *proxly*, *x* -\u003e *t* for transparent\nand *s* for splice, as it uses the Linux *splice(2)* system call.\n\nsprotly is a tool to sit in front of a proxy such as squid and forward https\nclient requests to the proxy converting them into *CONNECT*'s.\n\nThis would be used for cases where you want to be able to perform some action\non https requests based purely on destination within squid and don't want them\nrun through SSLBump.\n\nThis is done by using an iptables rule to redirect port 443 traffic to a\nport that sprotly is listening on e.g\n\n    # ip6tables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 3129\n    # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 3129\n    # sprotly -l localhost:3129 -p :9443\n\nThus any traffic destined for port 443 is redirected to port 3129 where\nsprotly turns the standard requests into CONNECT's as squid would be\nexpecting them for https requests. The corresponding squid config for this\nwould be\n\n    http_port 9443\n\nIt then connects to squid on port 9443 (it will try IPv6 first then IPv4)\non localhost (by not specifying a host) and sends the CONNECT request, once\nit gets the OK from squid it then just shuffles packets back and forth\nbetween the client and squid.\n\n\n## Building\n\nThe only hard requirement is libac. On a rpm based system something like the\nfollowing should work\n\n    $ git clone https://github.com/ac000/libac\n    $ cd libac\n    $ cp libac.spec ~/rpmbuild/SPECS\n    $ git archive --format=tar --prefix=libac-$(grep ^Version libac.spec | cut -f 2)/ -o ~/rpmbuild/SOURCES/libac-$(grep ^Version libac.spec | cut -f 2).tar HEAD\n    $ rpmbuild -bb ~/rpmbuild/SPECS/libac.spec\n    $ sudo dnf install ~/rpmbuild/RPMS/x86_64/libac-\u003cVERSION\u003e-?.\u003cDIST\u003e.x86_64.rpm\n\nYou can create a suitable rpmbuild tree with\n\n    $ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}\n\nsprotly can optionally include support for seccomp via libseccomp if you have\nit installed, e.g on Red Hat based distros this would be the\n\n    libseccomp\n    libseccomp-devel\n\npackages.\n\nThis can be disabled at build time by setting the SPROTLY\\_SECCOMP shell\nenvironment variable to 0. e.g\n\n    $ SPROTLY_SECCOMP=0 make\n\nFor sprotly\n\n    $ git clone https://github.com/ac000/sprotly\n    $ cd src\n    $ make\n    $ sudo install -Dp 0755 sprotly /usr/local/sbin/\n\n\n## How to use\n\nsprotly has no configuration file and has only a few options\n\n    $ ./sprotly -h\n    Usage: sprotly [-D] \u003c-l [host]:port[,...]\u003e \u003c-p [proxy]:port\u003e [-s] [-v] [-h]\n\n      -D      - Run in debug mode. Log goes to terminal and runs in the\n                 foreground.\n      -l      - Listens on the optionally specified host/address(es) and\n                 port(s). If no host is specified uses the unspecified address\n                 (::, 0.0.0.0). Listens on both IPv6 and IPv4.\n      -p      - The optional host/address of the proxy and port to send\n                 requests to. If the host is unspecified uses localhost. Will\n                 try IPv6 first then IPv4.\n      -s      - Disable TLS SNI extraction.\n      -v      - Display the version.\n      -h      - Display this text.\n\n    Example -\n\n        sprotly -l localhost:3129 -p :9443\n\n*-l* and *-p* are the only required options. And the example shown is generally\nhow you'd want to run it.\n\n-l can take a comma separated list of [host]:port pairs.\n\nThis will tell sprotly to listen on port *3129* on *::1* and *127.0.0.1* for\nclient requests which have been redirected by the above ip{6}tables rules.\n\nIt will then send the *CONNECT* requests to the proxy running on *::1* or\n*127.0.0.1* on port *9443*.\n\nBy default sprotly will try to extract the requested hostname as given in the\nTLS SNI field from the 'Client Hello' message and use this in the *CONNECT*\nrequests. If there isn't one it will fall back to using the IP address as\nretrieved from the network stack.\n\n-s is used to tell sprotly not to do this and just use the IP address.\n\n\n## Architecture\n\nsprotly uses a multiprocess, multi-threaded architecture.\n\nWhen started, sprotly will fork a listen process for each cpu in the system.\nThese *listen* processes wait for new client connections and hand them off to\na *worker* thread.\n\nFor the actual sending/receiving of data to/from client/proxy it uses the\n*splice(2)* system call which has the potential to allow for zero copy I/O.\n\nHowever it does make sprotly somewhat file descriptor hungry requiring *six*\nfd's per connection. i.e\n\n    1 - peer socket\n    2 - peer pipe read end\n    3 - peer pipe write end\n    4 - proxy socket\n    5 - proxy pipe read end\n    6 - proxy pipe write end\n\nalthough on modern 64bit systems with plenty of RAM this shouldn't really be\nan issue, hence at startup sprotly will attempt to increase RLIMIT\\_NOFILE to\n*65536*. This limit is per-process and should allow for 10,000+ connections\nper worker.\n\nWhen run as root, the worker processes will change to run as the *sprotly*\nuser. Also sprotly will write to two log files; */var/log/sprotly/access_log*\nand */var/log/sprotly/error_log*.\n\nIf the sprotly user doesn't exist, then it will try using the 'nobody' user.\n\nYou can create a *sprotly* user like\n\n    # useradd -r -d / -s /sbin/nologin sprotly\n\nAlso by default sprotly will *daemon(3)ize* itself. When run in the foreground\n*(-D)* sprotly simply logs to the terminal.\n\nsprotly can also optionally do syscall filtering with seccomp(2) via\nlibseccomp if you have it installed.\n\n\n## License\n\nsprotly is licensed under the GNU General Public License version 2. See\n*GPL-2.0*.\n\nsrc/tls\\_sni.[ch] are licensed under the BSD 2-clause \"Simplified\" License, see\n*BSD-2-Clause*.\n\n\n## Credits\n\nIt should be noted that sprotly was heavily influenced by Andi Kleen's eproxy\nhttps://github.com/andikleen/eproxy\n\n\n## Contributing\n\nPatches and/or pull requests should be emailed to the project maintainer\n\n    Andrew Clayton \u003candrew@digital-domain.net\u003e\n\npreferably using *git-send-email(1)* and *git-request-pull(1)*\n\nCode should follow the coding style as outlined in *CodingStyle*.\n\nAlso, code should be signed-off. This means adding a line that says\n\n    Signed-off-by: Name \u003cemail\u003e\n\nat the end of each commit, indicating that you wrote the code and have the\nright to pass it on as an open source patch.\n\nSee: \u003chttp://developercertificate.org/\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fac000%2Fsprotly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fac000%2Fsprotly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fac000%2Fsprotly/lists"}