允许从本地主机到Docker容器的流量

时间:2019-01-06 03:58:35

标签: docker iptables

我正在尝试将我的后端服务托管在具有docker的Ubuntu 16.04服务器上。有一个nginx处理所有HTTP请求并将它们代理传递给后端服务。

使用 iptables const stringsToPages = (strings) => { // below is just a display of what is passed - not actually in my code. var strings = ["1 Received a ban", "2 Had a ban removed", "3 Received a ban", "4 Had a ban removed", "5 Received a ban", "6 Had a ban removed", "7 Received a ban", "8 Had a ban removed", "9 Received a ban", "10 Had a ban removed", "11 Received a ban", "12 Had a ban removed", "13 Received a ban"] let pages = ['']; // Initate pages array to return let currPage = 0; var limit = 50; // Character limit var clone = strings.slice(0); // Clone array clone.forEach(i => { let curPageLen = (pages[currPage] + i).length + 2; if (curPageLen >= limit) { pages[++currPage] = ''; } pages[currPage] = `${pages[currPage]}\n${i}`; }); return pages; // below is what is returned - not actually in my code. } let pages = stringsToPages(); console.log(pages); pages.forEach(p => console.log(p.length));INPUT OUTPUT-一切正常,但是,如果我尝试将除HTTP / HTTPS之外的任何访问限制到nginx, localhost 和docker容器中断。

这是我的 iptables

ACCEPT

我代理传递的容器在映射到docker-compose.yml中的3003的端口4000上运行:

-P INPUT DROP
-P FORWARD DROP
-P OUTPUT DROP
-N DOCKER
-N DOCKER-ISOLATION-STAGE-1
-N DOCKER-ISOLATION-STAGE-2
-N DOCKER-USER

# Drop empty flag packets and sync-flood packets
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP
-A INPUT -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j DROP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG FIN,SYN,RST,PSH,ACK,URG -j DROP

# Allow HTTP/HTTPS
-A INPUT -p tcp -m tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

-A OUTPUT -p tcp -m tcp --sport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 8080 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -p tcp -m tcp --sport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT


# Allow DNS
-A INPUT -p udp -m udp --sport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --sport 53 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 53 -j ACCEPT

# Block ping
-A INPUT -p icmp -m state --state NEW -m icmp --icmp-type 8 -j DROP

# Allow any loopback
-A INPUT -i lo -j ACCEPT
-A OUTPUT -o lo -j ACCEPT

# Allow forwarding from/to localhost to/from docker
-A FORWARD -i docker0 -o lo -j ACCEPT
-A FORWARD -i lo -o docker0 -j ACCEPT

# Docker-generated rules    
-A FORWARD -j DOCKER-USER
-A FORWARD -j DOCKER-ISOLATION-STAGE-1
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
-A FORWARD -o br-30c18a0778b5 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -o br-30c18a0778b5 -j DOCKER
-A FORWARD -i br-30c18a0778b5 ! -o br-30c18a0778b5 -j ACCEPT
-A FORWARD -i br-30c18a0778b5 -o br-30c18a0778b5 -j ACCEPT
-A DOCKER -d 172.18.0.2/32 ! -i br-30c18a0778b5 -o br-30c18a0778b5 -p tcp -m tcp --dport 27017 -j ACCEPT
-A DOCKER -d 172.18.0.3/32 ! -i br-30c18a0778b5 -o br-30c18a0778b5 -p tcp -m tcp --dport 4000 -j ACCEPT
-A DOCKER-ISOLATION-STAGE-1 -i docker0 ! -o docker0 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -i br-30c18a0778b5 ! -o br-30c18a0778b5 -j DOCKER-ISOLATION-STAGE-2
-A DOCKER-ISOLATION-STAGE-1 -j RETURN
-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -o br-30c18a0778b5 -j DROP
-A DOCKER-ISOLATION-STAGE-2 -j RETURN
-A DOCKER-USER -j RETURN

但是如果我运行 webapi: build: . depends_on: - mongo deploy: replicas: 1 resources: limits: cpus: "0.1" memory: 256M restart_policy: condition: on-failure ports: - "3003:4000" networks: - webnet -我会得到curl http://localhost:3003/api/healthcheck,这使我感到困惑,因为我对curl: (56) Recv failure: Connection reset by peer或转发到loopback没有任何限制。

我唯一的想法是:从容器的端口4000到本地主机3003的转发被阻止,但我想不出如何允许它。

2 个答案:

答案 0 :(得分:0)

对此的简单答案是仅在回送接口上发布端口,因此您无需对它们进行防火墙保护:

  port:
    - "127.0.0.1:3003:4000"

为调试防火墙规则,在丢弃数据包之前,我先在其中进行了一些登录。 Docker不仅使用docker-0网桥,还使用了很多东西,发布端口涉及各种nat / mangle规则和代理进程。

答案 1 :(得分:0)

我也遇到了一个问题,我创建了一个docker网络,只想公开DNS服务器和Nginx服务。这样做时,系统外部的一切工作都很好,但是只要INPUT策略为DROP,我就无法在主机内部进行访问。将本地主机以及确切的IP地址和端口添加到INPUT链无效。

我找到的解决方案是接受INPUT链中的docker网络桥接口。 Docker默认将其命名为br-(例如br-22153f050ac4)。您可以将此讨厌的标签添加到iptables配置中,也可以命名docker网络桥接口并添加更具确定性的接口名称。

假设您使用以下方式创建了网络:

docker network create -d bridge -o com.docker.network.bridge.name=webnet webnet

您应该能够允许localhost-> docker容器,例如:

sudo iptables -A INPUT -i webnet -j ACCEPT

假设一切都成功了,您现在应该可以通过本地主机地址(例如127.0.0.1)和docker容器地址(例如172.X.Y.Z)访问容器。