Порты 443/80 отображаются как закрытые после установки

Привет,

Я только что завершил установку Discourse на сервере Ubuntu 22.04.4 в среде виртуализации Proxmox VE.
Установка прошла успешно, без ошибок, но после её завершения сайт форума не открывается, сообщая, что сервис недоступен.

При проверке из моей сети я вижу, что порты закрыты:

PS C:\Users\mwojt> nmap 192.168.131.211
Nmap scan report for 192.168.131.211

PORT    STATE  SERVICE
22/tcp  open   ssh
80/tcp  closed http
443/tcp closed https

Однако при запуске той же команды для localhost внутри машины Ubuntu порты отображаются как открытые:

root@ubuntu-discourse:~# nmap localhost
Nmap scan report for localhost (127.0.0.1)

PORT    STATE SERVICE
22/tcp  open  ssh
80/tcp  open  http
443/tcp open  https

Но если я выполняю проверку IP-адреса с той же виртуальной машины Ubuntu на саму себя, я вижу следующее:

root@ubuntu-discourse:~# nmap 192.168.131.211
Nmap scan report for ubuntu-discourse (192.168.131.211)

PORT    STATE    SERVICE
22/tcp  open     ssh
80/tcp  filtered http
443/tcp filtered https

Таким образом, порты отображаются как отфильтрованные.

Порты были открыты в брандмауэре:

root@ubuntu-discourse:~# ufw status
Status: active

To                         Action      From
--                         ------      ----
80                         ALLOW       Anywhere
443                        ALLOW       Anywhere
22                         ALLOW       Anywhere
80 (v6)                    ALLOW       Anywhere (v6)
443 (v6)                   ALLOW       Anywhere (v6)
22 (v6)                    ALLOW       Anywhere (v6)

И перенаправление портов Docker, похоже, настроено правильно:

root@ubuntu-discourse:~# docker port 6922c7802903
80/tcp -> 0.0.0.0:80
80/tcp -> [::]:80
443/tcp -> 0.0.0.0:443
443/tcp -> [::]:443

Что я делаю не так? В чём проблема?

Я только что потратил ещё 90 минут на установку Discourse. На этот раз на отдельном физическом сервере, чтобы исключить проблемы с виртуальной средой, и столкнулся с той же проблемой, хотя тщательно следовал инструкциям с GitHub.

Разве это невозможно заставить работать??

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

Можете ли вы получить доступ к вашему экземпляру через прокси, например, Browserling?

Редактирование: постойте, ваш адрес 192.168.131.211 — это локальный адрес, и от него не следует ожидать доступности из глобальной сети.

Редактирование: что вы видите на вашем хосте Discourse, когда выполняете netstat -rn?

Вот мой вывод netstat:

root@ubuntu-forum:/var/discourse# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.131.1   0.0.0.0         UG        0 0          0 enp1s0
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
192.168.130.0   0.0.0.0         255.255.254.0   U         0 0          0 enp1s0
192.168.131.1   0.0.0.0         255.255.255.255 UH        0 0          0 enp1s0
192.168.131.152 0.0.0.0         255.255.255.255 UH        0 0          0 enp1s0

Помимо Discourse на Ubuntu, я установил Talkyard на Debian (Talkyard — это движок форумов, немного похожий на Discourse), также в Docker, и он работает отлично. Поэтому я думаю, что попробую установить Discourse и на Debian.

Вывод netstat -rn на моём Debian выглядит так:

root@debian-12:~# netstat -rn
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
0.0.0.0         192.168.131.1   0.0.0.0         UG        0 0          0 ens18
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
172.26.0.0      0.0.0.0         255.255.255.128 U         0 0          0 br-886bebfa13ae
192.168.130.0   0.0.0.0         255.255.254.0   U         0 0          0 ens18

Не уверен, что это полезно.

Думаю, это правда, что Discourse работает только при доступе через домен. Поэтому у вас есть настройка, позволяющая открывать ваш сайт через браузер и домен? Если вы полностью находитесь в локальной сети (LAN), возможно, это можно сделать с помощью файла hosts, но я не уверен. Мне кажется, что и сервер, и клиент (а возможно, и Docker) должны иметь возможность выполнять поиск по имени.

У меня есть локальный DNS-сервер, который разрешает моё сетевое имя для этого хоста, поэтому всё работает так же, как и из внешнего мира.

