elektrine/config/runtime/dns.exs

377 lines
10 KiB
Elixir

import Config
parse_bool_env = fn env_name, default ->
case System.get_env(env_name) do
nil ->
default
"" ->
default
value when value in ["1", "true", "TRUE", "yes", "YES", "on", "ON"] ->
true
value when value in ["0", "false", "FALSE", "no", "NO", "off", "OFF"] ->
false
_ ->
default
end
end
parse_int_env = fn env_name, default ->
case System.get_env(env_name) do
nil ->
default
"" ->
default
value ->
case Integer.parse(value) do
{int, ""} when int > 0 -> int
_ -> default
end
end
end
parse_dns_endpoint = fn value ->
trimmed = String.trim(value)
case Regex.run(~r/^\[(.+)\](?::(\d+))?$/, trimmed) do
[_, host, port] ->
with {:ok, ip} <- :inet.parse_address(String.to_charlist(host)),
{parsed_port, ""} <- Integer.parse(port) do
{:ok, {ip, parsed_port}}
else
_ -> :error
end
[_, host] ->
with {:ok, ip} <- :inet.parse_address(String.to_charlist(host)) do
{:ok, {ip, 53}}
else
_ -> :error
end
nil ->
case String.split(trimmed, ":", parts: 2) do
[host, port] ->
with {:ok, ip} <- :inet.parse_address(String.to_charlist(host)),
{parsed_port, ""} <- Integer.parse(port) do
{:ok, {ip, parsed_port}}
else
_ -> :error
end
[host] ->
with {:ok, ip} <- :inet.parse_address(String.to_charlist(host)) do
{:ok, {ip, 53}}
else
_ -> :error
end
_ ->
:error
end
end
end
parse_dns_endpoints = fn value ->
value
|> String.split(",", trim: true)
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))
|> Enum.map(parse_dns_endpoint)
|> Enum.flat_map(fn
{:ok, endpoint} -> [endpoint]
:error -> []
end)
|> Enum.uniq()
end
dns_config = Application.get_env(:elektrine, :dns, [])
dns_nameservers =
case System.get_env("DNS_NAMESERVERS") do
nil -> Keyword.get(dns_config, :nameservers, [])
"" -> []
value -> value |> String.split(",", trim: true) |> Enum.map(&String.trim/1)
end
dns_soa_rname =
case System.get_env("DNS_SOA_RNAME") do
nil -> Keyword.get(dns_config, :soa_rname)
"" -> nil
value -> String.trim(value)
end
dns_recursive_allow_cidrs =
case System.get_env("DNS_RECURSIVE_ALLOW_CIDRS") do
nil -> Keyword.get(dns_config, :recursive_allow_cidrs, [])
"" -> []
value -> value |> String.split(",", trim: true) |> Enum.map(&String.trim/1)
end
dns_recursive_upstreams =
case System.get_env("DNS_RECURSIVE_UPSTREAMS") do
nil -> Keyword.get(dns_config, :recursive_upstreams, [])
"" -> []
value -> parse_dns_endpoints.(value)
end
dns_edge_proxy_ipv4_addresses =
case System.get_env("DNS_EDGE_PROXY_IPV4_ADDRESSES") do
nil ->
Keyword.get(dns_config, :edge_proxy_ipv4_addresses, [])
"" ->
[]
value ->
value |> String.split(",", trim: true) |> Enum.map(&String.trim/1)
end
dns_edge_proxy_ipv6_addresses =
case System.get_env("DNS_EDGE_PROXY_IPV6_ADDRESSES") do
nil ->
Keyword.get(dns_config, :edge_proxy_ipv6_addresses, [])
"" ->
[]
value ->
value |> String.split(",", trim: true) |> Enum.map(&String.trim/1)
end
dns_edge_proxy_hostname =
case System.get_env("DNS_EDGE_PROXY_HOSTNAME") do
nil ->
Keyword.get(dns_config, :edge_proxy_hostname)
"" ->
nil
value ->
value |> String.trim() |> String.trim_trailing(".") |> String.downcase()
end
dns_public_bind_ip =
case System.get_env("PUBLIC_DNS_BIND_IP") || System.get_env("DNS_PUBLIC_BIND_IP") do
nil -> Keyword.get(dns_config, :public_bind_ip)
"" -> nil
value -> String.trim(value)
dns_tunnel_connector_urls =
case System.get_env("DNS_TUNNEL_CONNECTOR_URLS") do
nil ->
Keyword.get(dns_config, :tunnel_connector_urls, [])
"" ->
[]
value ->
value
|> String.split(",", trim: true)
|> Enum.map(&String.trim/1)
|> Enum.reject(&(&1 == ""))
end
config :elektrine, :dns,
authority_enabled:
parse_bool_env.(
"DNS_AUTHORITY_ENABLED",
Keyword.get(dns_config, :authority_enabled, false)
),
recursive_enabled:
parse_bool_env.(
"DNS_RECURSIVE_ENABLED",
Keyword.get(dns_config, :recursive_enabled, false)
),
dnssec_enabled:
parse_bool_env.(
"DNS_DNSSEC_ENABLED",
Keyword.get(dns_config, :dnssec_enabled, false)
secondary_axfr_enabled:
parse_bool_env.(
"DNS_SECONDARY_AXFR_ENABLED",
Keyword.get(dns_config, :secondary_axfr_enabled, false)
),
secondary_ingest_enabled:
parse_bool_env.(
"DNS_SECONDARY_INGEST_ENABLED",
Keyword.get(dns_config, :secondary_ingest_enabled, false)
),
secondary_ingest_poll_interval_ms:
parse_int_env.(
"DNS_SECONDARY_INGEST_POLL_INTERVAL_MS",
Keyword.get(dns_config, :secondary_ingest_poll_interval_ms, 60_000)
),
dnssec_zsk_hold_down_seconds:
parse_int_env.(
"DNS_DNSSEC_ZSK_HOLD_DOWN_SECONDS",
Keyword.get(dns_config, :dnssec_zsk_hold_down_seconds, 86_400)
),
edge_proxy_enabled:
parse_bool_env.(
"DNS_EDGE_PROXY_ENABLED",
Keyword.get(dns_config, :edge_proxy_enabled, true)
),
edge_rules_enabled:
parse_bool_env.(
"DNS_EDGE_RULES_ENABLED",
Keyword.get(dns_config, :edge_rules_enabled, false)
),
edge_rules_max_per_zone:
parse_int_env.(
"DNS_EDGE_RULES_MAX_PER_ZONE",
Keyword.get(dns_config, :edge_rules_max_per_zone, 50)
),
edge_access_client_id:
System.get_env("DNS_EDGE_ACCESS_CLIENT_ID") ||
Keyword.get(dns_config, :edge_access_client_id, "elektrine-edge-access"),
edge_access_client_secret:
System.get_env("DNS_EDGE_ACCESS_CLIENT_SECRET") ||
Keyword.get(dns_config, :edge_access_client_secret),
edge_access_issuer_url:
System.get_env("DNS_EDGE_ACCESS_ISSUER_URL") ||
Keyword.get(dns_config, :edge_access_issuer_url),
edge_access_cookie_max_age_seconds:
parse_int_env.(
"DNS_EDGE_ACCESS_COOKIE_MAX_AGE_SECONDS",
Keyword.get(dns_config, :edge_access_cookie_max_age_seconds, 8 * 60 * 60)
),
edge_access_exchange_ttl_seconds:
parse_int_env.(
"DNS_EDGE_ACCESS_EXCHANGE_TTL_SECONDS",
Keyword.get(dns_config, :edge_access_exchange_ttl_seconds, 60)
),
edge_access_state_max_age_seconds:
parse_int_env.(
"DNS_EDGE_ACCESS_STATE_MAX_AGE_SECONDS",
Keyword.get(dns_config, :edge_access_state_max_age_seconds, 600)
cache_enabled:
parse_bool_env.(
"DNS_CACHE_ENABLED",
Keyword.get(dns_config, :cache_enabled, false)
),
edge_cache_max_entries:
parse_int_env.(
"DNS_EDGE_CACHE_MAX_ENTRIES",
Keyword.get(dns_config, :edge_cache_max_entries, 10_000)
),
edge_cache_max_bytes:
parse_int_env.(
"DNS_EDGE_CACHE_MAX_BYTES",
Keyword.get(dns_config, :edge_cache_max_bytes, 256 * 1024 * 1024)
),
edge_cache_ttl_cap_seconds:
parse_int_env.(
"DNS_EDGE_CACHE_TTL_CAP_SECONDS",
Keyword.get(dns_config, :edge_cache_ttl_cap_seconds, 3_600)
),
zone_cache_refresh_interval_ms:
parse_int_env.(
"DNS_ZONE_CACHE_REFRESH_INTERVAL_MS",
Keyword.get(dns_config, :zone_cache_refresh_interval_ms, 300_000)
),
nameservers: dns_nameservers,
soa_rname: dns_soa_rname,
public_bind_ip: dns_public_bind_ip,
recursive_upstreams: dns_recursive_upstreams,
recursive_allow_cidrs: dns_recursive_allow_cidrs,
edge_proxy_ipv4_addresses: dns_edge_proxy_ipv4_addresses,
edge_proxy_ipv6_addresses: dns_edge_proxy_ipv6_addresses,
edge_proxy_hostname: dns_edge_proxy_hostname,
# DNS query analytics retention only (dns_query_stats). Does not control
# platform :analytics_retention (profile/site).
query_stats_retention_days:
parse_int_env.(
"DNS_QUERY_STATS_RETENTION_DAYS",
Keyword.get(dns_config, :query_stats_retention_days, 90)
),
query_stats_retention_batch_size:
parse_int_env.(
"DNS_QUERY_STATS_RETENTION_BATCH_SIZE",
Keyword.get(dns_config, :query_stats_retention_batch_size, 5_000)
),
query_stats_retention_max_batches:
parse_int_env.(
"DNS_QUERY_STATS_RETENTION_MAX_BATCHES",
Keyword.get(dns_config, :query_stats_retention_max_batches, 100)
),
tunnel_enabled:
parse_bool_env.(
"DNS_TUNNEL_ENABLED",
Keyword.get(dns_config, :tunnel_enabled, false)
),
tunnel_max_streams:
parse_int_env.(
"DNS_TUNNEL_MAX_STREAMS",
Keyword.get(dns_config, :tunnel_max_streams, 16)
),
tunnel_max_per_zone:
parse_int_env.(
"DNS_TUNNEL_MAX_PER_ZONE",
Keyword.get(dns_config, :tunnel_max_per_zone, 10)
),
tunnel_connector_urls: dns_tunnel_connector_urls,
edge_site_heartbeat_interval_ms:
parse_int_env.(
"DNS_EDGE_SITE_HEARTBEAT_INTERVAL_MS",
Keyword.get(dns_config, :edge_site_heartbeat_interval_ms, 15_000)
),
edge_site_stale_after_ms:
parse_int_env.(
"DNS_EDGE_SITE_STALE_AFTER_MS",
Keyword.get(dns_config, :edge_site_stale_after_ms, 45_000)
),
edge_config_bundle_ttl_seconds:
parse_int_env.(
"DNS_EDGE_CONFIG_BUNDLE_TTL_SECONDS",
Keyword.get(dns_config, :edge_config_bundle_ttl_seconds, 300)
),
max_udp_payload:
parse_int_env.(
"DNS_MAX_UDP_PAYLOAD",
Keyword.get(dns_config, :max_udp_payload, 1232)
),
rate_limit_window_ms:
parse_int_env.(
"DNS_RATE_LIMIT_WINDOW_MS",
Keyword.get(dns_config, :rate_limit_window_ms, 1000)
),
udp_rate_limit_per_window:
parse_int_env.(
"DNS_UDP_RATE_LIMIT_PER_WINDOW",
Keyword.get(dns_config, :udp_rate_limit_per_window, 200)
),
tcp_rate_limit_per_window:
parse_int_env.(
"DNS_TCP_RATE_LIMIT_PER_WINDOW",
Keyword.get(dns_config, :tcp_rate_limit_per_window, 50)
),
udp_max_inflight:
parse_int_env.(
"DNS_UDP_MAX_INFLIGHT",
Keyword.get(dns_config, :udp_max_inflight, 1024)
),
tcp_max_inflight:
parse_int_env.(
"DNS_TCP_MAX_INFLIGHT",
Keyword.get(dns_config, :tcp_max_inflight, 256)
),
udp_port:
parse_int_env.(
"DNS_UDP_PORT",
Keyword.get(dns_config, :udp_port, 5300)
),
tcp_port:
parse_int_env.(
"DNS_TCP_PORT",
Keyword.get(dns_config, :tcp_port, 5300)
),
recursive_timeout:
parse_int_env.(
"DNS_RECURSIVE_TIMEOUT_MS",
Keyword.get(dns_config, :recursive_timeout, 3000)
)