UFW允许22的IPv4和IPv6,但启用时SSH断开连接


10

sudo ufw disable然后sudo ufw enable将我踢出SSH

DMESG报告

[UFW BLOCK] IN=eth0 OUT= MAC=30:........ SRC=192.168.1.me DST=192.168.1.server LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=15776 DF PROTO=TCP SPT=55640 DPT=22 WINDOW=253 RES=0x00 ACK URGP=0

我可以重新登录,而无需通过控制台更改规则(仍启用UFW)。

这是在将Xenial(16.04)从内核4.4升级到4.15(HWE)之后开始的。升级到18.04.1不能解决问题。

版本:

  • iptables v1.6.1
  • 友联0.35
  • 4.15.0-29-通用#31-Ubuntu
  • Ubuntu 18.04.1 LTS

UFW状态为冗长(省略了一些规则,但都允许)

Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22                         ALLOW IN    Anywhere
22 (v6)                    ALLOW IN    Anywhere (v6)

为什么会发生这种情况,或者至少如何恢复到预期的行为?

我看着这个答案,但不确定是否适用,但这是/etc/ufw/before.rules

#
# rules.before
#
# Rules that should be run before the ufw command line added rules. Custom
# rules should be added to one of these chains:
#   ufw-before-input
#   ufw-before-output
#   ufw-before-forward
#

# Don't delete these required lines, otherwise there will be errors
*filter
:ufw-before-input - [0:0]
:ufw-before-output - [0:0]
:ufw-before-forward - [0:0]
:ufw-not-local - [0:0]
# End required lines


# allow all on loopback
-A ufw-before-input -i lo -j ACCEPT
-A ufw-before-output -o lo -j ACCEPT

# quickly process packets for which we already have a connection
-A ufw-before-input -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-output -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A ufw-before-forward -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# drop INVALID packets (logs these in loglevel medium and higher)
-A ufw-before-input -m conntrack --ctstate INVALID -j ufw-logging-deny
-A ufw-before-input -m conntrack --ctstate INVALID -j DROP

# ok icmp codes for INPUT
-A ufw-before-input -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-input -p icmp --icmp-type source-quench -j ACCEPT
-A ufw-before-input -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-input -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-input -p icmp --icmp-type echo-request -j ACCEPT

# ok icmp code for FORWARD
-A ufw-before-forward -p icmp --icmp-type destination-unreachable -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type source-quench -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type time-exceeded -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type parameter-problem -j ACCEPT
-A ufw-before-forward -p icmp --icmp-type echo-request -j ACCEPT

# allow dhcp client to work
-A ufw-before-input -p udp --sport 67 --dport 68 -j ACCEPT

#
# ufw-not-local
#
-A ufw-before-input -j ufw-not-local

# if LOCAL, RETURN
-A ufw-not-local -m addrtype --dst-type LOCAL -j RETURN

# if MULTICAST, RETURN
-A ufw-not-local -m addrtype --dst-type MULTICAST -j RETURN

# if BROADCAST, RETURN
-A ufw-not-local -m addrtype --dst-type BROADCAST -j RETURN

# all other non-local packets are dropped
-A ufw-not-local -m limit --limit 3/min --limit-burst 10 -j ufw-logging-deny
-A ufw-not-local -j DROP

# allow MULTICAST mDNS for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 224.0.0.251 --dport 5353 -j ACCEPT

# allow MULTICAST UPnP for service discovery (be sure the MULTICAST line above
# is uncommented)
-A ufw-before-input -p udp -d 239.255.255.250 --dport 1900 -j ACCEPT

# don't delete the 'COMMIT' line or these rules won't be processed
COMMIT

PS:我没想到这可以“解决”问题,但仅供参考,我更改了SSHD监听的端口(以及相应的规则),问题仍然存在。


因此,一切正常,除了在关闭防火墙然后重新打开防火墙时暂时从ssh会话中退出之外,其他一切正常吗?
伯纳德·魏

是的,暂时断开连接,我必须重新连接。它不会“只是”停顿
Gaia

这很奇怪,因为通过ufw启用/禁用应该仅在重启后才生效。您可以使用systemctl status ufw进行检查,以查看发出这些命令时该命令仍在运行(或未运行)。
伯纳德·魏

