Skip to content

[Nginx] only bind IPv6 default_server when ENABLE_IPV6 is set#7343

Open
smpaz7467 wants to merge 1 commit into
mailcow:stagingfrom
smpaz7467:fix/nginx-ipv6-default-server
Open

[Nginx] only bind IPv6 default_server when ENABLE_IPV6 is set#7343
smpaz7467 wants to merge 1 commit into
mailcow:stagingfrom
smpaz7467:fix/nginx-ipv6-default-server

Conversation

@smpaz7467

Copy link
Copy Markdown

What

The HTTP→HTTPS redirect server block in nginx.conf.j2 binds
listen [::]:{{ HTTP_PORT }} default_server unconditionally, while all six
other IPv6 listen directives in the same template are guarded by
{% if ENABLE_IPV6 %}. On hosts with IPv6 disabled at the kernel level,
nginx cannot bind :: and fails to start.

It only triggers when HTTP_REDIRECT=y and ENABLE_IPV6=false — which is
likely why it went unnoticed: testing ENABLE_IPV6=false with the redirect
off shows nothing wrong.

Verification

Rendered the template with Jinja2 across all four combinations and validated
each output with nginx -t (nginx:alpine, includes and cert stubbed):

ENABLE_IPV6 HTTP_REDIRECT listen [::] before after nginx -t
true true 3 3 ok
true false 3 3 ok
false true 1 (leaked) 0 ok
false false 0 0 ok

Behaviour with ENABLE_IPV6=true is unchanged.

Scope

Refs #7296

Deliberately limited to the nginx template — the bug in the issue title. The
reporter's follow-up notes that dovecot, php-fpm, postfix and unbound also
hardcode IPv6. Those are not addressed here: nginx is currently the only
service that consumes ENABLE_IPV6 at all, so making the others respect it
means introducing config templating where none exists today — a design
decision that seems better left to maintainers. (The workarounds in that
comment also hardcode IPv4, e.g. inet_protocols = ipv4, which would break
IPv6 for everyone else.)

Using Refs rather than Fixes so the issue stays open for that remaining work.

The HTTP-to-HTTPS redirect server block bound `listen [::]:{{ HTTP_PORT }}
default_server` unconditionally, while every other IPv6 listen directive in
this template is guarded by `{% if ENABLE_IPV6 %}`. On hosts where IPv6 is
disabled at the kernel level, nginx cannot bind `::` and fails to start.

This only triggers when HTTP_REDIRECT is enabled and ENABLE_IPV6 is false,
which is why it survives testing with ENABLE_IPV6=false alone.

Guard the directive like the other six IPv6 listeners in the template.

Refs mailcow#7296

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant