We have a container that needs to contact the ECS container agent introspection endpoint at runtime.
The ecs task is using bridge networking mode.
The default iptables on our Amazon Linux 2 contain the following INPUT chain:
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:51678
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
I've added the rule ACCEPT tcp -- anywhere anywhere tcp dpt:51678 as an attempt to allow our containers to access the introspection endpoint.
However, it doesn't work.
If I delete REJECT all -- anywhere anywhere reject-with icmp-port-unreachable I can access the ECS container agent introspection no issues at all.
It feels bad removing the REJECT all from a security standpoint. Am I wrong? Is my attempt incorrect?
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-agent-introspection.html
If you're wondering, this is how we are hitting the endpoint at runtime from within our container
EC2_INSTANCE_ID=$(curl --silent ${ECS_CONTAINER_METADATA_URI_V4}/taskWithTags | jq -r '.ContainerInstanceTags.instanceid')
Help is greatly appreciated.
The amazon Linux 2 base ami we used had a reject all saved in the iptables chain INPUT.
Our old amazon Linux 1 instances didn't have this rule in their iptables.
To resolve this I did an iptables --flush and then added my desired rules and saved them.
i'm hosting a dockerized web application binded with port 8081 in my remote server.
I want to block that web application for external ips, as I already did wit port 8080 hosting a plain jenkins server.
Here's what i've tried:
iptables -A INPUT -d <my-server-ip> -p tcp --dport 8081 -j DROP
As I did with port 8080.
Here is
iptables -nv -L INPUT
output:
Chain INPUT (policy ACCEPT 2836 packets, 590K bytes)
pkts bytes target prot opt in out source destination
495 23676 DROP tcp -- * * 0.0.0.0/0 <my-ip-addr> tcp dpt:8080
0 0 DROP tcp -- * * 0.0.0.0/0 <my-ip-addr> tcp dpt:8081
Has it possibily something to do with DOCKER chain in iptables ?
Chain DOCKER (1 references)
pkts bytes target prot opt in out source destination
9 568 ACCEPT tcp -- !docker0 docker0 0.0.0.0/0 <container-eth1-addr> tcp dpt:8080
There are more specific rules i need to add ?
Isn't my server INPUT rules supposed to be applied before those listed in the DOCKER chain?
UPDATE - SOLVED
Thanks to larsks's comments I found the solution.
The goal here was to block tcp traffic on port 8081 binded with docker docker container but being able to use ssh tunneling as "poor man" VPN (so non publish the port was not an option).
Just had to add this rule:
iptables -I DOCKER-USER 1 -d <container-eth-ip> ! -s 127.0.0.1 -p tcp --dport 8080 -j DROP
I want to restrict my database access to 127.0.0.1, so I executed the following command:
docker run -it mysql:5.5 -p 127.0.0.1:3306:3306 -name db.mysql
But I have some confusion...
You can see here that only the port of 127.0.0.1 will be forwarded:
; docker ps
mysql:5.5 127.0.0.1:3306->3306/tcp db.mysql
Interestingly, I cannot find this restriction in iptables:
; iptables -L
Chain FORWARD (policy DROP)
DOCKER all -- anywhere anywhere
Chain DOCKER (2 references)
target prot opt source destination
ACCEPT tcp -- anywhere 192.168.112.2 tcp dpt:mysql
The source of this rule is anywhere.
The incoming traffic will go as next:
Incoming package to host's network -> use ip tables to forward to container
And, your restrict was not in iptables, it was in host's network, you just open 3306 bind on 127.0.0.1, not 0.0.0.0, so you of course not see anything in iptables. 127.0.0.1:3306:3306 means hostIp:hostPort:containerPort.
You could confirm it with netstat -oanltp | grep 3306 to see no 0.0.0.0 was there, so no foreign host could visit your host machine, thus also could not visit your container.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
I would like to block direct access to the docker containers from outside. I use a haproxy and want to only allow access to port 80, 443.
I added the following rule to iptables. But I still can access docker containers through different ports.
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
COMMIT
This probably due to the DOCKER chain
# iptables -L
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- anywhere anywhere state RELATED,ESTABLISHED
ACCEPT icmp -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:ssh
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:http
ACCEPT tcp -- anywhere anywhere state NEW tcp dpt:https
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER-ISOLATION all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.18.0.2 tcp dpt:http
Chain DOCKER-ISOLATION (1 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
What rules would I need to create to block direct access?
Rather than doing this with IP tables you could use the docker network create NETWORK command to create a network to connect your apps to as well as your proxy. Also don't expose the apps on any ports. The only container you should expose is your proxy. From within the proxy you can then route traffic using the container name as a hostname. Each container on the same network can be reached by other containers.
For example if
I have container A which has a name of my-service and a service running on port 3000 and no ports published to the host
Container B which is a proxy running on port 80 published to the host. My proxy can pass requests to http://my-service:3000 and it will route traffic to the container.
If I try to go to http://mydomain:3000 this wont work as ports have not been exposed and the only way to reach the app is via the proxy on port 80
I'd suggest taking a read of https://docs.docker.com/engine/userguide/networking/work-with-networks/ as this explains how to get started with networking.
Full Disclosure: I run this kind of setup on my personal VPS and cannot access my containers via ports directly. Using the built in docker networking will probably play better than messing around with your IP tables
Hope this is useful.
Dylan
Edit
I have generalised the process as I do not know the specifics of your setup with regards to proxies, network restrictions etc. I have also not gone into specific commands as the link above covers it better than I would.
I realize I'm responding to an old thread, but I've spent most of a morning frustrated by this problem. This post shows at the top of a google search, but I feel the accepted answer does not answer the OP's question, but instead offers a different design as a way of avoiding the problem stated in the original question. That solution requires standing up a new docker image to act as a gateway to the original docker.
It is possible the following information was not available at the time of the original question, but what I found from Docker.com is this link
https://docs.docker.com/network/iptables/
which appears to answer the original question when it states:
"
By default, all external source IPs are allowed to connect to the Docker daemon. To allow only a specific IP or network to access the containers, insert a negated rule at the top of the DOCKER filter chain. For example, the following rule restricts external access to all IP addresses except 192.168.1.1:
$ iptables -I DOCKER-USER -i ext_if ! -s 192.168.1.1 -j DROP"
and
"If you need to add rules which load before Docker’s rules, add them to the DOCKER-USER chain."
But regrettably, I have attempted that solution and it too does not appear to work for me on docker version 17.05.0-ce
As #dpg points out, this problem is frustating if you need to tackle it from a newbie point of view.
The main problem for me (as I try to resolve also the problems of #dpg's answer), is that the Docker documentation is confusing in two of the pages that address this (link1 and link2)
To summarize, and to save time for others, if you don't have a lot of knowledge, and fall into the "Docker and iptables", the answer is there, just that they have missed this: where ext_if is the name of the interface providing external connectivity to the host.
Instead, in the "Understand container communication" link, there is indeed a little text that exactly points that ext_if should be the network interface.
So, for me to limit the access to a docker exposed port (ex: 6782) (that means that the DOCKER-USER needs to be modified and not the common INPUT chain) to a certain IP (ex: 192.27.27.90) and restrict all others, I need to do this, which works in my case:
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 6782 -j REJECT
(Here I suppose that the network interface that communicates with the outside world is eth0 and that you want to REJECT instead of DROP).
If more clarification is needed, I will be glad to assist.
Addition to comment by #Ezarate11 (since I dont have enough rep to comment), make sure the --dport is the port that is being forwarded to, not the port that is exposed.
For example, if your configuration is 0.0.0.0:64743->80, then you would need to do
sudo iptables -I DOCKER-USER -p tcp -i eth0 ! -s 192.27.27.90 --dport 80 -j REJECT
This detail alone took me a while to figure out, I didn't see this mentioned anywhere else.
I've got some issues with my captive portal.
I want to open a pop-up when anyone try to connect to my Raspberry wifi access point. In order to, I have turn my Rpi into a wifi access point and I have put a LAMP server on my Rpi.
Actually I use DNSMASQ and i change the conf file to :
address=/#/10.0.0.1
listen-address=10.0.0.1
dhcp-range=10.0.0.10,10.0.0.50,12h
And I change the iptables in order to capture all the connexion :
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 443 -j DNAT --to-destination 10.0.0.1:443
iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j DNAT --to-destination 10.0.0.1:80
So when I connect and go on the browser with my phone I'm redirected to the home page of the server => This is what I want, so it's good :)
But my problem is I want a trigger to open the home page automatically when i connect to the network.
Anyone knows how to do this ?
Another question, when I call "google.fr" in my browser, I'm redirected to my Apache home page, but when I launch a search request in the browser, I've got an error. Anyone knows why ?
the reaseon why you get an error is either because :
your server is not setup for https request
if you request google.com/search?=whatever, /search doesn't exist on your server.
you need to:
configure your server for https (but it will show a security alert because of bad certificate)
tell your server to rewrite any "unknown" url to a specific virtual host showing your home page
This tutorial for Ubuntu, is a good follow along for the Raspberry Pi if you are using Apache and php in your captive portal setup.
http://aryo.info/labs/captive-portal-using-php-and-iptables.html (from archive)