2
这似乎是内核回归,似乎已在内核4.13和4.14之间引入。我现在正在做一个内核二分法。需要一两天。如果有任何读者已经知道了罪魁祸首,请在此处发布,以免浪费时间。
道格·史密斯

1
还没有错误号,我只完成了内核二分法。4d3a57f23dec59f0a2362e63540b2d01b37afe0a netfilter:conntrack:除非需要,否则不要启用连接跟踪。给我几个小时,我会写一个答案。
道格·史密斯

Answers:


9

背景和问题的范围:

  • 仅当启用了具有这些ssh允许规则的UFW或iptables并启动ssh会话时,才会出现此问题。即,任何根本没有iptables的SSH会话都可以正常工作,但是一旦规则集到位,可能会随机退出。
  • 回想一下ufw仅仅是iptables的前端。
  • 即使在内核4.18-rc8中也存在此问题。

到底是怎么回事?

sudo ufw allow in port 22以下iptables规则段中的结果:

Chain ufw-before-input (1 references)
    pkts      bytes target     prot opt in     out     source               destination
      16     1553 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
     386   300622 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
      15     1068 ufw-logging-deny  all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
      15     1068 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID

一旦sudo ufw disable其次sudo ufw enable,即使SSH连接本身保持精细,所产生的iptables规则集似乎已经忘记了与该特定连接的关联,因此任何进入的数据包,无效的分类。不知何故,连接跟踪表变得混乱了,甚至不认为该数据包是NEW,而是带有错误的标志,也不将该数据包视为现有连接的一部分。

考虑一个等效的非常基本的iptables ufw。两个脚本,一个用于清除规则集,另一个用于创建规则集:

#!/bin/sh
FWVER=0.01
#
# clear_firewall_min 2018.08.10 Ver:0.01
#       clear iptables minimum.
#       Currently for this question:
#       /ubuntu/1059781/ufw-allows-22-for-ipv4-and-ipv6-but-ssh-disconnects-when-enabling
#
echo "Loading clear_firewall_min version $FWVER..\n"

# The location of the iptables program
#
IPTABLES=/sbin/iptables

#Set some stuff
#
EXTIF="ens5"
UNIVERSE="0.0.0.0/0"

#Clearing any previous configuration
#
echo "  Clearing any existing rules and setting default policies.."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -F INPUT

# Reset all IPTABLES counters
$IPTABLES -Z

#sleep 10

echo clear_firewall_min $FWVER done.

和:

#!/bin/sh
#
# test_firewall 2018.08.13 Ver:0.01
#       Minimum version of most basic iptables firewall.
#
# test_firewall 2018.08.09 Ver:0.01
#       Most basic iptables firewall.
#       Currently for this question:
#       /ubuntu/1059781/ufw-allows-22-for-ipv4-and-ipv6-but-ssh-disconnects-when-enabling
#

#sleep 50

# The location of the iptables program
#
IPTABLES=/sbin/iptables

#Set some stuff
#
EXTIF="ens5"
UNIVERSE="0.0.0.0/0"

#Clearing any previous configuration
#
#echo "  Clearing any existing rules and setting default policies.."
$IPTABLES -P INPUT DROP
$IPTABLES -F INPUT

# loopback interfaces are valid.
#
$IPTABLES -A INPUT -i lo -s $UNIVERSE -d $UNIVERSE -j ACCEPT

$IPTABLES -A INPUT -i $EXTIF -p tcp -m conntrack --ctstate INVALID -j LOG --log-prefix "IINVALID:" --log-level info
$IPTABLES -A INPUT -i $EXTIF -p tcp -m conntrack --ctstate INVALID -j DROP
$IPTABLES -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j LOG --log-prefix "NEW TCP no SYN:" --log-level info
$IPTABLES -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
$IPTABLES -A INPUT -i $EXTIF -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
$IPTABLES -A INPUT -i $EXTIF -p tcp -m conntrack --ctstate NEW --dport 22 -j ACCEPT

echo "test_firewall_min $FWVER done..." >> /dev/kmsg

sleep 3

导致这些数据包的计数是在清除/加载循环之后,并在加载循环之后启动的ssh会话中进行的:

