128

I have docker host and inside I have one container.

The docker host is binding the port on IPv6 interface only, not on IPv4.

This is the output

tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:55082           0.0.0.0:*               LISTEN      -
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      -
tcp6       0      0 :::80                   :::*                    LISTEN      -
tcp6       0      0 :::22                   :::*                    LISTEN      -
tcp6       0      0 :::40280                :::*                    LISTEN      -
tcp6       0      0 :::5432                 :::*                    LISTEN      -
tcp6       0      0 :::40122                :::*                    LISTEN      -
tcp6       0      0 :::36378                :::*                    LISTEN      -
tcp6       0      0 :::40543                :::*                    LISTEN      -
tcp6       0      0 :::111                  :::*                    LISTEN      -

Now I have 40122 port on host to link with port 22 on container.

I want to SSH into that container but I am not able to as its only bound to IPv6

This is my docker version Docker version 1.5.0, build a8a31ef

docker ps

201bde6c839a        myapp:latest   "supervisord -n"    3 weeks ago         Up 2 hours          0.0.0.0:40122->22/tcp, 0.0.0.0:40280->80/tcp, 0.0.0.0:40543->443/tcp   myapp

I ran using docker run -d -P -p 40122:22

netstat -tlna

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN
tcp        0      0 127.0.0.1:3031          0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN
tcp6       0      0 :::22                   :::*                    LISTEN
tcp6       0      0 :::6379                 :::*                    LISTEN

ps aux

root         1  0.0  0.8  52440 16668 ?        Ss   00:53   0:03 /usr/bin/python /usr/bin/supervisord -n
root        49  0.0  0.1  17980  3048 ?        S    01:32   0:00 bash
root        64  0.0  0.1  46632  2712 ?        S    01:32   0:00 su -l vagrant
vagrant     65  0.0  0.1  21308  3760 ?        S    01:32   0:00 -su
root       288  0.0  0.1  17980  3088 ?        S    02:01   0:00 bash
root       304  0.0  0.1  46632  2720 ?        S    02:01   0:00 su -l vagrant
vagrant    305  0.0  0.1  21304  3804 ?        S    02:01   0:00 -su
vagrant    308  0.0  3.7 429616 75840 ?        Sl+  02:01   0:05 python ./manage.py shell_plus
root       654  0.0  0.4  47596  9848 ?        S    03:12   0:01 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       655  0.0  0.3  90280  7732 ?        S    03:12   0:00 nginx: master process /usr/sbin/nginx
www-data   656  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   657  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   658  0.0  0.1  90600  3624 ?        S    03:12   0:00 nginx: worker process
www-data   659  0.0  0.2  90940  4500 ?        S    03:12   0:00 nginx: worker process
root       660  0.0  0.2  61372  5332 ?        S    03:12   0:00 /usr/sbin/sshd -D
root       669  0.0  0.4  37004  8892 ?        Sl   03:12   0:01 redis-server *:6379
root       856  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       857  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       858  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
root       859  8.0  2.8 388720 57792 ?        Sl   04:07   0:18 /usr/local/bin/uwsgi --die-on-term --ini /var/www/conf/uwsgi.ini
vagrant    889  0.0  0.1  18692  2508 ?        R+   04:11   0:00 ps aux
user3214546
  • 6,523
  • 13
  • 51
  • 98
  • What command did you use to start the container? Also post the output of `docker ps` when the container is running. – Daniel t. Apr 30 '15 at 02:56
  • 1
    Can you confirm sshd is actually running on the container? Run `docker exec -ti 201bde6c839a /bin/bash`, once you are in, post the output of `ps aux ` and `netstat -taln` – Daniel t. Apr 30 '15 at 03:15
  • In my Docker host, all docker ports are listening on IPv6 and have no problem connecting to ssh on containers. – Daniel t. Apr 30 '15 at 03:17
  • @Danielt. i have added the info. I am able ssh using exec but i am not able to ssh into container directly from outside using host port 40122 from mac – user3214546 Apr 30 '15 at 04:13
  • You could hitting this issue https://github.com/docker/docker/issues/2174 , i am not sure if it is resolved. Can you also share how you are trying to connect through ssh and the error you are getting? – Daniel t. Apr 30 '15 at 13:41

8 Answers8

96

As @daniel-t points out in the comment: github.com/docker/docker/issues/2174 is about showing binding only to IPv6 in netstat, but that is not an issue. As that github issues states:

When setting up the proxy, Docker requests the loopback address '127.0.0.1', Linux realises this is an address that exists in IPv6 (as ::0) and opens on both (but it is formally an IPv6 socket). When you run netstat it sees this and tells you it is an IPv6 - but it is still listening on IPv4. If you have played with your settings a little, you may have disabled this trick Linux does - by setting net.ipv6.bindv6only = 1.

