контейнер docker-compose недоступен из внешней сети – порт ‘фильтруется’

Вопрос или проблема

Меня перенаправили с 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, фаервола или маршрутизации сетевых пакетов. Последовательная проверка конфигурации, использование инструментов командной строки для диагностики и уверенность в отсутствии конфликтов смогут помочь решить проблему, обеспечив доступ к вашему контейнеру с внешней сети.

Оцените материал
Добавить комментарий

Капча загружается...