Uncomplicated Firewall (UFW) ничего не блокирует при использовании Docker


44

Я впервые настраиваю Ubuntu Server (14.04 LTS), и у меня возникают проблемы с настройкой брандмауэра (UFW).

Мне нужно только, sshи httpпоэтому я делаю это:

sudo ufw disable

sudo ufw reset
sudo ufw default deny incoming
sudo ufw default allow outgoing

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp

sudo ufw enable
sudo reboot

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

РЕДАКТИРОВАТЬ : эти базы данных находятся в контейнерах Docker. Может ли это быть связано? это переопределяет мой конфиг ufw?

EDIT2 : выводsudo ufw status verbose

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
22/tcp (v6)                ALLOW IN    Anywhere (v6)
80/tcp (v6)                ALLOW IN    Anywhere (v6)

какая база данных? какой порт? Вы уверены, что это та же самая машина? какой выходной ufw status
solsTiCe

@solsTiCe да, я уверен, что это та же самая машина. База данных - InfluxDB (на контейнере Docker) с портами 8083и 8086. Я добавил ufw status verboseвывод в вопрос. Спасибо.
ESala

Ответы:


64

Проблема заключалась в использовании -pфлага на контейнерах.

Оказывается, Docker вносит изменения прямо на вас iptables, которые не отображаются с ufw status.

Возможные решения:

  1. Прекратите использовать -pфлаг. Вместо этого используйте Docker Linking или Docker Networks .

  2. Свяжите контейнеры локально, чтобы они не были видны снаружи вашей машины:

    docker run -p 127.0.0.1:8080:8080 ...

  3. Если вы настаиваете на использовании -pфлага, скажите докеру не трогать вас iptables, отключив их /etc/docker/daemon.jsonи перезапустив:

    { "iptables" : false }

Я рекомендую вариант 1 или 2. Остерегайтесь того, что вариант 3 имеет побочные эффекты , такие как контейнеры не могут подключиться к Интернету.


8
Это так полезно - я схожу с ума от возможности доступа к портам, которые я не разрешил в UFW. Однако использование iptables = false значительно нарушает работу, например, когда контейнеры становятся доступными на локальном хосте, например, для обратного прокси. Лучше убедиться, что контейнер слушает правильно, не используйте -p 80:80, но используйте -p 127.0.0.1:80:80 или другой порт, например 127.0.0.1:3000:80, для обратного проксирования с nginx или apache и без порта столкновения.
Андреас Рифф

2
@AndreasReiff вы правы, но в последнее время я нашел, что лучше избегать -pкак можно больше. Например, в случае обратного прокси-сервера я не сопоставляю порты для рабочих контейнеров, а затем помещаю nginx в свой собственный контейнер с -p 80:80и a --linkна другие. Таким образом, не может быть никаких конфликтов портов, и единственная точка доступа - через nginx.
ESala

1
Также проверьте этот пост для третьей меры предосторожности, которые вы должны принять! svenv.nl/unixandlinux/dockerufw
Хенк

1
Важно : /etc/default/dockerэто файл конфигурации, используемый конфигурацией upstart. Если вы перешли с upstart на systemd, этот файл не будет использоваться.
orshachar

@ESala Вам следует подумать о снятии отметки с этого ответа как правильного, поскольку оно датировано.
ctbrown

8

16.04 представляет новые проблемы. Я сделал все шаги, как показано Запуск Docker за брандмауэром UFW, НО я НЕ смог заставить работать Docker плюс UFW 16.04. Другими словами, что бы я ни делал, все порты докеров стали глобально доступными для Интернета. Пока я не нашел это: Как настроить Docker 1.12+, чтобы НЕ мешать IPTABLES / FirewallD

Я должен был создать файл /etc/docker/daemon.jsonи поместить следующее:

{
    "iptables": false
}

Затем я выпустил sudo service docker stopтогда, наконец, sudo service docker startдокер просто следует соответствующим правилам в UFW.

Дополнительные данные: Docker отменяет UFW!


В Ubuntu 16.04 и Docker версии 17.09 это решение разрывает исходящее соединение из контейнеров. Смотрите ответ askubuntu.com/a/833363/262702 и askubuntu.com/a/954041/262702
ctbrown

5

Если вы используете систему инициализации systemd (Ubuntu 15.10 и более поздние версии), отредактируйте /etc/docker/daemon.json(возможно, потребуется создать его, если он не существует), убедитесь, что у него iptablesнастроен ключ:

{   "iptables" : false }

РЕДАКТИРОВАТЬ : это может привести к потере подключения к Интернету изнутри контейнеров

