Выходной брандмауэр iptables не работает с IPv6
У меня есть сервер под управлением Ubuntu 16.04 с приложением, которому нужны только исходящие соединения для обновления пакетов и синхронизации времени NTP. Для этого он имеет динамический адрес IPv6 в отдельном сетевом интерфейсе. Все остальные соединения осуществляются через локальную сеть другого интерфейса, у которого нет шлюза в глобальную сеть.
Я бы хотел обезопасить эту машину, запретив любые исходящие соединения, кроме как для обновления пакетов и синхронизации времени NTP.
Однако, когда я пробую следующие правила, ничто не блокируется:
ip6tables -A OUTPUT -o lo -p all -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 -j ACCEPT
ip6tables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p udp -m owner --uid-owner systemd-timesync -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 53 -j ACCEPT
while read p; do
ip6tables -A OUTPUT -d $p -j ACCEPT
done < firewall/hosts-to-allow.list
ip6tables -A OUTPUT -o ens18 -j REJECT
Обратите внимание, что входящие запросы icmpv6 разрешены, но все остальные входящие порты заблокированы.
Обратите внимание, что в предыдущем состоянии этого вопроса я ошибочно отбрасывал все пакеты первыми после их регистрации.
Применяются следующие правила:
Chain INPUT (policy ACCEPT 70 packets, 126K bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT all * lo ::/0 ::/0
8 536 ACCEPT icmpv6 * * ::/0 ::/0
67 6405 ACCEPT all * * ::/0 ::/0 state NEW,RELATED,ESTABLISHED
0 0 ACCEPT tcp * * ::/0 ::/0 tcp dpt:53
0 0 ACCEPT udp * * ::/0 ::/0 udp dpt:53
0 0 ACCEPT udp * * ::/0 ::/0 owner UID match 100
0 0 ACCEPT tcp * * ::/0 2001:67c:1560:8001::14
0 0 ACCEPT tcp * * ::/0 2001:67c:1360:8001::17
0 0 ACCEPT tcp * * ::/0 2001:67c:1360:8001::21
0 0 ACCEPT tcp * * ::/0 2001:67c:1560:8001::11
0 0 ACCEPT udp * * ::/0 2001:67c:1560:8001::14
0 0 ACCEPT udp * * ::/0 2001:67c:1360:8001::17
0 0 ACCEPT udp * * ::/0 2001:67c:1360:8001::21
0 0 ACCEPT udp * * ::/0 2001:67c:1560:8001::11
0 0 ACCEPT tcp * * ::/0 2001:67c:1562::19
0 0 ACCEPT tcp * * ::/0 2001:67c:1560:8001::14
0 0 ACCEPT tcp * * ::/0 2001:67c:1562::16
0 0 ACCEPT tcp * * ::/0 2001:67c:1360:8001::21
0 0 ACCEPT tcp * * ::/0 2001:67c:1360:8001::17
0 0 ACCEPT tcp * * ::/0 2001:67c:1560:8001::11
0 0 ACCEPT udp * * ::/0 2001:67c:1562::19
0 0 ACCEPT udp * * ::/0 2001:67c:1560:8001::14
0 0 ACCEPT udp * * ::/0 2001:67c:1562::16
0 0 ACCEPT udp * * ::/0 2001:67c:1360:8001::21
0 0 ACCEPT udp * * ::/0 2001:67c:1360:8001::17
0 0 ACCEPT udp * * ::/0 2001:67c:1560:8001::11
0 0 REJECT all * ens18 ::/0 ::/0 reject-with icmp6-port-unreachable
Chain LOGGING (0 references)
pkts bytes target prot opt in out source destination
1 ответ
Ваша таблица OUTPUT немедленно начинается с отправки всего трафика для ens18 в таблицу LOGGING, которая переходит в журнал, а затем отбрасывает весь трафик.
Помните, что правила iptables интерпретируются по порядку. Поскольку вы уже отбросили весь трафик для ens18, никакие другие правила в OUTPUT не будут оцениваться для этого трафика.
Я подозреваю, что правило ведения журнала должно быть в конце таблицы, а не в начале. Конечно, вы уже поместили целевое правило REJECT, поэтому вам следует решить, какое из них вы хотите.
Я также подозреваю, что вы заметили бы намного раньше, если бы попытались подключиться к вашему серверу через IPv6 на уязвимом интерфейсе, поскольку вы бы сразу заметили, что трафик не проходит...
Кроме того, после устранения этой проблемы вы фактически разрешаете весь трафик в этом правиле:
ip6tables -A OUTPUT -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
Это соответствует каждому возможному действительному состоянию соединения. Я ожидаю, что вы не хотите, чтобы все NEW
соединения, только те RELATED
а также ESTABLISHED
тем, кого вы позволите позже.
Вам нужно удалить NEW
из этого (и использовать -m conntrack
вместо устаревших -m state
) и добавьте его к исходящим соединениям, которые вы хотите разрешить, например:
ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
а также
ip6tables -A OUTPUT -m conntrack --ctstate NEW -d $p -j ACCEPT