docker ps shows different ports than nmap - docker

docker ps says there are three ports forwarded:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
06584d4ad44e quay.io/coreos/etcd:v3.1.8 "etcd -name etcd01..." 2 days ago Up 3 minutes 0.0.0.0:2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp etcd01
But nmap -sT 127.0.0.1 can only find the 4001:
Starting Nmap 7.40 ( https://nmap.org ) at 2017-06-13 00:06 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0011s latency).
Not shown: 969 closed ports, 30 filtered ports
PORT STATE SERVICE
4001/tcp open newoak
How comes? Can I verify if the ports are there in another way?

nmap doesn't scan all ports by default.
As you can see, it only scanned 1000 ports: 969 (closed) + 30 (filtered) + 1 (open).
To really scan all ports, you should specify use the -p option like this: -p1-65535. It may take a while, though... Customize the options to make it faster. You need to run as root for TCP SYN scan. The default TCP Connect is slower.
Do not use nmap for knowing which ports are opened when you're in the host. Use either netstat (deprecated) as in netstat -tunlp or ss (which accepts most of the same options as netstat): ss -tunlp. The options are nmemonic:
-t for TCP
-u for UDP
-n for numeric
-l for listening ports
-p for PID's

Related

Port issue with Docker for Windows

I'm trying to follow the beginner tutorial at training.play-with-docker.com. At Task 2, step 6, I do the following and get the error as below:
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 80:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
d39667ed1deafc382890f312507ae535c3ab2804907d4ae495caaed1f9c2b2e1
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: driver failed programming external connectivity on endpoint linux_tweet_app (a819223be5469f4e727daefaff3e82eb68eb0674e4a46ee1a32e703ce4bd384d): Error starting userland proxy: listen tcp 0.0.0.0:80: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
I am using Docker Desktop on a Win10 machine locally. I've tried resetting Docker as suggested here. Error persists. Since something else must be using port 80, I should be able to avoid the error by using a different port, right?
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:1337 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
Right! docker ps now confirms the container is running:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b700df12c2d1 dzemens/linux_tweet_app:1.0 "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp, 443/tcp, 0.0.0.0:1337->1337/tcp linux_tweet_app
But when I try to view the webpage that the tutorial sends me to, I get an error in the browser.
I'm not sure how the link is dynamically generated but it looks something like this:
http://ip172-18-0-32-blsfgt2d7o0g00epuqi0-80.direct.labs.play-with-docker.com/
Browser error as below:
The proxy could not connect to the destination in time.
URL: http://ip172-18-0-32-blsfgt2d7o0g00epuqi0-80.direct.labs.play-with-docker.com/
Failure Description: :errno: 104 - 'Connection reset by peer' on socketfd -1:server state 7:state 9:Application response 502 cannotconnect
Another highly-upvoted answer suggests I need to "disable Windows 10 fast startup" -- I have not tried this yet, mainly because I'm not sure what the full repercussions are with that setting.
Is there something stupidly obvious that I'm overlooking here? Shouldn't I be able to run this on different ports? If not, why not? If I have to use 80:80, but System is already using that port, won't I have some further problems if I try to kill that pid?
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> netstat -a -n -o | findstr :80 | findstr LISTENING
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:8003 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 1348
TCP 0.0.0.0:8081 0.0.0.0:0 LISTENING 4688
TCP 127.0.0.1:8080 0.0.0.0:0 LISTENING 2016
TCP 127.0.0.1:8082 0.0.0.0:0 LISTENING 28536
TCP [::]:80 [::]:0 LISTENING 4
TCP [::]:8003 [::]:0 LISTENING 4
TCP [::]:8080 [::]:0 LISTENING 1348
TCP [::]:8081 [::]:0 LISTENING 4688
I made a small change in the Dockerfile changing EXPOSE 80 443 to EXPOSE 1337 443 and I'm now able to view my app by navigating to localhost:1337 in my browser. I think that will get me through the next steps in the training module, but still curious if I'm doing something wrong.
This seems to work regardless of the change in Dockerfile (I've removed and republished after changing Dockerfile).
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
Try this
> net stop winnat
> docker start ...
> net start winnat
A part of the problem is that you're using the wrong mapping. The application uses the port 80, but you're mapping the ports 1337 to 1337.
The correct command should be:
PS C:\Users\david.zemens\Source\Repos\linux_tweet_app> docker container run --detach --publish 1337:80 --name linux_tweet_app $DOCKERID/linux_tweet_app:1.0
It may be because your IIS or some other server is already running on port 80.
Try stop the IIS and it should work.
Reference: https://forums.docker.com/t/error-starting-userland-proxy-listen-tcp-0-0-0-0-bind-an-attempt-was-made-to-access-a-socket-in-a-way-forbidden-by-its-access-permissions/81299/7

Establish conversation between hello-world apps in Docker containers

I'm trying to run my hello-world apps inside Docker: frontend need to consume REST from backend.
I run
docker run -p 1337:1337 --net=bridge me/p-dockerfile-advanced-backend:latest
docker run -p 1338:1338 --net=bridge me/p-dockerfile-advanced-frontend:latest http://127.0.0.1:1337
I am able to connect to both of them using a browser from the host OS (My desktop Windows 10 x64) :
The http://127.0.0.1:1337 parameter needed for the frontend application to know where the restful services reside. But the app cannot connect to them. I cannot connect too.
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\Users\user1> docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4b0852253b8a me/p-dockerfile-advanced-frontend:latest "/usr/bin/java -ja..." 24 minutes ago Up 24 minutes 0.0.0.0:1338->1338/tcp laughing_noyce
e73f8a6efa24 me/p-dockerfile-advanced-backend:latest "/usr/bin/java -ja..." 26 minutes ago Up 26 minutes youthful_chandrasekhar
PS C:\Users\user1> docker exec -it 4b0852253b8a bash
root#4b0852253b8a:/# apt-get install telnet
<...>
root#4b0852253b8a:/# telnet localhost 1337
Trying 127.0.0.1...
Trying ::1...
telnet: Unable to connect to remote host: Cannot assign requested address
root#4b0852253b8a:/#
Unable to connect, but it should because I specified --net=bridge on both containers and backend listen the port 1337 :
root#e73f8a6efa24:/# netstat -lntu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:1337 0.0.0.0:* LISTEN
root#e73f8a6efa24:/#
PS: I spent almost all day trying to make it work before asking here.
The problem is the 127.0.0.1 address.
Each container is assigned, by default, 2 interfaces: eth0 and lo (the loopback interface with the 127.0.0.1 address).
You need to specify the name or address of the previous container. For this simple application you may use the --link option.
docker run -p 1337:1337 --name backend me/p-dockerfile-advanced-backend:latest
docker run -p 1338:1338 --link backend:backend me/p-dockerfile-advanced-frontend:latest http://backend:1337
Note that the --link option is deprecated as stated in:
https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/
Since these are different containers, you have to expose ports on both of them. Run the first with:
docker run -p 1337:1337 --net=bridge me/p-dockerfile-advanced-backend:latest
Note that bridge is the default network so you it is extra. Both containers will be on the same bridge network by default anyway.

connect to docker app from remote server

am having a confussion (I think) regarding how to manage ports and TCP connections in docker. Currently I have a server A that is running some dockers containers, I am more interested in a application that s running in the port 4444, when I type docker container ls I get:
4d2c0db7e23c oryd/hydra:latest "/bin/sh" 27 minutes ago Up 27 minutes 4444/tcp, 0.0.0.0:9010->4445/tcp determined_snyder
7c586393ef61 oryd/hydra:latest "/bin/sh -c '/go/b..." 34 minutes ago Up 34 minutes 0.0.0.0:9000->4444/tcp someContainer
So, 1) I dont know how it's read 4444/tcp, 0.0.0.0:9010->4445/tcp what it means?
Then,I have a Server B with others apps (not docker) that are trying to connect to the container that is listening in the port 4444, but I get:
connectex: No connection could be made because the target machine actively refused it.
2) it's really the app running in the port 4444? that's why am interested in how to read the point 1
I must say that I typed in the server A this: sudo lsof -i -P -n and the only registers related with docker show this:
docker-pr 15057 root 4u IPv6 486152035 0t0 TCP *:9000 (LISTEN)
docker-pr 15224 root 4u IPv6 486156778 0t0 TCP *:9010 (LISTEN)
So, 1) I dont know how it's read 4444/tcp, 0.0.0.0:9010->4445/tcp what
it means?
This means that port 4445 from the container will be available as port 9010 on the host server from any interface.
To access your container from Server B, you should use the following: hostname-of-container-host:9010
If you want the service to be available from port 4445 of the host, you need to use -p 4445:port-of-the-service-from-the-container

