Docker outbound connection is blocked - docker

I am new to the docker world. I am currently setting up an custom application which relies on docker. The setup requires docker container to connect my outside network. All is working well but the container is unable to connect to outside network. After initial investiagtion and tcpdump I came to know that docker container can connect to the outside world. The packet is forwaded to the docker0 interface and docker0 has forwarded the packet to the eth0(physical interface), the eth0 then forwards the packet to the outside world and receives reponse. Now this is where the problem is, the eth0 after receiving reposne doesnot forward the packet to the docker0 interface and finally to the end host.
The below is the iptable run which are all set to default.
Also tcpdump output
Inteface present on th host
HOST OS is SUSE Ent linux 15.3
Docker version 20.10.17-ce, build a89b84221c85
I will be very much grateful for any reponse.
Thank You

Related

Why can my Docker app receive UDP data without publishing the port?

I'm learning Docker networking. I'm using Docker Desktop on Windows.
I'm trying to understand the following observations:
Short version in a picture:
Longer version:
First setup (data from container to host)
I have a simple app running in a container. It sends one UDP-datagram to a specific port on the host (using "host.docker.internal")
I have a corresponding app running on the host. It listens to the port and is supposed to receive the UDP-datagram.
That works without publishing any ports in docker (expected behavior!).
Second setup (data from host to container)
I have a simple app on the host. It sends one UDP-datagram to a specific port on the loopback network (using "localhost")
I have a corresponding app running in a container. It listens to the port and is supposed to receives the UDP-datagram.
That works only if the container is run with option -p port:port/udp (expected behavior!).
Third setup (combination of the other two)
I have an app "Requestor" running in a container. It sends a UDP request-message to a specific port on the host and then wants to receive a response-message.
I have a corresponding app "Responder" running on the host. It listens to the port and is supposed to receive the request-message. Then it sends a UDP response-message to the endpoint of the request-message.
This works as well, and - that's what I don't understand - without publishing the port for the response-message!
How does this work? I'm pretty sure there's some basic networking-knowledge that I simply don't have already to explain this. I would be pleased to learn some background on this.
Sidenote:
Since I can do curl www.google.com successfully from inside a container, I realize that a container definitely must not publish ports to receive any data. But there's TCP involved here to establish a connection. UDP on the other hand is "connectionless", so that can't be the (whole) explanation.
After further investigation, NAT seems to be the answer.
According to these explanations, a NAT is involved between the loopback interface and the docker0 bridge.
This is less recognizable with Docker Desktop for Windows because of the following (source):
Because of the way networking is implemented in Docker Desktop for Windows, you cannot see a docker0 interface on the host. This interface is actually within the virtual machine.

Docker swarm ingress - unable to connect through two networks

I tried to run docker swarm over two different networks.
First network is 10.10.100.x/24
Second network is 10.10.150.x/24
Both networks can see each other. There are no firewall rules between them to block any traffic.
Specifically I tested 7946 TCP and UDP and 4789 UDP. I can confirm, that I can connect from the first network to the second network on both ports and both protocols. And also from the second network to the first network without any issue.
Docker swarm is up and running and used engine is 20.10.11
I can see that all nodes have status=Ready and availability=Active.
Ingress network is default:
and I can see all peers listed there as well.
But when I deploy any service to any node with port -p 20000:80, then I can see this node only from the network where it was deployed.
If service lands on the first network, it is accessible only through nodes from the first network, not from the second.
If service lands on the second network, it is accessible only through nodes from the second network, not from the first.
Any thoughts how to fix this?
Thanks
update 1:
Tried to run swarm with additional parameter docker swarm init --default-addr-pool 172.100.0.0/16. Result remains the same.
update 2:
Based on the advice from #BMitch
I verified with sudo tcpdump -nn -s0 -v port 4789 or 7946, that port 7946 works (UDP and TCP).
I also verified with the previous tcpdump command and nc -z -v -u 10.10.150.200 4789 (run from the first network), that port 4789 works as well.
Same issue for me, routing and overlay work great but ingress load balancer only works through the same site endpoints that runs the container.
Oddly I discovered ingress load balancer works cross sites when using nc -l as server socket, making the whole even more obscure to me.
REM: Underlay network is wireguard VPN (L3 point-to-point)
In the end - problem was in the NAT. Our second network was behind NAT, which caused this issue. Once we removed NAT, everything worked.

