Нескладний брандмауер (UFW) нічого не блокує під час використання Docker


44

Це вперше налаштування сервера Ubuntu (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

Але я все одно можу підключитися до баз даних на інших портах цієї машини . Будь-яке уявлення про те, що я роблю неправильно?

EDIT : ці бази даних є на контейнерах 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 (на докерному контейнері) з портами 8083та 8086. Я додав ufw status verboseвихід у запитання. Дякую.
ESala

Відповіді:


64

Проблема полягала у використанні -pпрапора на контейнерах.

Виявляється, Docker вносить зміни безпосередньо на ваші iptables, які не показані ufw status.

Можливі рішення:

  1. Перестаньте використовувати -pпрапор. Замість цього використовуйте докерні мережі або докерні мережі .

  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 дуже багато, хоча контейнери стають доступними у localhost, наприклад, для зворотного проксі. Краще переконайтесь, що контейнер правильно слухає, не використовуйте -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та а --linkдля інших. Таким чином, не може бути жодних зіткнень портів, і єдина точка доступу - через nginx.
ESala

1
Також перевірте цю посаду на предмет третьої обережності, яку ви повинні вжити! svenv.nl/unixandlinux/dockerufw
Хенк

1
Важливо : /etc/default/dockerце файл конфігурації, який використовується конфігурацією upstart. Якщо ви перейшли від початкового до системного, цей файл не буде використовуватися.
оршачар

@ESala Вам слід подумати над тим, щоб не позначити цю відповідь правильною, оскільки вона датується.
ctbrown

8

16.04 представляє нові виклики. Я зробив усі кроки, як показано. Запуск Docker за брандмауером ufw. Але я не зміг отримати докер плюс UFW для роботи 16.04. Іншими словами, незалежно від того, що я робив, всі докерські порти стали глобально відкритими в Інтернеті. Поки я не знайшов цього: Як встановити Docker 1.12+ для того, щоб НЕ перешкоджав IPTABLES / FirewallD

Мені довелося створити файл /etc/docker/daemon.jsonі помістити наступне:

{
    "iptables": false
}

Тоді я видав, sudo service docker stopто sudo service docker startКОНТАКТНО докер просто дотримується відповідних правил у UFW.

Додаткові дані: Докер перевищує UFW!


З Ubuntu 16.04 та Docker версії 17.09 це рішення розриває вихідне з'єднання з контейнерів. Дивіться відповідь askubuntu.com/a/833363/262702 та askubuntu.com/a/954041/262702
ctbrown

5

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

{   "iptables" : false }

EDIT : це може призвести до втрати зв’язку з Інтернетом зсередини контейнерів

Якщо увімкнено 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 = хост, коли ви запускаєте контейнер, щоб докер зіставив порт в ізольовану мережу, що використовується лише для хоста, а не мережеву містку за замовчуванням. Я не бачу законних способів блокувати мостову мережу. Крім того, ви можете використовувати власну визначену користувачем мережу з ізоляцією.


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.Стопний контейнер:

докер зупинити ваш контейнер; 2.Отримати ідентифікатор контейнера:

докер перевіряє ваш контейнер; 3.Modify 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.Запустіть свій конатинер;

docker start yourcontainer;


0

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

Виправлення, щоб зробити порт доступним лише для моїх контейнерів докера, була ця зміна у моєму docker-compose.ymlфайлі:

ports:
- "1234:1234"

до цього:

ports:
- "1234"

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.