Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Light OAuth IPv6 Support

Problem

The Rust light-oauth service binds its HTTPS listener to 0.0.0.0. That is correct for IPv4, but it does not accept connections sent to an IPv6 address.

In a dual-stack container network, Docker DNS can return the IPv6 address for light-oauth before the IPv4 address. A client that does not retry the next address can fail even though the service is healthy on IPv4. One observed failure is the gateway proxying /oauth2/{providerId}/code to https://light-oauth:6881 and receiving ECONNREFUSED on the IPv6 address.

Goals

  • Allow light-oauth to bind IPv4, IPv6, or a specific interface from config.
  • Keep the current default behavior as IPv4 wildcard binding.
  • Avoid breaking existing deployments whose server.yml does not contain the new property.
  • Build the listener address with SocketAddr so IPv6 addresses are parsed correctly.

Non-Goals

  • Do not enable IPv6 for every deployment by default.
  • Do not change TLS, OIDC, token, or database behavior.
  • Do not change gateway upstream retry behavior in this change.

Configuration

light-oauth adds a server bind IP property:

ip: ${server_ip:0.0.0.0}

The default value remains:

server_ip: "0.0.0.0"

To listen on IPv6 wildcard:

server_ip: "::"

To listen on a specific IPv4 or IPv6 address:

server_ip: "172.16.1.3"
server_ip: "fdd0:0:0:1::3"

Implementation

The Rust config model includes an ip field with a default of 0.0.0.0. The default keeps old external server.yml files working.

The listener address is built as:

#![allow(unused)]
fn main() {
let ip = config.ip.parse::<IpAddr>()?;
let addr = SocketAddr::new(ip, config.port);
}

This avoids string formatting problems with IPv6 addresses. For example, :: plus port 6881 must become [::]:6881, not :::6881.

Deployment Guidance

Use IPv6 binding only when the runtime network is intentionally dual-stack and other services can reach the IPv6 address. In a container environment, confirm that:

  • the container network has IPv6 enabled;
  • the service has an IPv6 address;
  • clients resolve or connect to the same address family;
  • health checks cover the chosen address family.

For local or single-stack deployments, keep the default IPv4 binding.

Verification

For IPv4 default:

curl -k https://light-oauth:6881/oauth2/<providerId>/keys

For IPv6 wildcard binding in a dual-stack network, verify from another container:

curl -k -g https://[<light-oauth-ipv6>]:6881/oauth2/<providerId>/keys

If the client uses service DNS, verify that the first returned address family is reachable:

getent ahosts light-oauth
curl -k -v https://light-oauth:6881/oauth2/<providerId>/keys