Правило IPTables, разрешающее входящие соединения SSH

11

Цель этого сценария - разрешить трафик только через VPN, за исключением localhost <-> localhost и входящего трафика SSH. Но когда я запускаю сценарий через SSH, я отключаюсь и вынужден перезагружать виртуальную машину. Что не так с моим сценарием?

#!/bin/bash
iptables -F

#Allow over VPN
iptables -A INPUT -i tun+ -j ACCEPT
iptables -A OUTPUT -o tun+ -j ACCEPT

#Localhost
iptables -A INPUT -s 127.0.0.1/8 -j ACCEPT
iptables -A OUTPUT -d 127.0.0.1/8 -j ACCEPT

#VPN
iptables -A INPUT -s 123.123.123.123 -j ACCEPT
iptables -A OUTPUT -d 123.123.123.123 -j ACCEPT

#SSH
iptables -A INPUT -p tcp --dport ssh -j ACCEPT

#Default Deny
iptables -A INPUT -j DROP
iptables -A OUTPUT -j DROP
Стивен
источник

Ответы:

10

Цепочка вывода отвечает за любой выходящий пакет.

Ваш сценарий разрешает только исходящие пакеты для туннельного интерфейса, локального хоста и удаленного хоста в 123.123.123.123.

Если вы подключаетесь к серверу способом, который требует от демона SSH отправки пакетов в пункт назначения, отличный от указанного выше, трафик не будет разрешен для выхода.

Чтобы разрешить исходящие пакеты от вашего демона SSH клиенту SSH, вам нужно добавить следующее правило:

iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT

Вы также можете добавить критерии IP-адреса назначения в вышеприведенное правило, если вы подключаетесь только из одного местоположения. Это правило должно предшествовать окончательному правилу «DROP что-нибудь еще» для цепочки вывода.

hellodanylo
источник
+1 Это будет работать и более конкретно, чем использование установленного, связанного правила (делая его более или менее полезным в зависимости от контекста).
Златовласка
Оба отличных ответа я многому научил! Я проверил ответ @SkyDan, и он работает хорошо!
Стивен
Nitpick: цепочка вывода не отвечает за перенаправленные пакеты.
Бьорн Линдквист
13

Ваше #SSHправило подразумевает, что ssh является односторонней формой общения, а это не так. Данные отправляются туда и обратно.

Обычный способ справиться с этим, поскольку вы не можете заранее знать номер порта на стороне клиента, это разрешить соединения, которые считаются «установленными» или «связанными» с установленным соединением. Для этого вам нужно:

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Перед вашими DROPправилами (и желательно наверху, так как правила обрабатываются по порядку, и эти два будут применяться к большинству пакетов).

Там есть объяснение того , как соединение TCP укореняется здесь ; по сути, тот факт, что сервер отвечает на пакет, разрешенный вашим #SSH INPUTправилом, делает это так.

лютик золотистый
источник
1
Это не будет работать. Установлено означает, что пакеты в обоих направлениях для данного TCP-соединения были замечены. Если добавить только это правило, первый исходящий пакет все равно будет заблокирован.
hellodanylo
2
@SkyDan Вот ссылка для этого . Обратите внимание на диаграмму, что когда сервер отправляет syn / ack обратно клиенту после получения открытия syn, соединение устанавливается, то есть iptables пропускает этот ответный пакет: «Как только он увидел один пакет (SYN), он считает, что соединение как НОВОЕ. Как только он видит возвращаемый пакет (SYN / ACK), он считает соединение УСТАНОВЛЕННЫМ. " -> еще раз: iptables видит возвращаемый пакет, который сервер хочет отправить, устанавливает соединение как установленное и пропускает ответ.
Златовласка
1
Хорошо, я понимаю, почему это будет работать. Это немного неясно, так как человек iptables говорит только о том, чтобы видеть пакеты в обоих направлениях, а не о том, что пакеты TCP-рукопожатия являются исключением. Спасибо за ссылку!
hellodanylo
2
@SkyDan На самом деле логика применима не только к tcp - я ошибался в том, чтобы что-то менять -p tcpв этом смысле, и посмотрим на последующее объяснение UDP на этой странице (это то же самое). Дело в том, что сервер отвечает, не зная, разрешит ли это iptables или нет, и когда iptables получает этот ответ от сервера в локальной системе , он теперь видит трафик в обоих направлениях (даже если клиент еще этого не делал), считает соединение установлено, и позволяет ответ. «Техническость» здесь зависит от межсетевого экрана, находящегося посередине двух сторон.
Златовласка
1
Вы правы там. Кто-то, вероятно, должен включить эту информацию в iptables man.
hellodanylo