Can't send/receive UDP communication between two Docker containers on Mac OS Host

I'm running Docker Desktop for Mac on host, it is running two containers.
Container-1: linux-based OS, running UDP-based server program listening on 14xxx port (udp://:14xxx/).
Container-2: linux-based OS, python application sending/receiving data via UDP address as udp://14xxx/ without any specific hostname.
Question: My python app on Container-2 is able to send on UDP port, but never receives anything back from Container-1.
Given UDP works differently from TCP & HTTP protocols..
How can I establish successful UDP communication between two docker containers running on same host (MacOS)?
Various things that I have tried, but no luck.
Tried running both containers using --network host option.
Tried creating a new docker network testnet and started containers using --network testnet option.
Never mind. I found the solution.
First, it was not a docker thing at all.
In my python application on Container-2, I used environment variables to determine the UDP address. Apparently, these variables were not set properly. Hence, the confusion/error.
Second, "--network host" is still a VALID argument to have for both running Docker containers to make sure they discover/talk to each other.
Hope it helps!

how to block external access to docker container linux centos 7

I have a mongodb docker container I only want to have access to it from inside of my server, not out side. even I blocked the port 27017/tcp with firewall-cmd but it seems that docker is still available to public.
I am using linux centos 7
and docker-compose for setting up docker
I resolved the same problem adding an iptables rule that blocks 27017 port on public interface (eth0) at the top of chain DOCKER:
iptables -I DOCKER 1 -i eth0 -p tcp --dport 27017 -j DROP
Set the rule after docker startup
Another thing to do is to use non-default port for mongod, modify docker-compose.yml (remember to add --port=XXX in command directive)
For better security I suggest to put your server behind an external firewall
If you have your application in one container and MongoDb in other container what you need to do is to connect them together by using a network that is set to be internal.
See Documentation:
Internal
By default, Docker also connects a bridge network to it to provide
external connectivity. If you want to create an externally isolated
overlay network, you can set this option to true.
See also this question
Here's the tutorial on networking (not including internal but good for understanding)
You may also limit traffic on MongoDb by Configuring Linux iptables Firewall for MongoDB
for creating private networks use some IPs from these ranges:
10.0.0.0 – 10.255.255.255
172.16.0.0 – 172.31.255.255
192.168.0.0 – 192.168.255.255
more read on Wikipedia
You may connect a container to more than one network so typically an application container is connected to the outside world network (external) and internal network. The application communicates with database on internal network and returns some data to the client via external network. Database is connected only to the internal network so it is not seen from the outside (internet)
I found a post here may help enter link description here. Just post it here for people who needed it in future.
For security concern we need both hardware firewall and OS firewall enabled and configured properly. I found that firewall protection is ineffective for ports opened in docker container listened on 0.0.0.0 though firewalld service was enabled at that time.
My situation is :
A server with Centos 7.9 and Docker version 20.10.17 installed
A docker container was running with port 3000 opened on 0.0.0.0
The firewalld service had started with the command systemctl start firewalld
Only ports 22 should be allow access outside the server as the firewall configured.
It was expected that no one others could access port 3000 on that server, but the testing result was opposite. Port 3000 on that server was accessed successfully from any other servers. Thanks to the blog post, I have had my server under firewall protected.

Can't set udp source port in docker

I am using Docker 18.06.1-ce-win73 on windows 10 and trying to perform the following udp operation:
Docker port 10001 --------------> host port 10620
It is mandatory for the application running on the host to receive packets from the port 10001.
Inside the docker container, using python I bind on the IP ('0.0.0.0', 10001) and use the socket to send my packets to the host IP on port 16020.
I have also started the container with the argument -p 10001:10001/udp.
Unfortunately, when receiving the packet on the Host application, the origin port is not 10001 but a random one.
Is it possible to force docker to use a specific source port when using UDP from inside the container ?
You can control the container source port, but when you communicate outside of docker, even to your host, the request will go through a NAT layer that will change the source to be the host with a random port. You may be able to modify the iptables rules to work around this NAT effect.
However, if you really need control of the source port like this, you may be better off switching to host networking (--net=host or network_mode: host depending on how you run your containers), or change to a networking driver like macvlan that exposes the container directly without going through the NAT rules.

Resources