Если у вас включен UFW, убедитесь, что вы можете получить доступ к Интернету изнутри контейнеров. если нет - вы должны определить , DEFAULT_FORWARD_POLICYкак ACCEPTна /etc/default/ufwи применить трюк , описанный здесь: https://stackoverflow.com/a/17498195/507564


2

Быстрый обходной путь - при запуске Docker и сопоставлении портов. Вы всегда можете сделать

docker run ...-p 127.0.0.1:<ext pot>:<internal port> ...

чтобы предотвратить доступ вашего Docker извне.


2

Использование /etc/docker/daemon.jsonс контентом

{
  "iptables": false
}

может звучать как решение, но оно работает только до следующей перезагрузки . После этого вы можете заметить, что ни один из ваших контейнеров не имеет доступа к Интернету, поэтому вы не можете, например, пропинговать любой веб-сайт. Это может быть нежелательное поведение.

То же самое относится и к привязке контейнера к конкретному IP. Вы можете не хотеть этого делать. Окончательный вариант - создать контейнер и оставить его позади UFW, независимо от того, что происходит и как вы создаете этот контейнер, поэтому есть решение:

После того, как вы создадите /etc/docker/daemon.jsonфайл, вызовите:

sed -i -e 's/DEFAULT_FORWARD_POLICY="DROP"/DEFAULT_FORWARD_POLICY="ACCEPT"/g' /etc/default/ufw
ufw reload

поэтому вы устанавливаете политику пересылки по умолчанию в UFW для принятия и используете:

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE

Если вы собираетесь использовать docker-compose, то IP-адрес из приведенной выше команды должен быть заменен IP-адресом сети, создаваемой docker-compose при запуске с docker-compose up.

Я описал проблему и решение более подробно в этой статье

Надеюсь, это поможет!


1

В моем случае я изменил iptables, чтобы разрешить доступ к Docker только с определенных IP-адресов.

Согласно ответу ESala :

Если вы используете -pфлаг для контейнеров, Docker вносит изменения непосредственно в iptables, игнорируя ufw.

Пример записей, добавленных в iptables Docker

Маршрут к сети «ДОКЕР»:

-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Пересылка пакетов из цепочки «DOCKER» в контейнер:

-A DOCKER -i docker0 -j RETURN
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 6379 -j DNAT --to-destination 172.17.0.3:6379

Вы можете изменить iptables, чтобы разрешить доступ к цепочке DOCKER только с указанного исходного IP-адреса (например 1.1.1.1):

-A PREROUTING -s 1.1.1.1 -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT -s 1.1.1.1 ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

Возможно, вы захотите использовать iptables-save > /tmp/iptables.confи iptables-restore < /tmp/iptables.confвыводить, редактировать и восстанавливать правила iptables.


0

Используйте --network = host при запуске контейнера, чтобы docker отображал порт в изолированную сеть только для хоста вместо мостовой сети по умолчанию. Я не вижу законных способов заблокировать мостовую сеть. В качестве альтернативы вы можете использовать пользовательскую сеть с изоляцией.


0
  1. Войдите в вашу консоль докера:

    sudo docker exec -i -t docker_image_name / bin / bash

  2. И затем в вашей консоли докера:

    sudo apt-get update
    sudo apt-get install ufw
    sudo ufw allow 22
    
  3. Добавьте свои правила UFW и включите UFW

    sudo ufw enable

    • Ваш образ Docker должен быть запущен с --cap-add = NET_ADMIN

Чтобы включить опцию Docker «NET_ADMIN»:

Контейнер 1.Stop:

Докер останови свой контейнер; 2. Получить идентификатор контейнера:

Докер проверяет ваш контейнер; 3. Модифицировать hostconfig.json (путь к докеру по умолчанию: / var / lib / docker, вы можете изменить свой)

vim /var/lib/docker/containers/containerid/hostconfig.json

4. Найдите «CapAdd» и измените null на [«NET_ADMIN»];

...., "VolumesFrom": null, "CapAdd": ["NET_ADMIN"], "CapDrop": null, .... 5.Перезапустите докер на хост-компьютере;

перезапуск сервисного докера; 6. Запустите свой контейнер;

Докер запустить свой контейнер;


0

Раньше я docker-composeзапускал несколько контейнеров, а также имел проблему с тем, что один порт был открыт миру, игнорируя правила UFW.

Исправление для того, чтобы сделать порт доступным только для моих докер-контейнеров, было следующим изменением в моем docker-compose.ymlфайле:

ports:
- "1234:1234"

к этому:

ports:
- "1234"

Теперь другие docker-контейнеры все еще могут использовать порт, но я не могу получить к нему доступ извне.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.