Docker Gateway IP displayed for all clients FIX / enabling IPv6 for TeamSpeak on Docker

Since I had some fun with IPv6, Docker and my TeamSpeak server, I want to share my experience to you so that don’t have to experience the same issues.

Prequesites:

In this post I am refering on TeamSpeak on Docker on a Linux VPS.

For me, and other people in the TeamSpeak community, it is normal that your displayed client IP is not your external IPv4 address but the Docker bridge network gateway IP address if you (auto-)reconnect after a server restart.
If you reconnect again, the problem should be fixed.
If not, this is what this post is about.

The problem:

For all clients the gateway IP of the Docker bridge network is displayed as their client IP instead of their external IP address (usually from IP range 172.16.0.0/12, e.g. 172.29.0.1)

The problem occured when I added a AAAA entry to my domain.
It is important to know that TeamSpeak preferes IPv6 over IPv4 (due to my client logs).

Infrastructure:

I have a domain, let’s say example.com.
People usually connect via my domain.
The problem I described above occures when they connect via my domain or IPv6, but not when they connect via IPv4 directly.

In my case I have a SRV entry next to my A and AAAA entry for my domain, it looks like this:


(I am not sure if this is important at all, but I rather post it than missing important information.)

The fix:

For me, I fixed the problem by enabling IPv6 on Docker:

Step 1: Add this to your /etc/docker/daemon.json

{
    "ipv6": false,
    "fixed-cidr-v6": "2001:db8:1::/64"
}

The IPv6 range is officially used for documentation, but even Docker says that you can use it, just copy it.

Restart / reload Docker after this (systemctl restart docker).

Step 2: Add IPv6 to your docker network

My docker-compose.yaml looks like this:

version: '3.8'

services:

  # Database

  teamspeak_db:
    container_name: teamspeak_db
    image: mariadb:10.9.3
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: "${DBPW}"
      MYSQL_DATABASE: teamspeakserver
    volumes:
      - "./data_db:/var/lib/mysql"
    networks:
      - teamspeak

  # Server

  teamspeak_server:
    container_name: teamspeak_server
    restart: always
    image: teamspeak:3.13.7
    ports:
      - target: 9987
        published: 9987
        protocol: udp
        mode: host
      - target: 30033
        published: 30033
        protocol: tcp
        mode: host
    environment:
      TS3SERVER_DB_PLUGIN: ts3db_mariadb
      TS3SERVER_DB_SQLCREATEPATH: create_mariadb
      TS3SERVER_DB_HOST: teamspeak_db
      TS3SERVER_DB_USER: root
      TS3SERVER_DB_PASSWORD: "${DBPW}"
      TS3SERVER_DB_NAME: teamspeakserver
      TS3SERVER_DB_WAITUNTILREADY: 1
      TS3SERVER_LICENSE: accept
      TS3SERVER_DB_CLIENTKEEPDAYS: 90
    volumes:
      - "./data_ts:/var/ts3server"
    depends_on:
      - teamspeak_db
    networks:
      - teamspeak

networks:
  teamspeak:
    external: false
    enable_ipv6: true
    ipam:
      driver: default
      config:
        - subnet: fd4d:6169:6c63:abcd::/64
          gateway: fd4d:6169:6c63:abcd::1

For the subnet / gateway IP, I use a unique local address (fd00::/8), so you can copy it or modify it.

After a docker compose down & docker compose up, IPv6 should work.

Now you should see the country flags of the users again ^^

3 Likes