我正在尝试将我的后端服务托管在具有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的转发被阻止,但我想不出如何允许它。
答案 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)访问容器。