Я пытаюсь сделать брандмауэр для моего raspberry pi. Правила, которые я хочу, это
Разрешить входящий SSH - это работает
Разрешить исходящий ssh - это НЕ работает и это моя главная проблема
- Разрешить входящий и исходящий VNC - в настоящее время это работает наполовину, где я могу подключиться, но не могу выполнять никаких действий. Не совсем приоритет
- Разрешить исходящий https — я могу зайти на веб-сайт, но мне кажется, что нужно добавить еще одну строку для DNS, чтобы это работало правильно при загрузке.
- Разрешить исходящие письма — это работает
- Разрешить исходящие пинги и получить ответ — это работает
- Отбросьте все остальное. Думаю, это работает, потому что я не могу установить исходящий SSH-трафик, поэтому я считаю, что проблема в моем правиле.
Я знаю, что мой ssh в целом работает, так как без загруженного брандмауэра я могу создать исходящее SSH-соединение с одного pi на другой.
#!/bin/sh
#Flush all rules
iptables -F
#Allow incoming and outgoing SSH
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
#Allow VNC sessions
sudo iptables -A INPUT -s 10.10.10.1,192.168.0.150 -m state --state NEW,ESTABLISHED -m tcp -p tcp -m multiport --dports 5900:5905,6000:6005 -j ACCEPT
sudo iptables -A OUTPUT -d 10.10.10.1,192.168.0.150 -m state --state NEW,ESTABLISHED -m tcp -p tcp -m multiport --sports 5900:5905,6000:6005 -j ACCEPT
#Accept only incoming etstablished and allow new or established outgoing
sudo iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -A INPUT -i eth0 -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
#Accept port 587 for email
sudo iptables -A INPUT -p tcp --sport 587 -j ACCEPT
sudo iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT
#Allow ping requests to go out and get a reply
sudo iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-reply -j ACCEPT
#Drop all other packets and protocols
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT DROP
решение1
Ваша проблема со строкой SSH заключается в том, что вы пытаетесь разрешить исходный порт 22
с вашей локальной машины. Однако, когда вы подключаетесь к удаленному серверу SSH, ваша машина не использует для этого порт 22. Она использует случайный порт, обычно из более высокого диапазона портов. Это имеет смысл, поскольку если бы она использовала порт 22 для исходящих подключений SSH, вы могли бы подключаться только к одному серверу SSH за раз.
Чтобы исправить это, самый простой способ — использовать --dport
вместо --sport
, разрешая каждое соединение, имеющее порт назначения 22
(ssh).
sudo iptables -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
Обратите внимание, что вам необходимодобавлятьэту строку вместо ее замены, как указал @bcs78 в комментариях.
Также, как правило, плохая идея блокировать трафик для внутреннего петлевого соединения. Некоторые программы полагаются на это соединение и не будут работать правильно без него. Добавьте это в начало вашего скрипта:
sudo iptables -A INPUT -i lo -j ACCEPT
решение2
Добавьте, один раз на цепочку, всеобъемлющийс сохранением состоянияправило, которое упростит большинство других правил:
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
iptables -F
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Плюс обычное lo
правило интерфейса, разрешающее все локальные службы. Удалите его, если считаете, что оно действительно не нужно:
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
Теперь вам не придется дублировать другие правила (я оставляю состояние, NEW
в котором оно было, даже если оно не очень полезно и не присутствовало постоянно):
iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -s 10.10.10.1 -m tcp -p tcp -m multiport --dports 5900:5905,6000:6005 -m conntrack --ctstate NEW -j ACCEPT
iptables -A INPUT -s 192.168.0.150 -m tcp -p tcp -m multiport --dports 5900:5905,6000:6005 -m conntrack --ctstate NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT
iptables -A OUTPUT -p icmp --icmp-type echo-request -j ACCEPT
Все решается первыми двумя правилами, нет необходимости дублировать каждое правило, и теперь начальное направление потока понятно: INPUT
или OUTPUT
, только один раз. Так что становится более ясно, что --sport 22
для SSH не помогало в исходящем случае ( --dport 22
необходимо). RELATED
было бы полезно, если бы были udp
правила для связанных icmp
ответов об ошибках. В этой настройке это может быть не нужно.