Score:2

How do I configure a virtual server in nginx to listen only on IPv6

br flag

For my website I need effectively 3 domains:

  • example.domain: accessible via both IPv4 & IPv6
  • ipv4.example.domain: accessible via IPv4 only
  • ipv6.example.domain: accessible via IPv6 only

I tried to solve this using the following nginx config:

server {
    listen [::]:80 ipv6only=off default_server;
    listen 80 default_server;
    server_name example.domain;
}

# IPv4 only endpoint
server {
    listen 80;
    server_name ipv4.example.domain;
}

# IPv6 only endpoint
server {
    listen [::]:80 ipv6only=on;
    server_name ipv6.example.domain;
}

But this throws the error: nginx: [emerg] duplicate listen options for [::]:80 for the IPv6 server block (line 15 in my example).

How can I achieve the desired result? Would I be required to use 2 separate IPv6 addresses to host these websites on?

djdomi avatar
za flag
to be easy said, you all just say listen to port 80 regarless so to bind port 80 on ip4 you will exlusive needed to use 0.0.0.0:80
xorinzor avatar
br flag
@djdomi ipv4 isn't the issue, it's IPv6 which throws an error.
Score:2
jp flag

From the listen documentation about the ipv6only option:

This parameter is turned on by default. It can only be set once on start.

You cannot use both ipv6only=off and ipv6only=on.

In fact, your first server block should be ipv6only=on anyway, because you have separate listen directives in the same server block, one for ipv4 only, and one for ipv6 only (which is what that option is for).

xorinzor avatar
br flag
Ah, thanks. I understand where my thinking went wrong, this makes total sense. Only odd thing left is that any requests to `ipv6.example.domain` still return a IPv4 address if I check the `REMOTE_ADDR` header. Guessing that might be something docker related.
Score:1
co flag

You are misunderstanding the ipv6Only listen flag, if it is set to off, you get a dual-stack socket, while if it is set to on it makes an IPv6 socket

You need the following config:

server {
    # listen on IPv6 only
    listen [::]:80 ipv6only=on default_server;
    # listen on IPv4 only
    listen 80 default_server;
    server_name example.domain;
}

# IPv4 only endpoint
server {
    # listen on IPv4 only
    listen 80;
    server_name ipv4.example.domain;
}

# IPv6 only endpoint
server {
    # listen on IPv6 only
    listen [::]:80;
    server_name ipv6.example.domain;
}

If a request comes in on the [::]:80 server socket, NGINX knows it has to match to the servers ipv6.example.domain or example.domain, falling back to example.domain if there is no match.

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.