{"id":23889558,"url":"https://github.com/o-x-l/proxy-forwarder","last_synced_at":"2026-06-22T14:31:56.623Z","repository":{"id":190707914,"uuid":"683158737","full_name":"O-X-L/proxy-forwarder","owner":"O-X-L","description":"Service to forward traffic to a remote (Squid) proxy server (using NF-/IPTables)","archived":false,"fork":false,"pushed_at":"2023-09-23T14:35:05.000Z","size":339,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"latest","last_synced_at":"2025-02-23T04:44:31.880Z","etag":null,"topics":["forward-proxy","iptables","nftables","outbound-proxy","proxy","proxy-forwarder","squid","squid-proxy","squid-proxy-server"],"latest_commit_sha":null,"homepage":"https://wiki.superstes.eu/en/latest/1/network/squid.html#transparent-proxy","language":"Go","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/O-X-L.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,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-25T18:31:05.000Z","updated_at":"2024-10-02T07:46:32.000Z","dependencies_parsed_at":"2025-01-04T10:09:53.965Z","dependency_job_id":"df822d01-7737-40d4-86b0-3861f05846d4","html_url":"https://github.com/O-X-L/proxy-forwarder","commit_stats":null,"previous_names":["superstes/squid-dnat-forwarder","o-x-l/proxy-forwarder"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fproxy-forwarder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fproxy-forwarder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fproxy-forwarder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/O-X-L%2Fproxy-forwarder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/O-X-L","download_url":"https://codeload.github.com/O-X-L/proxy-forwarder/tar.gz/refs/heads/latest","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240271529,"owners_count":19774859,"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":["forward-proxy","iptables","nftables","outbound-proxy","proxy","proxy-forwarder","squid","squid-proxy","squid-proxy-server"],"created_at":"2025-01-04T10:09:48.900Z","updated_at":"2026-06-22T14:31:56.618Z","avatar_url":"https://github.com/O-X-L.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Proxy Forwarder\n\n\u003cp align=\"center\"\u003e\n    \u003ca title=\"Support this Project (Donate, Support-Licenses)\" href=\"https://shop.oxl.app/collections/open-source\"\u003e\n        \u003cimg src=\"https://files.oxl.at/img/badge-oss-support.svg\" alt=\"Support Badge (Donate, Support-Licenses)\"/\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n----\n\n[![Test](https://github.com/O-X-L/proxy-forwarder/actions/workflows/test.yml/badge.svg?branch=latest)](https://github.com/O-X-L/proxy-forwarder/actions/workflows/test.yml)\n\nThis tool is specifically designed to solve a problem when using proxy servers:\n\n* Setting the environment-variables 'HTTP_PROXY', 'HTTPS_PROXY', 'http_proxy' and 'https_proxy' for all applications and HTTP-clients may be problematic/too inconsistent\n* There is no clean way of forwarding all system traffic to a remote proxy server that is outside your layer 2 network\n* Some proxy servers (_like Squid_) do not support redirecting the traffic using DNAT\n\n\n\u003ca href=\"https://docs.o-x-l.com/proxy/forward_squid.html#transparent-proxy\"\u003e\n\u003cimg src=\"https://github.com/superstes/proxy-forwarder/blob/latest/docs/squid_remote.png\" alt=\"Remote Proxy Server\" width=\"600\"/\u003e\n\u003c/a\u003e\n\nFor more information about Squid see: [OXL Docs - Squid](https://docs.o-x-l.com/proxy/forward_squid.html)\n\n----\n\n## How does it work?\n\nThis tool is based on [go-gost](https://gost.run/en/tutorials/redirect/) but was stripped of all features/dependencies that are unnecessary to perform this task.\n\n### Support\n\n* Layer 3: IPv4 \u0026 IPv6\n* Layer 4: TCP\n* Application: redirect of HTTP \u0026 HTTPS\n* HTTP Versions: HTTP/1.0, HTTP/1.1, HTTP/2.0\n* Target-Proxy Protocols: HTTP, HTTPS\n\n### Usage\n\n```bash\n  -P 'Listen port' (required)\n  -F 'Proxy server to forward the traffic to' (required, Example: 'http://192.168.0.1:3128')\n  -T 'Enable TProxy mode'\n  -M 'Mark to set for TProxy traffic' (default: None)\n  -V 'Show version'\n  -D 'Enable debug mode'\n  -U 'Enable UDP listeners'\n  -metrics 'Set a metrics service address (prometheus)' (Example: '127.0.0.1:9000', Docs: 'https://gost.run/en/tutorials/metrics/')\n  -no-log-time 'Do not add timestamp to logs'  # use when systemd service\n```\n\n### It does\n\n* Bind to localhost (_127.0.0.1 \u0026 ::1_) for TCP\n* Allow you to redirect traffic to the forwarder using:\n\n  * Destination NAT (_default_)\n  * or [TProxy Mode](https://docs.kernel.org/networking/tproxy.html) (see also: [extended documentation](https://docs.o-x-l.com/firewall/nftables_tproxy.html#remote-proxy-problem))\n\n* Forward the traffic to the server defined using the `-F` flag\n\n\nThese are the main two files that cover the logic:\n\n* [redirect-tcp handler](https://github.com/superstes/proxy-forwarder/blob/latest/gost/x/handler/redirect/tcp/handler.go) (*HTTP/HTTPS split*)\n* [http connector](https://github.com/superstes/proxy-forwarder/blob/latest/gost/x/connector/http/connector.go) (*CONNECT Tunnel*)\n\n----\n\n## Install\n\nYou can download the binary for most mainstream systems [from the releases](https://github.com/superstes/proxy-forwarder/releases)!\n\n----\n\n## Examples\n\n```bash\n\u003e curl https://superstes.eu\n# proxy-forwarder\n2023-08-29 20:49:10 | INFO | handler | 192.168.11.104:36386 \u003c=\u003e superstes.eu:443/tcp | connection established\n# squid\nNONE_NONE/200 0 CONNECT superstes.eu:443 - HIER_NONE/- -\nTCP_TUNNEL/200 6178 CONNECT superstes.eu:443 - HIER_DIRECT/superstes.eu -\n\n\u003e curl http://superstes.eu\n# proxy-forwarder\n2023-08-29 20:49:07 | INFO | handler | 192.168.11.104:50808 \u003c=\u003e superstes.eu:80/tcp | connection established\n# squid\nTCP_REFRESH_MODIFIED/301 477 GET http://superstes.eu/ - HIER_DIRECT/superstes.eu text/html\n```\n\n----\n\n## Squid\n\nThis forwarder will connect:\n\n* https over a HTTP-connect 'tunnel'\n* plain http without such a 'tunnel'\n\nSo you need to make sure it is allowed by the proxy:\n\n```text\nacl CONNECT method CONNECT\nacl ssl_ports port 443\nacl step1 at_step SslBump1\n\nhttp_access deny CONNECT !ssl_ports\nhttp_access allow CONNECT step1\n# NOTE: without 'step1' one would be able to create a CONNECT 'tunnel' through the proxy\n```\n\n----\n\n## Redirect\n\n### NFTables\n\nFull example when using 'TProxy' mode: [NFTables - TProxy](https://gist.github.com/superstes/6b7ed764482e4a8a75334f269493ac2e)\n\n```bash\n# we expect you to have a table 'filter' of type 'inet'\nsudo nft list ruleset\n\n# whole input/forward traffic\nsudo nft 'add chain inet filter prerouting_dnat { type nat hook prerouting priority -100; }'\nsudo nft 'add rule inet filter prerouting_dnat tcp dport { 80, 443 } dnat to 127.0.0.1:3128'\n\n# whole output traffic - excluding the traffic for the proxy-forwarder itself (anti-loop)\nsudo nft 'add chain inet filter output_dnat { type nat hook output priority -100; }'\nsudo nft 'add rule inet filter output_dnat tcp dport { 80, 443 } meta skuid != 1100 dnat to 127.0.0.1:3128'\n\n# only output-traffic for one user to specific target (nice for testing purposes)\nsudo nft 'add rule inet filter output_dnat meta l4proto tcp ip daddr 1.1.1.1 dnat to 127.0.0.1:3128'\nsudo nft 'add rule inet filter output_dnat meta l4proto tcp ip6 daddr 2606:4700:4700::1111 dnat to [::1]:3128'\n```\n\n### IPTables\n\nFull example when using 'TProxy' mode: [IPTables - TProxy](https://gist.github.com/superstes/c4fefbf403f61812abf89165d7bc4000)\n\n```bash\n# whole input/forward traffic\nsudo iptables -t nat -I PREROUTING -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:3128\nsudo iptables -t nat -I PREROUTING -p tcp --dport 443 -j DNAT --to-destination 127.0.0.1:3128\n\n# whole output traffic - excluding the traffic for the proxy-forwarder itself (anti-loop)\nsudo iptables -t nat -I OUTPUT -m owner ! --uid-owner 1100 -p tcp --dport 80 -j DNAT --to-destination 127.0.0.1:3128\nsudo iptables -t nat -I OUTPUT -m owner ! --uid-owner 1100 -p tcp --dport 443 -j DNAT --to-destination 127.0.0.1:3128\n\n# only output-traffic for one user to specific target (nice for testing purposes)\nsudo iptables -t nat -I OUTPUT -m owner --uid-owner 1000 -d 135.181.170.219 -p tcp -j DNAT --to-destination 127.0.0.1:3128\n```\n\n----\n\n## Permissions\n\n### Destination NAT\n\nIf you use DNAT to redirect the traffic - the service user running the proxy-forwarder has no need for additional privileges!\n\nA default linux user with `/usr/sbin/nologin` as shell is enough.\n\n### TPROXY\n\nIf you want to use TPROXY to redirect the traffic - the service user needs the privilege to set `cap_net_raw` on its sockets.\n\nThe [CAP_NET_RAW](https://man7.org/linux/man-pages/man7/capabilities.7.html) may be needed for this:\n\n\u003e bind to any address for transparent proxying\n\nYou can add it like this:\n\n```bash\nsetcap cap_net_raw=+ep /usr/local/bin/proxy-forwarder\n\n# make sure only wanted users can execute the binary!\nuseradd proxy_forwarder --shell /usr/sbin/nologin\nchown root:proxy_forwarder /usr/local/bin/proxy-forwarder\nchmod 750 /usr/local/bin/proxy-forwarder\n```\n\n----\n\n## Service\n\nHere's an example systemd service to run the forwarder:\n\n```text\n# /etc/systemd/system/proxy-forwarder.service\n\n[Unit]\nDescription=Proxy forwarder\nDocumentation=https://github.com/superstes/proxy-forwarder\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/local/bin/proxy_forwarder -P 4128 -F http://192.168.1.20:3128 -no-log-time\nUser=proxy_forwarder\nGroup=proxy_forwarder\nRestart=on-failure\nRestartSec=5s\n\nStandardOutput=journal\nStandardError=journal\nSyslogIdentifier=proxy_forwarder\n\n[Install]\nWantedBy=multi-user.target\n```\n\n----\n\n## Build\n\n* [Install go](https://go.dev/doc/install)\n* Download this repository\n* Build the binary\n\n  ```bash\n  env GOOS=linux GOARCH=amd64 bash scripts/build.sh\n\n  # use 'CGO_ENABLED' if you see this error on the target system:\n  \u003e error \"/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32'\"\n\n  env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 bash scripts/build.sh\n  ```\n\n* Copy the new binary to the target host(s)\n* Run\n\n  ```bash\n  proxy_forwarder -P 4138 -F http://192.168.10.20:3128\n  ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Fproxy-forwarder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fo-x-l%2Fproxy-forwarder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fo-x-l%2Fproxy-forwarder/lists"}