V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
DoraJDJ
V2EX  ›  问与答

正在搭 git 服务, iptables 允许 22 端口,然而策略并没有生效

  •  
  •   DoraJDJ · 2017-05-15 20:22:27 +08:00 · 3411 次点击
    这是一个创建于 2550 天前的主题,其中的信息可能已经有所发展或是发生改变。

    稍微遇到看上去有些奇怪的 bug 了。

    前几天自己用 docker 搭了个 gogs 服务给团队里的人用,安装时过程顺利,如下是 docker 容器的端口转发:

    yudachi@hostker:~$ sudo docker container port ydcgit
    22/tcp -> 0.0.0.0:22
    3000/tcp -> 0.0.0.0:60003
    

    其中 22 端口是用于 ssh 的,而 60003 用于 nginx 反代到其中一个虚拟主机上。

    然后我配置了下 iptables,允许 22 端口入站,然而策略并没有生效。

    如下是 iptables 配置:

    yudachi@hostker:~$ sudo iptables -L -v -n
    Chain INPUT (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      378  469K ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0           
        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           
      546 63053 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
        0     0 ACCEPT     all  --  *      *       127.0.0.1            0.0.0.0/0            state NEW
        0     0 ACCEPT     all  --  *      *       172.16.0.0/16        0.0.0.0/0            state NEW
        0     0 ACCEPT     all  --  *      *       172.17.0.0/16        0.0.0.0/0            state NEW
        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22 state NEW
        0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:22 state NEW
        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:<服务器的实际 ssh 端口> state NEW
        0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:<服务器的实际 ssh 端口> state NEW
        2   120 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 state NEW
        0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:80 state NEW
        7   400 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443 state NEW
        0     0 ACCEPT     udp  --  *      *       0.0.0.0/0            0.0.0.0/0            udp dpt:443 state NEW
        0     0 invalid_drop  all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
       14  1092 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = broadcast
        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            PKTTYPE = multicast
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x00
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x01
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x03/0x03
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x06/0x06
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x05/0x05
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x29
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x3F
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x3F/0x3F
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x11/0x01
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x18/0x08
        0     0 portscan_drop  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:0x30/0x20
       13   564 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 0 level 4
       13   564 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    
    Chain FORWARD (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
    
    Chain OUTPUT (policy ACCEPT 29 packets, 1622 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      378  469K ACCEPT     all  --  *      lo      0.0.0.0/0            0.0.0.0/0           
      383  138K ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state RELATED,ESTABLISHED
        0     0 invalid_drop  all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
    
    Chain invalid_drop (2 references)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID limit: avg 1/sec burst 5 LOG flags 0 level 4 prefix "INVALID PACKAGE"
        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            state INVALID
    
    Chain portscan_drop (11 references)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 1/sec burst 5 LOG flags 0 level 4 prefix "PORTSCAN DETECTED"
        0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0
    

    而下面是本人在本机测试的结果:

    λ ssh git@<服务器地址>
    ssh: connect to host <服务器地址> port 22: Connection timed out
    

    我稍微有点不能理解,端口号是正确的,配置时自我确定没有任何问题,为何这个规则并没有生效?

    刚才还尝试 Google 了相关关键词,暂时还没有找到自己想要的结果,想在此问问各位大触有什么解决方案?

    谢谢!

    第 1 条附言  ·  2017-05-15 22:39:39 +08:00
    初步确认原因,可能是 iptables 规则的问题。

    刚才尝试放行另外一个容器的 HTTP 端口时同样出现了无法连接的情况,而另外一个非运行在 docker 容器内的服务能够正常连接。
    18 条回复    2017-05-16 12:13:34 +08:00
    wdd2007
        1
    wdd2007  
       2017-05-15 20:32:04 +08:00
    service iptables save、service iptables restart 了么?
    DoraJDJ
        2
    DoraJDJ  
    OP
       2017-05-15 20:36:11 +08:00
    @wdd2007 iptables 已经重启很多次了,包括整个系统,甚至连 iptables 规则从头弄了一遍,仍然不行
    tlday
        3
    tlday  
       2017-05-15 21:15:27 +08:00 via Android
    看看 log,确定是入站还是出站的问题? sshd 进程的状态?不是很懂 iptables 输出的这个东西,只了解一点 iptables 的命令,无责任建议。
    shshilmh
        4
    shshilmh  
       2017-05-15 21:31:46 +08:00
    这个 22 是宿主机的端口还是容器的端口?
    cnnblike
        5
    cnnblike  
       2017-05-15 21:50:36 +08:00 via iPhone
    selinux 的问题? setenforce 0 试试
    DoraJDJ
        6
    DoraJDJ  
    OP
       2017-05-15 21:50:48 +08:00 via Android
    @shshilmh 容器映射到宿主机的端口,都是 22。

    允许所有端口入站时 22 可以联通,但是当我打开防火墙的时候,即使已经设置允许 22 端口然而还是无法联通。
    DoraJDJ
        7
    DoraJDJ  
    OP
       2017-05-15 21:52:13 +08:00 via Android
    @cnnblike 拒绝无脑关闭 SELinux。

    防火墙关闭的时候可以正常连接 22 端口,所以我可以确定与 SELinux 无关。

    另外,系统用的是 Ubuntu Server 16.04.2 LTS。
    cnnblike
        8
    cnnblike  
       2017-05-15 21:52:20 +08:00 via iPhone
    22 会不会和默认的 ssh 端口冲突? service sshd stop 试试
    DoraJDJ
        9
    DoraJDJ  
    OP
       2017-05-15 21:53:30 +08:00 via Android
    @cnnblike 服务器的 ssh 端口是另外的四位数字,我可以确定和容器端口不存在冲突。
    cnnblike
        10
    cnnblike  
       2017-05-15 21:53:45 +08:00 via iPhone
    @DoraJDJ 所以我才让你 setenforce 0 啊,重启一下不就开了么?这是在排障,先确定问题在哪里再说
    ryd994
        11
    ryd994  
       2017-05-15 22:09:35 +08:00
    不需要设置入站,docker 是从 bridge 走,算 FORWARD,你设置 publish 就行了
    你的问题是 docker 会有个占端口用的进程,有 selinux 的情况下可能占不到 22
    你可以试试 dockerd 加--userland-proxy=false
    ryd994
        12
    ryd994  
       2017-05-15 22:11:16 +08:00
    你这 iptables 看起来就不对:FORWARD DROP,也没有 DOCKER chain
    你先重启一下 docker 服务
    DoraJDJ
        13
    DoraJDJ  
    OP
       2017-05-15 22:20:34 +08:00 via Android
    @ryd994 重启了下 docker 服务,现在 iptables 里有 DOCKER chain 了,FORWARD 里也有 docker 相关的条目。

    然而 22 端口还是无法联通。
    ryd994
        14
    ryd994  
       2017-05-15 22:26:22 +08:00
    @DoraJDJ 那你是不是忘了重启容器啊?
    shshilmh
        15
    shshilmh  
       2017-05-15 22:54:17 +08:00
    看一下 nat 表 sudo iptables -t nat -nvL
    这是我的一个部署了 gitlab 容器的 nat 表
    ![]( )
    tlday
        16
    tlday  
       2017-05-16 10:04:53 +08:00
    @ryd994 经提醒突然发现 docker 的-p/-P 参数映射的端口原来也是走 bridge 网络的端口转发。我一直以为是本地直接作映射的。也就是说即使使用-p 参数映射端口,这个数据报实际上的路径也是
    外网->eth0->docker0->bridge->container
    而不是
    外网->eth0->container 的咯?
    ryd994
        17
    ryd994  
       2017-05-16 12:04:11 +08:00
    @tlday docker 使用 iptables nat 做的,不过还是有 userland proxy 做备份,同时占端口
    每个 container 必须有自己的网络栈,否则容器的网络隔离会比较麻烦
    tlday
        18
    tlday  
       2017-05-16 12:13:34 +08:00
    @ryd994 以前没有考虑过具体的实现,想当然了,现在再仔细考虑一下确实作 nat 转发才是最简单可靠的方案。感谢回复。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1061 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 22:05 · PVG 06:05 · LAX 15:05 · JFK 18:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.