Haproxy supports the PROXY protocol which sends useful proxy information
to the backends even though we're not terminating tls on the haproxy
load balancer. Hopefully this will give us better x forwarded for
information which can be useful for debugging.
Rebase onto the current Anubis-era gitea vhost (which proxies to Anubis
at http://[::1]:10000/ rather than directly to gitea:3000) and except
IPv6 localhost (::1) in addition to 127.0.0.1 from the PROXY protocol
requirement. The functional tests connect to the backend directly, e.g.
`git clone https://localhost:3081`, where localhost resolves to ::1;
without that exception mod_remoteip's RemoteIPProxyProtocol drops those
header-less connections and system-config-run-gitea fails. The haproxy
load balancer is deliberately not excepted so mod_remoteip can still
recover the real client address for proxied traffic; its health checks
work because send-proxy also prepends the PROXY header to httpchk
connections.
Bind the balance_git_https listener as separate native IPv4 (0.0.0.0:443)
and IPv6 (:::443 v6only) sockets rather than a single dual-stack :::443.
On a dual-stack socket the kernel presents IPv4 peers as IPv4-mapped IPv6
(::ffff:A.B.C.D), so send-proxy emits `PROXY TCP6 ::ffff:...`, which
released Apache mod_remoteip rejects with AH03500 (its TCP6 address
charset has no '.'), aborting the connection -- including the gitea-lb
testinfra requests to 127.0.0.1 and every real IPv4 client once PROXY
protocol is enabled. Native sockets make haproxy emit `PROXY TCP4
A.B.C.D` for v4 clients, which mod_remoteip accepts; IPv6 clients still
get a native TCP6 header.
Set the backend proxy_string to 'send-proxy' only, not 'ssl send-proxy'.
The frontend bind has no 'ssl'/'crt', so in mode tcp haproxy relays the
byte stream and TLS is end-to-end between the client and gitea's Apache.
Adding 'ssl' to the server line makes haproxy open a second TLS session
to the backend and write the client's already-encrypted bytes into it;
Apache then decrypts the outer layer and reads the client's ClientHello
as a plaintext request, answering in cleartext to a client waiting for a
ServerHello. That surfaced as curl exit 35 in testinfra with nothing at
all in gitea's ssl error log. The existing check-ssl is unaffected: it
governs the health check, not the data path.
Do not emit RemoteIPTrustedProxy for the load balancers. That directive
only gates the header-based path (RemoteIPHeader, e.g. X-Forwarded-For),
and no RemoteIPHeader is set here, so the lines were inert. Access to
port 3081 is already restricted to the gitea-lb group by
iptables_extra_allowed_groups, and RemoteIPProxyProtocolExceptions is
what scopes PROXY header trust. Leaving them in would suggest the client
address depends on them, which it does not.
Change-Id: Ic223a7723babd10f0e7f010925462594c384f0de
Signed-off-by: Anil Belur <abelur@linuxfoundation.org>