doug@s17:~$ sudo iptables -v -x -n -L
Chain INPUT (policy DROP 3 packets, 220 bytes)
    pkts      bytes target     prot opt in     out     source               destination
       0        0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
      35     6388 LOG        tcp  --  ens5   *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID LOG flags 0 level 6 prefix "IINVALID:"
      35     6388 DROP       tcp  --  ens5   *       0.0.0.0/0            0.0.0.0/0            ctstate INVALID
       0        0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 ctstate NEW LOG flags 0 level 6 prefix "NEW TCP no SYN:"
       0        0 DROP       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp flags:!0x17/0x02 ctstate NEW
       9      680 ACCEPT     all  --  ens5   *       0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
       0        0 ACCEPT     tcp  --  ens5   *       0.0.0.0/0            0.0.0.0/0            ctstate NEW tcp dpt:22

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 12 packets, 1408 bytes)
    pkts      bytes target     prot opt in     out     source               destination

请注意,在我在残缺的ssh会话终端上键入的35个无效数据包以及PuTTY终止之前。

为什么这会停止工作,而以前却能工作呢?

因为这是100%可重复的,所以将内核二等分相对容易,只是浪费时间。结果是:

4d3a57f23dec59f0a2362e63540b2d01b37afe0a is the first bad commit
commit 4d3a57f23dec59f0a2362e63540b2d01b37afe0a
Author: Florian Westphal <fw@strlen.de>
Date:   Fri Jul 28 11:22:04 2017 +0200

    netfilter: conntrack: do not enable connection tracking unless needed

    Discussion during NFWS 2017 in Faro has shown that the current
    conntrack behaviour is unreasonable.

    Even if conntrack module is loaded on behalf of a single net namespace,
    its turned on for all namespaces, which is expensive.  Commit
    481fa373476 ("netfilter: conntrack: add nf_conntrack_default_on sysctl")
    attempted to provide an alternative to the 'default on' behaviour by
    adding a sysctl to change it.

    However, as Eric points out, the sysctl only becomes available
    once the module is loaded, and then its too late.

    So we either have to move the sysctl to the core, or, alternatively,
    change conntrack to become active only once the rule set requires this.

    This does the latter, conntrack is only enabled when a rule needs it.

    Reported-by: Eric Dumazet <edumazet@google.com>
    Signed-off-by: Florian Westphal <fw@strlen.de>
    Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

链接到整个提交。

如何还原为预期的行为?

禁用ufw或清除iptables规则集后,创建一个新的SSH会话。它将在后续的ufw启用后继续存在,但有时可能会随机退出。

此问题将在某个时候通过相关的电子邮件列表在上游解决。

编辑:上游电子邮件线程(包含变通方法)。解决方法复制到此处:

echo 1 | sudo tee /proc/sys/net/netfilter/nf_conntrack_tcp_be_liberal

编辑2:上游建议的补丁,我已经测试并报告了。

编辑3:2018.11.06:这已经停滞在上游,我还没有时间去研究它们。我会尽快恢复原状。

编辑4:2019.03.17:我无法使用内核5.0可靠地重现此问题。


1
即使使用内核4.18-rc8,问题仍然存在。根据到任何ssh会话的队列是否为空,是否会发生问题之间存在关系。不,缓解不是解决方案。我需要更多的时间。
道格·史密斯

1
好,谢谢。我必须对答案进行一些更改,但不知道何时。这里有多个问题。我正在通过第二部分,仅与iptables有关。我正试图从问题中消除UFW。事情有点混乱(我认为),并且由于我发现的第一个提交,conntrak工具基本上已损坏。一旦有足够的细节,我就去上游。
道格·史密斯

1
@Gaia如果您没有分配全部赏金,那么如果有两个投票,Doug将只获得其中的50%。目前只有一个投票赞成,所以我要部分添加另一个以保证50%的赏金,但这主要是因为这是一个很好的答案。
WinEunuuchs2Unix

1
@Gaia:我只能假设您的问题与您的UFW规则中的某些问题有关。我已经发送了一封上游电子邮件(它们没有错误系统),但是我完全取消了UFW,仅引用iptables。由于我不在该特定电子邮件列表中,并且尚未在存档中看到它,因此我认为该文件正处于审核中。我将提供一个链接。
道格·史密斯

1
@Gaia:我无法推​​测。我所知道的是,仅使用ssh规则,启用UFW,然后重新启动ssh连接就可以正常工作,至少对我而言。在随后的UFW禁用/启用后,它将被丢弃。
道格·史密斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.