IPv6 binding error: Cannot assign requested address - docker

As I understand, IPv6 addresses are allocated in blocks. Each machine gets a range of IPv6 address and any IPv6 address in that range would point to it.
Basis for this assumption:
https://stackoverflow.com/a/15266701/681671
The /64 is the prefix length. It is the number of bits in the address
that is fixed. So a /64 indicates that the first 64 bits of the
128-bit IPv6 address are fixed. The remaining bits (64 in this case)
are flexible, and you can use all of them. This means that when your
ISP gives you a /64 they are giving you 264 addresses (that is
18,446,744,073,709,551,616 addresses).
Edit: I confirmed using Wireshark that the packets sent to any IP in that /64 range do get routed to my server.
Looking at this line from ifconfig output
inet6 2a01:2e8:d2c:e24c::1 prefixlen 64 scopeid 0x0<global>
I conclude that all IPv6 addresses with 2a01:2e8:d2c:e24c prefix will point to my machine.
However I am unable to bind any service to any IPv6 address other than
2a01:2e8:d2c:e24c:0000:0000:0000:0001
nc -l 2a01:2e8:d2c:e24c:0000:0000:0000:0002 80 Does not work
nc -l 2a01:2e8:d2c:e24c:0000:0000:0001:0001 80 Does not work
nc -l 2a01:2e8:d2c:e24c:1000:0000:0000:0001 80 Does not work
nc -l 2a01:2e8:d2c:e24c:0000:0000:0000:0001 80 Only this works
nc -l <IP> <PORT> opens up a simple TCP server on the specified IP and port.
The error I get is nc: Cannot assign requested address
I want to run multiple instances of a service on same port but different IPv6 addresses. Since public IPv6 address are abundantly available to each machine, I thought of utilizing the same.
ifconfig:
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 88.77.66.55 netmask 255.255.255.255 broadcast 88.77.66.55
inet6 fe80::9300:ff:fe33:64c1 prefixlen 64 scopeid 0x20<link>
inet6 2a01:2e8:d2c:e24c::1 prefixlen 64 scopeid 0x0<global>
ether 96:00:00:4e:31:e4 txqueuelen 1000 (Ethernet)
RX packets 26788391 bytes 21199864639 (21.1 GB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 21940989 bytes 20045216536 (20.0 GB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
OS: Ubuntu 18.04
VPS Host: Hetzner
I am actually trying to run multiple nginx docker containers mapped to port 80 on different IPv6 addresses of the host. That is when I encountered the problem. The nc -l test is just to simplify the problem description.

I conclude that all IPv6 addresses with 2a01:2e8:d2c:e24c prefix will point to my machine
That assumption is wrong. The prefix length has the same meaning as the IPv4 netmask. It determines which addresses are on your local network, not which addresses belong to your local host.

This is all you need:
ip route add local 2a01:2e8:d2c:e24c::/64 dev lo
Credit: Can I bind a (large) block of addresses to an interface?

To re-iterate and expand upon Sander's answer:
You must bind each individual IP address to the nic, network interface card, before it considers the traffic to send up the stack.
Wireshark sets the nic in promiscuous mode,i.e. send all traffic received.
There is a practical limit to how many IP addresses can be assigned on a system, MUCH less than the 2^64 required by the op post. Storing the addresses alone would be more than any system's memory.
Unlike IPV4 with its, 127.0.0.0/8, 2^24 loopback addresses, IPV6 only defines a single address 0::1/128.
The only practical solution would be to treat the entire IPV6 subnet as a "reverse" NAT using IP masquerading(NAT). This solution would require a second instance acting as the NAT "router". The rules would rewrite the destination addresses to a single address/port.

Related

Accessing webservice in docker image from a macchine different from docker host

Good morning,
I'm a new user of docker technology and I'm facing some issue.
Any help will be appreciated (I update the question, thanks to the questions provided by #JRichardsz).
Here the problem:
Docker Host: Ubuntu 20.04.2 LTS. This is a VMWare virtual machine
In the host no process is using port 80. (Running "sudo lsof -i :80" return no process name, if I do not start any docker image)
if I stop the running docker image by "docker compose down", I have 2 network interfaces:
docker0: flags=4099 mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:2f:a6:ae:d2 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
ens160: flags=4163 mtu 1500
inet 192.168.128.60 netmask 255.255.255.0 broadcast 192.168.128.255
inet6 fe80::250:56ff:fea6:60bb prefixlen 64 scopeid 0x20
ether 00:50:56:a6:60:bb txqueuelen 1000 (Ethernet)
RX packets 2929 bytes 251888 (251.8 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 424 bytes 53706 (53.7 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
when I start my docker image (this is a docker image provided by Xibo CMS developers), the network interfaces related to the docker image appears, and I'm able to view bridge information:
bridge name bridge id STP enabled interfaces
br-33e8e1916c0d 8000.024261f9ddaa no veth0b9040e
veth3c6ecf0
veth821b253
vethe879c11
docker0 8000.02422fa6aed2 no
when the docker is active, command "sudo lsof -i :80" provides me:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
docker-pr 25417 root 4u IPv4 122292 0t0 TCP *:http (LISTEN)
docker-pr 25423 root 4u IPv6 122300 0t0 TCP *:http (LISTEN)
so web service inside docker image is active on all interfaces.
If I open a browser inside the Linux docker Host, looking at url http://127.0.0.1/ I can access the web server page without any problem
If I open a browser at http://192.168.128.80/ in a PC connected in the same subnet of ens160, I'm not able to reach the webserver.
Please note, no firewall is active (if I shutdown docker image by "docker compose down" command, and try from a PC connected in the same subnet of ens160 to open a telnet connection to port 80 in 192.168.128.80, I can capture packets using tcpdump)
After stopping the docker image, I performed the following commands on the docker host PC:
sudo python3 -m http.server 80
connecting from a different PC using putty telnet on port 80, I can see messages on the python example command line (so no firewall issues)
Is there anyone that can help me find why the webservice inside docker image can be accessed only when opening webpage from Linux Docker Host machine?
Any help will be very helpful.

Can't reach service of host from container

On the host, there is a service
#server# netstat -ln | grep 3308
tcp6 0 0 :::3308 :::* LISTEN
It can be reached from remote.
The container is in a user-defined bridge network.
The server IP address is 192.168.1.30
#localhost ~]# ifconfig
br-a54fd3b63acd: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
inet6 fe80::42:1eff:fecc:92e8 prefixlen 64 scopeid 0x20<link>
ether 02:42:1e:cc:92:e8 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
inet6 fe80::42:37ff:fe9f:e4f1 prefixlen 64 scopeid 0x20<link>
ether 02:42:37:9f:e4:f1 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 34 bytes 4018 (3.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.30 netmask 255.255.255.0 broadcast 192.168.1.255
And ping from container also works.
#33208c18aa61:~# ping -c 2 192.168.1.30
PING 192.168.1.30 (192.168.1.30) 56(84) bytes of data.
64 bytes from 192.168.1.30: icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from 192.168.1.30: icmp_seq=2 ttl=64 time=0.105 ms
And the service is available.
#server# telnet 192.168.1.30 3308
Trying 192.168.1.30...
Connected to 192.168.1.30.
Escape character is '^]'.
N
But the service can't be reached from the container.
#33208c18aa61:~# telnet 192.168.1.30 3308
Trying 192.168.1.30...
telnet: Unable to connect to remote host: No route to host
I checked
Make docker use IPv4 for port binding
make sure I didn't have IPv6 set to only bind on IPv6
# sysctl net.ipv6.bindv6only
net.ipv6.bindv6only = 0
From inside of a Docker container, how do I connect to the localhost of the machine?
find my route is a little different.
# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default router.asus.com 0.0.0.0 UG 100 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
172.18.0.0 0.0.0.0 255.255.0.0 U 0 0 0 br-a54fd3b63acd
192.168.1.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
Does it matter? Or could it be another reason?
Your docker container is on a different network namespace and connected to a different interface than your host machine that's why you can't reach it using the ip 192.168.x.x
What you need to do is to use the docker network gateway instead, in your case 172.17.0.1 but be aware that this IP might no be the same from host to host so to reproduce this everywhere and be completely sure of which is the IP you can create an user-defined network specifying the subnet and gateway and running your container there for example:
docker network create -d bridge --subnet 172.16.0.0/24 --gateway 172.16.0.1 dockernet
docker run --net=dockernet ubuntu
Also whatever service you are trying to connect here must be listening on the docker's bridge interface as well.
Another option is to run the container on the same network namespace as the host with the --net=host flag, and in this case you can access service outside the container using localhost
Inspired by the official document
The Docker bridge driver automatically installs rules in the host
machine so that containers on different bridge networks cannot
communicate directly with each other.
I checked the iptables on the server, for an experiment I stopped the iptables temporary. Then the container can reach that service success. Later I was told, the server has been reboot recently. So guessing some config was lost after that reboot. Not familiar with iptables very much, and when I try
systemctl status iptables.service
It says the service is not installed. After I install and run the service,
iptables -L -n
is almost empty. Now not clue what kind of iptables rules can cause that messy.
But if anyone face the ping success telnet fail situation, iptables could be the place of the root cause.

ebtable NFLOG cause ARP request drop

Not sure what I'm doing wrong. I have two machines connected back to back with this ebtable rule setup:
ebtables -A OUTPUT -p ARP --arp-op Request --nflog-group 100 -j DROP
I have a process listening on netlink group 100. I have the following setup on both machines /etc/network/interface lets call this one peer1:
auto e101-001-0
iface e101-001-0 inet manual
auto bond100
iface bond100 inet manual
bond-slaves e101-001-0
bond-mode 4
bond-miimon 100
iface bond100.100 inet manual
vlan-raw-device bond100
auto br100
iface br100 inet static
bridge_ports bond100.100
address 10.1.1.1
netmask 255.255.255.0
The peer2 has the same setting except the ip address is 10.1.1.2. When I try to send a ping from peer1 to peer2, I get destination unreachable. Using arp -n I see it is not resolved. I used tcpdump and saw the ARP request was made on peer1 bridge but peer2 did not receive it on it's bridge. There are three ways I know of to get a ping across:
Erase the ebtable rule on peer1.
Don't use a bridge. This works fine if I just ping between physical interface.
Add this line to the etable rules above: --nflog-range 32. I can go as low as 22 and it will still work. It starts to fail around 17.
Anything lower than 32 seems to make it stop working. My questions are:
Is there a default nflog-range size if one is not set explicitly?
Is there a kernel config that affects the nflog-range size?
I know all this is part of the kernel so if it helps I'm using the default Debian Stretch kernel (Debian 4.9.110-3+deb9u4) (no special kernel config). peer2 is running on a modified kernel and is known to be working. If I have two systems with the same specs as peer2, everything works fine, which leads me to believe it maybe a kernel config issue.
Thanks for reading.

Unable to connect to Docker service

I am running a Docker image in a MAC machine and when I logged into the container, I see the ip address as "172.17.0.2"( cat /etc/hosts).
How does docker choose the IP?
Is there any IP range that Docker choose?
What if I run multiple container on the same host? Will it be different?
/etc/resolve.conf gives some IP. What is that IP and where does it get?
How to connect to Docker service using the internal IP, say 172.17.0.2
ping CONTAINER_ID -> returns the IP 172.17.0.2
How does it resolve the hostname?
I tried reading through networking but it doesn't help.
Also, I am running my service in the port 8443. Still, I am unable to connect.
I tried running,
docker run -net host -p 8443:8443 IMAGE
Still no luck.
Tried the below approach also.
docker run -p MY_MACHINE_IP:8080:8080 IMAGE
Tried with,
http://MY_MACHINE_IP:8080
http://localhost:8080
None of the above works.
ifconfig output,
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=1203<RXCSUM,TXCSUM,TXSTATUS,SW_TIMESTAMP>
inet 127.0.0.1 netmask 0xff000000
inet6 ::1 prefixlen 128
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=201<PERFORMNUD,DAD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
XHC20: flags=0<> mtu 0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
ether 60:f8:1d:b2:cb:0c
inet6 fe80::49d:a511:dc4e:7960%en0 prefixlen 64 secured scopeid 0x5
inet 10.231.168.63 netmask 0xffe00000 broadcast 10.255.255.255
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
p2p0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> mtu 2304
ether 02:f8:1d:b2:cb:0c
media: autoselect
status: inactive
awdl0: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1484
ether 0a:71:96:61:e4:eb
inet6 fe80::871:96ff:fe61:e4eb%awdl0 prefixlen 64 scopeid 0x7
nd6 options=201<PERFORMNUD,DAD>
media: autoselect
status: active
en1: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=60<TSO4,TSO6>
ether 72:00:07:57:48:30
media: autoselect <full-duplex>
status: inactive
en2: flags=8963<UP,BROADCAST,SMART,RUNNING,PROMISC,SIMPLEX,MULTICAST> mtu 1500
options=60<TSO4,TSO6>
ether 72:00:07:57:48:31
media: autoselect <full-duplex>
status: inactive
bridge0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
options=63<RXCSUM,TXCSUM,TSO4,TSO6>
ether 72:00:07:57:48:30
Configuration:
id 0:0:0:0:0:0 priority 0 hellotime 0 fwddelay 0
maxage 0 holdcnt 0 proto stp maxaddr 100 timeout 1200
root id 0:0:0:0:0:0 priority 0 ifcost 0 port 0
ipfilter disabled flags 0x2
member: en1 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 8 priority 0 path cost 0
member: en2 flags=3<LEARNING,DISCOVER>
ifmaxaddr 0 port 9 priority 0 path cost 0
nd6 options=201<PERFORMNUD,DAD>
media: <unknown type>
status: inactive
utun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 2000
inet6 fe80::3f17:8946:c18d:5d25%utun0 prefixlen 64 scopeid 0xb
nd6 options=201<PERFORMNUD,DAD>
utun2: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
inet6 fe80::20aa:76fd:d68:7fb2%utun2 prefixlen 64 scopeid 0xd
nd6 options=201<PERFORMNUD,DAD>
utun3: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1380
inet6 fe80::e42a:c616:4960:2c43%utun3 prefixlen 64 scopeid 0x10
nd6 options=201<PERFORMNUD,DAD>
utun1: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1342
inet 17...... --> 17.... netmask 0xff000000
inet6 fe80::93df:7780:862c:8a06%utun1 prefixlen 64 scopeid 0x12
nd6 options=201<PERFORMNUD,DAD>
for the first 4 question you can find here some information, in general the docker network is the responsable about manager the network.
Usually I specify the prots like this:
docker run -p 8443:8443 IMAGE
and it work.
An reference to an existing topic is here
1. How does docker choose the IP?
When docker installed in your machine it will create docker0 interface. It will gives ip address to your container whenever it launch.
you can verify the ip range for docker0 by ifconfig command.
2. Is there any IP range that docker choose?
Yes, Please refer my answer 1.
3. What if i run multiple container on the same host? Will it be different?
Yes, It will be different from the range of docker0 interface until you create your own network using docker network create for more refer : Docker Networking
4./etc/resolve.conf gives some IP. What is that IP and where does it get?
It's internal DNS of docker network you can give your DNS ip in vi /etc/systemd/system/docker.service.d/docker.conf add your DNS server on line like below:
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock -g "/opt/docker_storage" --dns <replace-dns-ip>
5. How to connect to docker service using the internal IP, say 172.17.0.2
You have to expose port to connect like docker run -p 8443:8443 <image-name>
after that you can connect by telnet localhost 8443 or curl http://172.17.0.2:8443
Most important
Add the following to /etc/sysctl.conf
net.ipv4.ip_forward = 1 and apply settings by
sysctl -p /etc/sysctl.conf
Hope this will help.
Thank you!
Docker manages all of this internal networking machinery itself. This includes allocating IP(v4) addresses from a private range, a NAT setup for outbound connections, and a DNS service to allow containers to communicate with each other.
A stable, reasonable setup is:
Run docker network create mynet, once, to create a non-default network. (Docker Compose will do this for you automatically.)
Run your containers with --net mynet.
When containers need to communicate with each other, they can use other containers' --name as DNS names (you can connect to http://other-container-name).
If you need to reach a container from elsewhere, publish its service port using docker run -p or the Docker Compose ports: section. It can be reached using the host's DNS name or IP address and the published port.
Never ever use the container-private IP addresses (directly).
Never use localhost unless you're absolutely sure about what it means. (It's a correct way to reach a published port from a browser running on the host that's running the containers; it's almost definitely not what you mean from within a container.)
The problems I've seen with the container-private IP addresses tend to be around the second time you use them: because you relaunched the container and the IP address changed; because it worked from your local host and now you want to reach it from somewhere else.
To answer your initial questions briefly: (1-2) Docker assigns them itself from a network that can be configured but often defaults to 172.17.0.0/16; (3) different containers have different private IP addresses; (4-5) Docker provides its own DNS service and /etc/resolv.conf points there; (6) ICMP connectivity usually doesn't prove much and you don't need to ping containers (use dig or nslookup for DNS debugging, curl for actual HTTP requests).

Which IPv4 is used while running ping *hostname* command

If I have a hostname that has several IPv4 addresses assigned.
Which IPv4 will be used by ping request to resolve the hostname address [for example, while running "ping Some-Pc"]?
Run the command 'route' in Linux and you will see the routing tables. Based on the destination address and the routing table you should be able to determine the interface being used to send the ICMP messages and thus the src IP address.
For example, given this routing table in Linux:
[mynode]$ route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default gateway 0.0.0.0 UG 100 0 0 enp0s3
10.0.2.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s3
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.56.0 0.0.0.0 255.255.255.0 U 100 0 0 enp0s8
192.168.124.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0
If you send a ping to address 10.0.2.45, it will use enp0s3 and the corresponding IP address as src address.
If you send a ping to address 172.17.0.0 it will send the address from NIC docker0 and the corresponding src IP address.
With ifconfig in Linux (ipconfig in Windows) you can see the IP address assigned to each interface.

Resources