Find open sockets in docker container

I have attached to a docker container and need to find out the number of sockets being open by java application . Unfortunately there is no lsof or netstat available in the container . There is no data in /proc/PID/net/tcp. Is there any way I can find this data?
I like netshoot for this. You can run a container in the same networking and even pid namespace, and use the tools in netshoot to analyze the other container's network:
$ docker run -d -p 8888:80 --name nginx-test nginx
d8a90f5c7d1744483ae6d26cc97dad222ed237b5c4211f711c9f15f88252897f
$ docker run --net container:nginx-test --pid container:nginx-test -it --rm nicolaka/netshoot
/ # netstat -lntp
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:80 0.0.0.0:* LISTEN 1/nginx: master pro
/ # ps -ef
PID USER TIME COMMAND
1 root 0:00 nginx: master process nginx -g daemon off;
7 104 0:00 nginx: worker process
8 root 0:00 sh
15 root 0:00 ps -ef
Alternatively, you can see this: /proc/PID/net/tcp in the host machine as long as you are in the same box as the docker daemon. This is less elegant than #BMitch's answer.
What you need to do is find out the PID of your process outside the container (in the main pid namespace, technically speaking, your host).
ps aux | grep java
Inside your container, your java has a pid; but outside it has another pid that you can use to access to the information that you have requested: /proc/PID/net/tcp

Bridge docker container port to host port

I run a docker container with the following command:
docker run -d --name frontend_service -net host --publish=3001:3000 frontend_service
As I understand it maps the local port 3001 to the container port 3000.
I already ssh to the container and checked curl localhost:3000. Works. But outside, on the host, I can't curl localhost:3001.
I checked nmap. The port is open:
nmap -v -sT localhost
Starting Nmap 6.47 ( http://nmap.org ) at 2016-10-19 01:24 UTC
Initiating Connect Scan at 01:24
Scanning localhost (127.0.0.1) [1000 ports]
Discovered open port 25/tcp on 127.0.0.1
Discovered open port 22/tcp on 127.0.0.1
Discovered open port 5051/tcp on 127.0.0.1
Discovered open port 3001/tcp on 127.0.0.1
Completed Connect Scan at 01:24, 0.06s elapsed (1000 total ports)
Nmap scan report for localhost (127.0.0.1)
Host is up (0.0011s latency).
Other addresses for localhost (not scanned): 127.0.0.1
Not shown: 996 closed ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp open smtp
3001/tcp open nessus
5051/tcp open ida-agent
How can i connect the container port with my host port?
When you specify --net=host, you are completely turning off Docker's network setup steps. The container won't get its own network namespace, won't get its own interfaces, and the port publishing system will have nothing to route to.
If you want your -p 3001:3000 to work, don't use --net=host.

Resources