Сегодня рассмотрим как защитить порты докера от доступа из интернета при помощи фаервола. Конечно настройка будет происходить при помощи iptables.
Вводные
Для применения правила в Ubuntu при помощи iptables используется пакет iptables-persistent.
1 |
apt install iptables-persistent |
Ну как используется. iptables-persistent нам нужен что бы правила применялись при старте системы.
Ничего нового скорее всего я не расскажу для тех кто уже знает как использовать iptables. Для тех же кто не знает статейка думаю будет полезной.
Итак, вводные. Представим что у нас есть хост, с установленным докером. И мы хотим что бы доступ по ssh, был только с адреса 67.98.32.122, доступ к портам 8080 и 8231 был с адреса 65.72.33.12, порты 80 и 443 были открыты для всех, а так же все порты открыты для адрес 132.75.14.52. Остальное отбрасываем. Все адреса вымышленные.
Табличка:
Адрес | Правило |
---|---|
132.75.14.52 | доступны все порты |
67.98.32.122 | только ссш (22 tcp порт) |
65.72.33.12 | tcp 8080 и 8231 |
любой | tcp 80 и 443 |
После установки iptables-persistent у нас появляется папочка /etc/iptables, в которой мы можем создать, а может и уже лежит файл rules.v4
1 |
nano /etc/iptables/rules.v4 |
Заполняем его следующим образом:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# custom generated *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :DOCKER-USER - [0:0] :chain-access - [0:0] #chain -A chain-access -m state --state RELATED,ESTABLISHED -j ACCEPT -A chain-access -p icmp -j ACCEPT -A chain-access -p tcp -m multiport --dports 80,443 -j ACCEPT -A chain-access -s 67.98.32.122 -p tcp -m tcp --dport 22 -j ACCEPT -A chain-access -s 65.72.33.12 -p tcp -m multiport --dports 8080,8231 -j ACCEPT -A chain-access -s 132.75.14.52 -j ACCEPT #host -A INPUT -j chain-access -A INPUT -i eno1 -j DROP #docker -A DOCKER-USER -j chain-access -A DOCKER-USER -i eno1 -j DROP COMMIT |
Теперь пару слов о том что мы написали:
- Все правила в iptables применяются сверху вниз. При первом совпадении, проверка дальше не идёт.
- Докер фильтруется по цепочке DOCKER-USER. Об этом написано в документации.
- Мы создали свою цепочку chain-access. Правила в этой цепочке будут применены как к INPUT так и к DOCKER-USER. Я сделал эту цепочку для простоты и удобства.
- Правила из /etc/iptables/rules.v4 применяются только при старте и только для IPv4.
- eno1 — имя внешнего сетевого интерфейса (посмотреть имена можно командой ip a )
Дополнение
При работающих сервисах в докере применить правила не получится (перетрёт правила которые создались докером). Поэтому самый простой вариант это перезагрузка. Либо применение правил, а затем перезапуск докера демона.
применение:
1 |
iptables-restore < /etc/iptables/rules.v4 |
докер:
1 |
systemctl restart docker.service |
После того как правила будут применены (например после ребута). Мы можем добавлять свои правила в цепочку chain-access без перезагрузки. Например добавим правило разрешающее для адреса 33.89.09.12 диапазон портов с 1000 по 1100.
1 |
iptables -I chain-access -s 33.89.09.12 -p tcp -m multiport --dports 1000:1100 -j ACCEPT |
и дублируем правило в файле /etc/iptables/rules.v4.
Так же не лишним будет запретить IPv6:
1 |
nano /etc/iptables/rules.v6 |
1 2 3 4 5 6 7 |
# Generated by ip6tables-save v1.8.4 on Fri Apr 9 07:36:42 2021 *filter :INPUT DROP [0:0] :FORWARD DROP [0:0] :OUTPUT ACCEPT [0:0] COMMIT # Comp |
Для просмотра действующих правил можем использовать команду iptables-save.
На сегодня это всё, если есть вопросы — пишите в комментариях ниже. Постараюсь ответить.