{"id":18151288,"url":"https://github.com/msantos/libproxyproto","last_synced_at":"2025-04-28T17:43:14.725Z","repository":{"id":38358463,"uuid":"218541729","full_name":"msantos/libproxyproto","owner":"msantos","description":"Proxy protocol v1 and v2 support via an LD_PRELOAD library","archived":false,"fork":false,"pushed_at":"2023-11-24T13:50:49.000Z","size":56,"stargazers_count":28,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-30T11:41:36.671Z","etag":null,"topics":["ld-preload","ldpreload","proxy-protocol"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/msantos.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}},"created_at":"2019-10-30T14:06:26.000Z","updated_at":"2024-11-18T08:12:51.000Z","dependencies_parsed_at":"2022-08-24T03:01:13.191Z","dependency_job_id":"d69e9d20-899a-4a4b-9658-d4ba12d21e5b","html_url":"https://github.com/msantos/libproxyproto","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Flibproxyproto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Flibproxyproto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Flibproxyproto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/msantos%2Flibproxyproto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/msantos","download_url":"https://codeload.github.com/msantos/libproxyproto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251357664,"owners_count":21576750,"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":["ld-preload","ldpreload","proxy-protocol"],"created_at":"2024-11-02T01:07:15.547Z","updated_at":"2025-04-28T17:43:14.708Z","avatar_url":"https://github.com/msantos.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NAME\n\nlibproxyproto - LD_PRELOAD library for adding support for proxy protocol v1 and v2\n\n# SYNOPSIS\n\n* server\n\nLD_PRELOAD=libproxyproto.so *COMMAND* *ARG* *...*\n\n* test client\n\nLD_PRELOAD=libproxyproto_connect.so *COMMAND* *ARG* *...*\n\n# DESCRIPTION\n\nlibproxyproto provides a method for applications to discover the original\nclient IP address and port of proxied connections. The application must\nbe dynamically linked.\n\nIntermediary proxies insert the proxy protocol header before the application\ndata:\n\nhttps://github.com/haproxy/haproxy/blob/master/doc/proxy-protocol.txt\n\nProxy protocol v1 and v2 are supported.\n\nWhen the connection is `accept(2)`'ed, libproxyproto:\n\n* intercepts the call to `accept(2)`\n* reads the proxy protocol header\n* sets the source IP address and port in the `struct sockaddr` argument of\n  `accept(2)`\n* caches the IP address and intercepts calls to `getpeername(2)`\n\nlibproxyproto_connect does the same thing for calls to `connect(2)`\nand can be used for testing.\n\n# ENVIRONMENT VARIABLES\n\n## Compile\n\n`LIBPROXYPROTO_GETPEERNAME_CACHE`\n: enable or disable support for the `getpeername(2)` (default: ENABLED,\nset to any value to disable)\n\n## Runtime\n\n### common\n\n`LIBPROXYPROTO_DEBUG`\n: Write errors to stderr (default: disabled)\n\n### libproxyproto\n\n`LIBPROXYPROTO_MUST_USE_PROTOCOL_HEADER`\n: By default, connections without the proxy protocol header are\nallowed. Enabling this option drops connections without a protocol header\n(default: disabled).\n\n`LIBPROXYPROTO_VERSION`\n: Supported proxy protocol version (default: 3):\n\n```\n0: proxy protocol disabled\n1: proxy protocol v1 only\n2: proxy protocol v2 only\n3: proxy protocol v1 and v2\n```\n\n### libproxyproto_connect\n\n`LIBPROXYPROTO_ADDR`\n: Source IP address (default: 127.0.0.1)\n\n`LIBPROXYPROTO_PORT`\n: Source port (default: 8080)\n\n`LIBPROXYPROTO_VERSION`\n: Supported proxy protocol version (default: 2):\n\n```\n0: proxy protocol disabled\n1: proxy protocol v1\n2: proxy protocol v2\n```\n\n# EXAMPLES\n\n## netcat\n\n```\n# run in a shell\nLD_PRELOAD=libproxyproto.so nc -vvvv -k -l 9090\n\n# in another shell\nLD_PRELOAD=libproxyproto_connect.so \\\n LIBPROXYPROTO_ADDR=\"8.8.8.8\" LIBPROXYPROTO_PORT=\"4321\" \\\n nc 127.0.0.1 9090\n```\n\n### IPv6\n\n```\n# run in a shell\nLD_PRELOAD=libproxyproto.so nc -vvvv -n -6 -k -l 9090\n\n# in another shell\nLD_PRELOAD=libproxyproto_connect.so \\\n LIBPROXYPROTO_ADDR=\"2001:4860:4860::8888\" LIBPROXYPROTO_PORT=\"4321\" \\\n nc -6 -v localhost 9090\n```\n\n## haproxy.conf\n\n```\n# test haproxy\n# server: LD_PRELOAD=libproxyproto.so nc -vvvv -k -l 9090\ndefaults\n    mode tcp\n    timeout connect 4s\n    timeout client 30s\n    timeout server 30s\n\nlisten example\n    bind :8080\n    server test 127.0.0.1:9090 send-proxy-v2\n```\n\n# ALTERNATIVES\n\n* [proxyproto.nim](https://github.com/ba0f3/proxyproto.nim)\n\n# BENCHMARK\n\nTo give a very rough idea of the overhead, a\n[benchmark](https://github.com/path-network/go-mmproxy/blob/master/README.md#benchmark)\nwas run against an echo service.\n\nThis benchmark is not meant to be conclusive:\n\n* run over the loopback\n* on an old system running many other services\n\n## Benchmark Client\n\n[tcpkali](https://github.com/satori-com/tcpkali)\n\n```\ntcpkali -c 50 -T 10s -e1 'PROXY TCP4 127.0.0.1 127.0.0.1 \\{connection.uid} 25578\\r\\n' -m 'PING\\r\\n' 127.0.0.1:1122\n```\n\n## Echo Server\n\nTo run:\n\n```\nerlc echo.erl\n\n# no proxy: run on port 1122\nerl -noshell -eval \"echo:start()\"\n\n# libproxyproto: run on port 1122\nLD_PRELOAD=libproxyproto.so erl -noshell -eval \"echo:start()\"\n\n# go-mmproxy: run on port 1123\nerl -noshell -eval \"echo:start(1123)\"\nsudo ./go-mmproxy -l 0.0.0.0:1122 -4 127.0.0.1:1123\n```\n\n```erlang\n-module(echo).\n\n-export([start/0, start/1]).\n\nstart() -\u003e\n    start(1122).\n\nstart(Port) -\u003e\n    {ok, S} = gen_tcp:listen(Port, [\n        binary,\n        {reuseaddr, true},\n        {backlog, 1024}\n    ]),\n    accept(S).\n\naccept(LS) -\u003e\n    {ok, S} = gen_tcp:accept(LS),\n    Pid = spawn(fun() -\u003e recv(S) end),\n    _ = gen_tcp:controlling_process(S, Pid),\n    accept(LS).\n\nrecv(S) -\u003e\n    receive\n        {tcp, S, Data} -\u003e\n            gen_tcp:send(S, Data),\n            recv(S);\n        {tcp_closed, S} -\u003e\n            ok;\n        Error -\u003e\n            error_logger:error_report([{socket, S}, {error, Error}])\n    end.\n```\n\n## Results\n\n|               | ⇅ Mbps | ↓ Mbps   | ↑ Mbps   | ↓ pkt/s  | ↑ pkt/s  |\n|---------------|--------|----------|----------|----------|----------|\n| noproxy       | 98.238 | 2455.263 | 2456.626 | 229245.6 | 210847.5 |\n| libproxyproto | 94.974 | 2373.474 | 2375.247 | 221341.9 | 203862.9 |\n| go-mmproxy    | 76.567 | 1901.043 | 1927.293 | 163515.0 | 165415.9 |\n\nBandwidth per channel: ⇅ Mbps\nAggregate bandwidth: ↓, ↑ Mbps\nPacket rate estimate: ↓, ↑\n\n# SEE ALSO\n\n*connect*(2), *accept*(2), *getpeername*(2)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsantos%2Flibproxyproto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmsantos%2Flibproxyproto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmsantos%2Flibproxyproto/lists"}