Я успешно установил Discourse на виртуальную машину в DigitalOcean. Я буду использовать её как эталон для моей локальной конфигурации. Одна вещь, которую я сразу заметил, — это файл hosts на этой виртуальной машине — в нём есть следующая запись:

Надеюсь, это оно. Я дам вам знать.

Нет, не получилось… Я полностью обессилел после трёх дней борьбы и очень устал… :slightly_frowning_face:
Начинаю думать, что установить Discourse на локальную машину, не используя хостинг-провайдера, невозможно :frowning:

Посмотрите это видео, которое я записал во время установки, и, пожалуйста, скажите, что я делаю не так.

Стоит попробовать
lsof -i
на сервере

Кажется весьма вероятным, что Discourse запущен, но из-за проблем с сетью к нему невозможно подключиться.

Отлично, я нашёл корневую причину… Я проверил логи Docker, и оказалось, что сервер nginx вообще не запускается, так как не может получить сертификат Let’s Encrypt (см. прикреплённые логи).
docker_logs_not_working.txt (10.0 КБ)

Теперь мне нужно понять, как это исправить. На самом деле SSL мне даже не нужен, так как я использую обратный прокси со своими собственными SSL-сертификатами. Поэтому он может легко общаться с Discourse через порт 80. Не уверен, понравится ли это серверу Discourse.

Если вы поищете, то обнаружите, что это самая распространенная причина, по которой локальные настройки в закрытых средах, иначе называемых интранетами, не работают. Для Discourse требуется SSL.

Мой DNS хостится в Cloudflare, поэтому я могу легко получить сертификаты Let’s Encrypt, предоставив для этого API-ключ. Можно ли настроить ACME в Discourse, чтобы автоматическая выдача сертификатов работала корректно? В документации я этого не нашел, но, возможно, я плохо искал.

После долгой борьбы мне наконец удалось это исправить.

Вот что нужно сделать:
В сессии SSH выполните следующую команду, чтобы найти идентификаторы или имена контейнеров:

docker ps

Используйте следующую команду для доступа к оболочке контейнера Docker:

docker exec -it [container_id or name] bash

Экспортируйте ключ API Cloudflare и адрес электронной почты как переменные окружения. Это необходимо, чтобы скрипт ‘acme.sh’ мог аутентифицироваться с API Cloudflare для создания и удаления DNS-записей, требуемых для DNS-проверки. Я использовал свой реальный адрес электронной почты и глобальный ключ API из вашей учетной записи Cloudflare.

export CF_Key="your_cloudflare_global_api_key"
export CF_Email="your_cloudflare_email_address"

Перейдите в следующую директорию:

cd /shared/letsencrypt

Запустите acme.sh с командой --issue, указав, что вы хотите использовать режим dns_cf (DNS Cloudflare) для обработки DNS-проверок. Замените yourdomain.com на домен, для которого вы хотите получить сертификат.

./acme.sh --issue --dns dns_cf -d yourdomain.com -d *.yourdomain.com

После успешного создания сертификата скрипт отобразит директорию, в которую он был скопирован. В моем случае это было:

Your cert is in: /root/.acme.sh/sprawy.info.pl_ecc/sprawy.info.pl.cer
Your cert key is in: /root/.acme.sh/sprawy.info.pl_ecc/sprawy.info.pl.key
The intermediate CA cert is in: /root/.acme.sh/sprawy.info.pl_ecc/ca.cer
And the full chain certs is there: /root/.acme.sh/sprawy.info.pl_ecc/fullchain.cer

Отредактируйте файл discourse.conf, чтобы обновить путь к сертификату:

nano /etc/nginx/conf.d/discourse.conf

Существующие строки ssl_certificate и ssl_certificate_key следует заменить на:

ssl_certificate /root/.acme.sh/sprawy.info.pl_ecc/sprawy.info.pl.cer;
ssl_certificate_key /root/.acme.sh/sprawy.info.pl_ecc/sprawy.info.pl.key;

Таким образом, они теперь указывают на новые расположения сертификатов.

Выполните следующую команду для проверки конфигурации:

nginx -t

Если ошибок нет — перезагрузите веб-сервер:

nginx -s reload

И вуаля!

Отличные новости, молодец, что разобрался. Стоит отметить, что с Let’s Encrypt, если вы делаете серию неудачных запросов на получение сертификата, вас блокируют (на 7 дней, если не ошибаюсь). Поэтому важно быть внимательным и правильно оформлять эти запросы.