- Вопрос или проблема
- Ответ или решение
- Почему контейнер Docker не доступен из внешней сети: анализ проблемы «порта, который фильтруется»
- 1. Анализ конфигурации Docker Compose
- 2. Убедимся, что контейнер доступен локально
- 3. Проверка состояния хоста
- 4. Проверка на наличие конфликтов сетевого интерфейса
- 5. Тестирование доступа
- 6. Проверка промежуточного сетевого оборудования
- Заключение
Вопрос или проблема
Меня перенаправили с SO (https://stackoverflow.com/questions/79256455/docker-compose-container-not-reachable-by-external-network)
У меня есть приложение, работающее на Ubuntu 20.04 LTS, где я не могу настроить порт (фиксированный на 8455), и мне нужно запускать его несколько раз. Поэтому я настроил контейнер Docker, чтобы он был доступен через порт 8457.
Но я не могу подключиться к контейнеру извне.
version: '3'
services:
t32tcpusb_3-6:
image: ubuntu
command: /home/fileuser/t32/bin/pc_linux64/t32tcpusb
privileged: true
stop_grace_period: 2s
volumes:
- "/home/fileuser/t32:/home/fileuser/t32"
- "/dev/lauterbach/trace32/3-6:/dev/lauterbach/trace32/3-6"
devices:
- "/dev/lauterbach/trace32/3-6"
ports:
- "8457:8455"
- Подключение с localhost:8457 работает.
- SSH-туннель к localhost:8457 работает.
- Подключение через Host-IP:8457 завершается неудачно из-за таймаута.
Если я запускаю приложение вне контейнера с его родным портом, оно работает, порт отображается как ‘открытый’:
$ sudo nmap -sS -p8455 192.168.1.104
PORT STATE SERVICE
8455/tcp open unknown
Если я запускаю приложение внутри Docker, оно не работает извне, порт отображается как ‘фильтруемый’
$ sudo nmap -sS -p8457 192.168.1.104
PORT STATE SERVICE
8457/tcp filtered unknown
Docker-proxy также работает нормально:
$ ps aux|grep docker-proxy
root 9293 0.0 0.0 1745360 3668 ? Sl 22:37 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 8457 -container-ip 172.22.0.2 -container-port 8455
root 9300 0.0 0.0 1745360 3700 ? Sl 22:37 0:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 8457 -container-ip 172.22.0.2 -container-port 8455
У вас есть идеи, почему порты, связанные с Docker, показываются как фильтруемые
?
Что также смущает: эта настройка работала несколько месяцев, и только сейчас я обнаружил, что она не работает..
$ sudo ufw status
Status: inactive
$ sudo iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy DROP)
target prot opt source destination
DOCKER-USER all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-1 all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
DOCKER all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
ACCEPT all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp -- anywhere 172.22.0.2 tcp dpt:8455
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (4 references)
target prot opt source destination
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
DROP all -- anywhere anywhere
RETURN all -- anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all -- anywhere anywhere
Ответ или решение
Почему контейнер Docker не доступен из внешней сети: анализ проблемы «порта, который фильтруется»
Контейнер Docker, который мы пытаемся настроить для доступа извне, не отвечает на запросы, и состояние порта отображается как «фильтруется». Давайте разберем все аспекты, касающиеся данной ситуации, и возможные решения.
1. Анализ конфигурации Docker Compose
Ваш файл docker-compose.yml
настроен следующим образом:
version: '3'
services:
t32tcpusb_3-6:
image: ubuntu
command: /home/fileuser/t32/bin/pc_linux64/t32tcpusb
privileged: true
volumes:
- "/home/fileuser/t32:/home/fileuser/t32"
- "/dev/lauterbach/trace32/3-6:/dev/lauterbach/trace32/3-6"
devices:
- "/dev/lauterbach/trace32/3-6"
ports:
- "8457:8455"
Убедитесь, что ваше приложение корректно запускается внутри контейнера и слушает на порту 8455
. Вам нужно проверить, как именно приложение реализует сетевые подключения и нет ли дополнительных настроек, касающихся биндирования интерфейса (например, если приложение настроено только на localhost
, оно будет недоступно извне).
2. Убедимся, что контейнер доступен локально
Если вы можете подключиться к localhost:8457
, значит проброс портов работает корректно, и проблема, скорее всего, связана с конфигурацией хоста. Это уже дает надежду, что приложение функционирует правильно в контейнере.
3. Проверка состояния хоста
Поскольку состояние порта 8457 отображается как «фильтруется», важно проверить настройки фаервола и маршрутизации. Вы упомянули, что ufw
неактивен, что само по себе хорошо, но стоит проверить iptables:
$ sudo iptables -L
Из приведенного вами вывода видно, что согласно правилам DOCKER-USER
у вас стоит политика RETURN
, что подразумевает, что любые пакеты, проходящие через эту цепочку, будут либо приняты, либо возвращены. Это позволяет трафику проходить. Тем не менее, посмотрите на DOCKER-ISOLATION-STAGE-2
, которая отбрасывает пакеты.
4. Проверка на наличие конфликтов сетевого интерфейса
Когда порт отображается как «фильтруется», это может свидетельствовать о том, что маршрутизация пакетов идет в неверном направлении или заблокирована. Убедитесь, что у вас нет других служб или приложений, прослушивающих тот же порт, а также проверьте, что ваша конфигурация сети не конфликтует.
5. Тестирование доступа
Попробуйте сделать проводимое тестирование с помощью команды nmap
, чтобы понять, как порт 8457 ведет себя извне:
$ nmap -sS -p8457 <ваш_IP_хоста>
Даже при условии, что хост отвечает, важно убедиться, что маршруты настроены правильно. Если там все еще показано «фильтруется», возможно, стоит временно позаботиться о тестовой настройке iptables:
$ sudo iptables -A INPUT -p tcp --dport 8457 -j ACCEPT
Это поможет вам выяснить, есть ли какая-либо блокировка на уровне фильтрации пакетов.
6. Проверка промежуточного сетевого оборудования
Если все вышеперечисленное не дало результатов, рекомендуется проверить, не блокирует ли какую-либо часть сетевого оборудования (например, роутер или коммутаторы) трафик на 8457. Иногда такие устройства имеют настройки, которые могут неожиданно влиять на доступность сервисов.
Заключение
Когда ваше приложение, работающее в Docker, не доступно из внешней сети и демонстрирует состояние «фильтруется», это может быть связано с изоляцией на уровне Docker, фаервола или маршрутизации сетевых пакетов. Последовательная проверка конфигурации, использование инструментов командной строки для диагностики и уверенность в отсутствии конфликтов смогут помочь решить проблему, обеспечив доступ к вашему контейнеру с внешней сети.