neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
proxy fixes
ddb8532 · gmorell · 2026-05-21 05:13
Files changed
modified
deploy/argo/neiam-ircd/app.yml
+9
−3
@@ -94,7 +94,10 @@ spec:
| 94 | 94 | initialDelaySeconds: 10 |
| 95 | 95 | periodSeconds: 5 |
| 96 | 96 | livenessProbe: |
| 97 | − tcpSocket: { port: irc } | |
| 97 | + # Use the HTTP port — same BEAM serves it, no PROXY required. | |
| 98 | + # A bare TCP connect to 6667 would now fail because the | |
| 99 | + # listener expects a PROXY header on every connection. | |
| 100 | + httpGet: { path: /, port: http } | |
| 98 | 101 | initialDelaySeconds: 30 |
| 99 | 102 | periodSeconds: 15 |
| 100 | 103 |
@@ -214,7 +217,10 @@ spec:
| 214 | 217 | services: |
| 215 | 218 | - name: ircd-irc |
| 216 | 219 | port: 6697 |
| 217 | − proxyProtocol: | |
| 218 | − version: 2 | |
| 220 | + # No proxyProtocol here — when Traefik does TLS passthrough, | |
| 221 | + # the PROXY v2 header would land before the ClientHello and | |
| 222 | + # confuse :ssl in the pod. TLS users currently appear as | |
| 223 | + # Traefik's IP; switching to TLS-termination-at-Traefik with | |
| 224 | + # PROXY would fix it but loses per-handshake cert refresh. | |
| 219 | 225 | tls: |
| 220 | 226 | passthrough: true |
modified
lib/oh_my_ex_oh_ircd/irc/connection.ex
+16
−6
@@ -116,20 +116,30 @@ defmodule OhMyExOhIrcd.IRC.Connection do
| 116 | 116 | end |
| 117 | 117 | |
| 118 | 118 | defp handle_proxy_header(socket, state) do |
| 119 | + require Logger | |
| 120 | + | |
| 119 | 121 | case OhMyExOhIrcd.IRC.Proxy.read_header(socket, 5_000) do |
| 120 | 122 | {:ok, real_ip, leftover} -> |
| 121 | 123 | {:continue, %{state | host: real_ip, buffer: leftover}} |
| 122 | 124 | |
| 123 | 125 | :no_header -> |
| 124 | − # No header arrived. With proxy_protocol enabled this is most | |
| 125 | − # likely a direct (non-proxied) connection — common during health | |
| 126 | − # checks. Fail closed so we don't surface a misleading peer IP. | |
| 127 | − require Logger | |
| 128 | − Logger.warning("PROXY protocol enabled but first bytes weren't a header; dropping") | |
| 126 | + # Direct TCP connect with no PROXY header — likely a port scan | |
| 127 | + # or a k8s probe that bypassed the proxy. Drop quietly. | |
| 128 | + {:close, state} | |
| 129 | + | |
| 130 | + {:error, :closed} -> | |
| 131 | + # Peer closed before sending anything; expected churn from | |
| 132 | + # health checks and load-balancer probes. | |
| 133 | + {:close, state} | |
| 134 | + | |
| 135 | + {:error, :timeout} -> | |
| 136 | + # Peer connected but sent nothing within the deadline. Same as :closed — | |
| 137 | + # uninteresting, just drop. | |
| 129 | 138 | {:close, state} |
| 130 | 139 | |
| 131 | 140 | {:error, reason} -> |
| 132 | − require Logger | |
| 141 | + # Truncated / malformed header — worth surfacing because it | |
| 142 | + # usually means our proxy and listener disagree on the version. | |
| 133 | 143 | Logger.warning("PROXY header parse failed: #{inspect(reason)}; dropping") |
| 134 | 144 | {:close, state} |
| 135 | 145 | end |
modified
lib/oh_my_ex_oh_ircd/irc/tls_listener.ex
+6
−1
@@ -71,7 +71,12 @@ defmodule OhMyExOhIrcd.IRC.TLSListener do
| 71 | 71 | ping_timeout_ms: Keyword.get(listener_cfg, :ping_timeout_ms, 60_000), |
| 72 | 72 | flood_threshold_seconds: Keyword.get(listener_cfg, :flood_threshold_seconds, 10), |
| 73 | 73 | flood_penalty_default: Keyword.get(listener_cfg, :flood_penalty_default, 1.0), |
| 74 | − proxy_protocol: Keyword.get(listener_cfg, :proxy_protocol, false) | |
| 74 | + # PROXY protocol is plain-port-only for now. On the TLS port | |
| 75 | + # Traefik passthrough would put the v2 header before the | |
| 76 | + # ClientHello, which `:ssl` can't skip. Read this listener's | |
| 77 | + # own `:proxy_protocol` (default false) instead of inheriting | |
| 78 | + # from the plain listener config. | |
| 79 | + proxy_protocol: Keyword.get(cfg, :proxy_protocol, false) | |
| 75 | 80 | } |
| 76 | 81 | ) |
| 77 | 82 | end |
Parents: e3999f1