Вот мои команды iptables:
sudo iptables -F
sudo iptables -A INPUT -p tcp -s 109.123.74.85 --dport 27000 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 188.170.80.4 --dport 27000 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 27000 -j REJECT
sudo iptables -L
Что дает мне следующие правила iptables:
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- 109.123.74.85 anywhere tcp dpt:27000
ACCEPT tcp -- 188.170.80.4 anywhere tcp dpt:27000
REJECT tcp -- anywhere anywhere tcp dpt:27000 reject-with icmp-port-unreachable
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (0 references)
target prot opt source destination
Chain DOCKER-ISOLATION (0 references)
target prot opt source destination
И у меня есть простой HTTP-сервер, чтобы проверить это:
python3 -m http.server 27000
когда я запрашиваю его у VPN-клиента (ip 109.123.74.85): curl myServerIP:27000/1.txt
он не отвечает.
Но когда я выключаю VPN на клиенте и запрашиваю curl myServerIP:27000/1.txt
с IP клиента 188.170.80.4 работает нормально.
Кроме того, интересно, что когда я использую порт 8881 вместо 27000, он отлично работает как для VPN, так и для VPN-клиентов.
Итак, как настроить iptables для открытия порта 27000 для определенных клиентов IP-адресов, которые используют VPN, и блокировки для всех остальных?
Чтобы уточнить тип ответа: у меня время ожидания операции, когда я запрашиваю от клиента VPN:
curl myServerIP:27000/1.txt
curl: (7) Failed to connect to myServerIP port 27000: Operation timed out
Когда я описал, что с портом 8881 он работает нормально, я имел в виду, что в этом случае я использовал следующие iptables:
sudo iptables -A INPUT -p tcp -s 109.123.74.85 --dport 8881 -j ACCEPT
sudo iptables -A INPUT -p tcp -s 188.170.80.4 --dport 8881 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 8881 -j REJECT
Вот как я проверяю свой IP-адрес клиента: curl ifconfig.me
Блин, я понял, что у меня такая же проблема с VPN-клиентом, запрашивающим порт 27000 даже с пустыми iptables на сервере. Поэтому я думаю, мне следует написать в службу поддержки провайдера VPN, чтобы выяснить, что происходит. Хотя запрос порта 8881 работает нормально.
Итак, я сменил поставщика vpn, и все работает, как ожидалось
Думаю, вы не эксперт по iptables, поэтому я постараюсь вам быстро помочь, но вы должны прочитать руководство по iptables (это отличный документ), чтобы понять детали.
Сохраните пример набора правил в некоторый файл и загрузите его с помощью iptables-apply <path-to-file>
команда. По умолчанию эта команда требует подтверждения от пользователя. Если время ожидания истекло без подтверждения от пользователя, набор правил будет отменен.
Кроме того, вы должны прочитать документацию к вашему дистрибутиву Linux, чтобы сделать изменения постоянными, иначе результаты будут потеряны после перезапуска системы. Рекомендуется использовать пакет iptables-persistent или аналогичный.
Общий скелет набора правил для вашего случая:
# Generated by iptables-save v1.6.2 on Thu May 16 16:17:54 2019
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:HTTP_IN - [0:0]
# allow already established and related connections
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# you can use multiple port numbers, separated with comma
# use the HTTP_IN chain for incoming packets to tcp/27000 port
-A INPUT -p tcp -m tcp -m multiport --dports 27000 -j HTTP_IN
# allow local connections
-A INPUT -i lo -j ACCEPT
# allow the icmp packets. it can be improved.
-A INPUT -p icmp -j ACCEPT
# this is the whitelist of ip addresses
-A HTTP_IN -s 109.123.74.85/32 -j ACCEPT
-A HTTP_IN -s 188.170.80.4/32 -j ACCEPT
# this rule should be last in the HTTP_IN chain
-A HTTP_IN -j REJECT --reject-with icmp-port-unreachable
COMMIT
Чтобы добавить новый IP-адрес в белый список, лучше отредактируйте текущий файл набора правил и загрузите его с помощью iptables-restore
или iptables-apply
. Также вы можете использовать iptables -I HTTP_IN --src <allowed-ip> -j ACCEPT
команда.
Относительно некоторых деталей в вашем вопросе.
когда я запрашиваю его у VPN-клиента (ip 109.123.74.85):
curl myServerIP:27000/1.txt
он не отвечает.
Есть разница между not response
и connection reset
. В первом случае у вас нет ответа, во втором - вы получаете специальный пакет (tcp с флагом RST или какое-то сообщение ICMP). Если у вас нет ответа, значит проблема в другом месте - используйте tcpdump
для устранения неполадок. Если у вас есть ICMP port unreachable
ответ - проверьте IP-адрес вашего клиента, вероятно, он не такой, как вы ожидаете. Также вы можете проверить счетчики правил (лучше использовать iptables-save -c
команда для вывода полного набора правил со счетчиками).
Кроме того, интересно, что когда я использую порт 8881 вместо 27000, он отлично работает как для VPN, так и для VPN-клиентов.
Это ожидаемое поведение, потому что в этом случае пакеты не проходят ваш ACCEPT
/REJECT
правила и приняты политикой INPUT.
Самый эффективный способ устранения неполадок соединения между двумя хостами - использование tcpdump
на обоих концах. Также в Linux tcpdump
захватывает входящие пакеты до netfilter
(читать как iptables
) обработка, но исходящие пакеты после брандмауэра. Если вы видите исходящие пакеты на одной стороне, но не видите их как входящие на другой стороне, то они отбрасываются или теряются где-то между ними. Ты можешь использовать traceroute
с участием tcp
/udp
пакеты для обнаружения проблемного хоста.