In other words, just because you see it as IPv6 only, it is still able to communicate on IPv4 unless you have IPv6 set to only bind on IPv6 with the net.ipv6.bindv6only setting. To be clear, net.ipv6.bindv6only should be 0 - you can run sysctl net.ipv6.bindv6only to verify.

Michael
  • 10,124
  • 1
  • 34
  • 49
21

2021 Update:

Currently docker binds to both IPv4 and IPv6 by default.

If you want to explicitly "Make docker use IPv4 for port binding" (as in, have it only bind on the IPv4 port) add 0.0.0.0: before the ports in the -p/--publish option(s), like so:

$ docker run --publish "0.0.0.0:80:80" --publish "0.0.0.0:443:443" --detach nginx

The result will look like this when you're done:

$ docker ps

CONTAINER ID   IMAGE   COMMAND                  CREATED          STATUS         PORTS                                      NAMES
2459bd225751   nginx   "/docker-entrypoint.…"   4 seconds ago    Up 2 seconds   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp   jovial_yonath

The netstat results will look like this:

$ sudo netstat -tulnp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State    PID/Program name
tcp        0      0 0.0.0.0:443   0.0.0.0:*       LISTEN   22676/docker-proxy
tcp        0      0 0.0.0.0:80    0.0.0.0:*       LISTEN   22698/docker-proxy

You can browse or curl to the device to make sure it works, of course.

If you don't add the "0.0.0.0", it will bind on both IP versions, and the PORTS will read 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, which may not be desirable for security, console spam or predictability reasons.

Darren S
  • 516
  • 4
  • 8
11

Setting net.ipv6.conf.all.forwarding=1 will fix the issue.

This can be done on a live system using sudo sysctl -w net.ipv6.conf.all.forwarding=1

Archimedes Trajano
  • 35,625
  • 19
  • 175
  • 265
LuciferJack
  • 781
  • 11
  • 12
  • This answer has one advantage: it allows you to "fix" the issue without having to restart the docker daemon (the answer with changing docker config below does). Regarding the top, selected answer: I actually had `sysctl net.ipv6.bindv6only=0` so changing this config did not help. – pkoperek May 29 '20 at 13:53
  • Great answer also add it to /etc/sysctl.d/97-ipv6-fwd.conf so it will persist after reboot – ir0h Jun 20 '21 at 15:32
  • 1
    On macOS I think it's `sudo sysctl net.inet6.ip6.forwarding=1` – Alex Nov 19 '21 at 09:14
4

ISSUE RESOVLED:

USE docker run -it -p 80:80 --name nginx --net=host -d nginx

that's issue we face with VM some time instead of bridge network try with host that will work for you

tcp     0    0 0.0.0.0:80            0.0.0.0:*             LISTEN      - 
tcp6    0    0 :::80                 :::*                  LISTEN      -  
agentsmith
  • 1,226
  • 1
  • 14
  • 27
1

By default, docker uses AF_INET6 sockets which can be used for both IPv4 and IPv6 connections. This causes netstat to report an IPv6 address for the listening address.

From RedHat https://access.redhat.com/solutions/3114021

0

If you want your container ports to bind on your ipv4 address, just :

  • find the settings file
    • /etc/sysconfig/docker-network on RedHat alike
    • /etc/default/docker-network on Debian ans alike
  • edit the network settings
    • add DOCKER_NETWORK_OPTIONS=-ip=xx.xx.xx.xx
    • xx.xx.xx.xx being your real ipv4 (and not 0.0.0.0)
  • restart docker deamon

works for me on docker 1.9.1

Sylvain
  • 876
  • 8
  • 11
  • 1
    does this work on debian ? shouldn't it be /etc/default/docker ? – Dimitri Kopriwa May 13 '16 at 10:05
  • 1
    @BigDong thanks for the comment, I'm on RedHat like OS so the path is a little different from one OS to the other I tried to reflect your comment in the answer – Sylvain May 14 '16 at 21:42
0

For CentOS users,

I've got same issue on CentOS7 and setting net.ipv4.ip_forward to 1 solves the issue. Please, refer to Docker Networking Disabled: WARNING: IPv4 forwarding is disabled. Networking will not work for more details.

0

Try to remove --attachable flag for created networks

Doesn't work

docker network create --attachable --driver overlay --subnet=10.0.3.0/24 --gateway=10.0.3.1 dev

It works, but listeness IPv4 ports still not seeing when you check with sudo netstat -tulnp4

docker network create --attachable --driver overlay --subnet=10.0.3.0/24 --gateway=10.0.3.1 dev
Dennis V
  • 574
  • 7
  • 19