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
  • UFW 0,35
  • 4.15.0-29-generic # 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 (и соответствующее правило), и проблема сохраняется.

Gaia
источник
Таким образом, все работает как надо, за исключением того, что вы на мгновение выходите из сеанса ssh, когда выключаете и снова включаете брандмауэр?
Бернард Вей
да, на мгновение, так как в нем отключается, и я должен подключиться снова. это не "просто" срыв
Гайя
Это очень странно, потому что включение / отключение через ufw должно вступать в силу только после перезагрузки. Вы можете проверить с помощью systemctl status ufw, чтобы убедиться, что он все еще работает (или не работает), когда выполняются эти команды.
Бернард Вэй
2
Похоже, что это регрессия в ядре, и она была введена между ядрами 4.13 и 4.14. Я делаю бисекцию ядра сейчас. Это займет день или два. Если кто-то из читателей уже знает, кто виновен, пишите здесь, чтобы я не терял время.
Дуг Смитис,
1
Нет номера ошибки, я только что закончил разделение ядра. 4d3a57f23dec59f0a2362e63540b2d01b37afe0a netfilter: conntrack: не включать отслеживание соединений без необходимости. Дайте мне несколько часов, и я напишу ответ.
Дуг Смитис

Ответы:

9

Предыстория и границы вопроса:

  • Проблема возникает только тогда, когда включен UFW или iptables с этими правилами ssh allow и запущен сеанс ssh. т. е. любой сеанс SSH, который был запущен вообще без iptables, работает нормально, но может быть подвержен случайным отсевам после того, как набор правил введен в действие.
  • Напомним, что 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, похоже, забыл связь с этим конкретным соединением и поэтому классифицирует все входящие пакеты как недействительные. Каким-то образом таблица отслеживания соединений стала запутанной, и пакет даже не считается НОВЫМ, но с неправильными флагами, а также не считается частью существующего соединения.

Рассмотрим очень простой эквивалент 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

Обратите внимание на 35 недопустимых пакетов, которые я набрал на поврежденном сессионном терминале ssh и до завершения 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 Если вы не назначили полную награду тогда Дуг будет получить только 50% из них IF Есть два вверх-голосов. В настоящее время есть только один голос "за", поэтому я добавляю еще один для 50% -ой гарантии вознаграждения, но в основном потому, что это отличный ответ.
WinEunuuchs2Unix
1
@Gaia: Я могу только предположить, что ваша проблема так или иначе связана с некоторыми другими вашими правилами UFW. Я отправил вышестоящее электронное письмо (у них нет системы ошибок), но я полностью исключил UFW и ссылаюсь только на iptables. Поскольку меня нет в этом конкретном списке электронной почты, и я еще не вижу его в архиве, я предполагаю, что он находится на модерации. Я предоставлю ссылку, когда она будет доступна.
Дуг Смитис
1
@ Gaia: я не могу спекулировать. Все, что я знаю, это то, что только с правилами ssh, UFW включен, а затем перезагружается соединение ssh работает нормально, по крайней мере для меня. Он сбрасывается при последующем отключении / включении UFW.
Дуг Смитис