defmodule OhMyExOhIrcd.IRC.Cloak do
@moduledoc """
Hashed-IP host cloaking.
When cloaking is enabled (the listener has a non-nil `:cloak_host`), a
connecting client's real IP is replaced in their `nick!user@host`
prefix with `<hash>.<cloak_host>`, e.g. `a1b2c3d4e5f6.irc.skyjeep.club`.
Properties:
* **Stable** — the same IP always yields the same cloak, so per-host
bans (`*@a1b2c3d4e5f6.irc.skyjeep.club`) work.
* **Opaque** — the IP can't be recovered from the cloak; the hash is
salted with a per-deployment secret so cloaks aren't comparable
across networks or brute-forceable from the IP space alone.
Operators still see the real IP via WHOIS numeric 338 (RPL_WHOISACTUALLY),
and the real IP is what K-line / O-line matching uses — cloaking is a
display concern only.
"""
# Length of the lowercase-hex hash label. 12 hex chars = 48 bits of the
# SHA-256 digest: short enough to read, wide enough that collisions are
# not a practical concern at our scale.
@hash_len 12
@doc """
Compute the display host for `real_ip`. With a nil/blank `base`,
cloaking is off and the real IP is returned unchanged.
"""
@spec host(String.t(), String.t() | nil) :: String.t()
def host(real_ip, base) when is_binary(base) and base != "" and is_binary(real_ip) do
"#{hash(real_ip)}.#{base}"
end
def host(real_ip, _base), do: real_ip
defp hash(ip) do
:crypto.hash(:sha256, salt() <> ip)
|> Base.encode16(case: :lower)
|> binary_part(0, @hash_len)
end
# Per-deployment salt. Prefer an explicit `:cloak_salt`; otherwise reuse
# the endpoint's secret_key_base (already required in prod) so cloaks are
# unguessable without copying yet another secret around. Falls back to a
# constant only in dev/test where there is no secret.
defp salt do
Application.get_env(:oh_my_ex_oh_ircd, __MODULE__, [])[:salt] ||
Application.get_env(:oh_my_ex_oh_ircd, OhMyExOhIrcdWeb.Endpoint, [])[:secret_key_base] ||
"oh-my-ex-oh-cloak-dev-salt"
end
end
neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
2.0 KiB · text
History
4b6fe3b