Сайт доступен по IP-адресу, если не следовать руководству по установке

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

Несколько причин:

  • Позволяет использовать сайт без HTTPS как для пользователей, так и при первоначальной настройке администратором.
  • Раскрывает адрес исходного сервера, что плохо, если вы используете Cloudflare или аналогичные сервисы для защиты IP-адреса исходного сервера от DDoS-атак или попыток взлома, особенно если хакеры считают сервер высокоценной целью. Существуют люди, запускающие ботов для сканирования всех диапазонов IP-адресов, принадлежащих веб-хостингам.

Кроме того, установщик Discourse теперь проверяет, правильно ли настроен домен/поддомен, и не продолжит установку, если это не так.

Всё, что нужно добавить в самый конец файла /etc/nginx/conf.d/discourse.conf (внутри контейнера Docker), это:

server {
    listen 80;
    server_name 1.1.1.1;
    server_tokens off;
    return 404;
}

Где 1.1.1.1 — это публичный IP-адрес вашего сервера. Вероятно, существует более элегантный способ указать IP-адрес, чем его жёсткое кодирование. Я пробовал несколько вариантов, но не смог заставить их работать.

Это хорошо работает у меня (включая проксирование через Cloudflare). Я не могу придумать много случаев, когда прямой веб-доступ по IP-адресу был бы полезен или необходим. Похоже, что запрет такого доступа — довольно распространённая практика. Буду рад услышать любые аргументы против такого подхода!

1 лайк

Зачем что-то менять, если наша стандартная инструкция оставляет вас с полностью рабочим сайтом, использующим только HTTPS?

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

9 лайков

Огромное спасибо!

1 лайк

Объективно говоря, это не совсем верно. Это не только HTTPS, так как вы можете получить доступ к сайту напрямую через IP-адрес, который не использует HTTPS.

Разница заключается в запрете на небезопасное подключение без HTTPS и в сокрытии исходного IP-адреса сервера. Мне неизвестно о каких-либо преимуществах такого подхода.

Если выполнить DNS-запрос для 50 крупнейших сайтов в мире, то окажется, что ни один из них недоступен напрямую через IP без HTTPS. Я считаю, что разумно предположить, что 50 крупнейших сайтов в мире используют лучшие практики.

Вот довольно точный список лидеров:

Вот инструмент для DNS-запросов:

Из коробки при попытке доступа по IP-адресу возвращается 301 Redirect на правильный домен:

$ curl 159.203.68.6 -I
HTTP/1.1 301 Moved Permanently
Server: nginx/1.16.1
Date: Mon, 29 Jun 2020 20:24:41 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
Location: https://falcoland.falco.dev/

Ваше предложение заключается в замене 301 на 404?

3 лайка

8 из 8 установок, выполненных с использованием образа Digital Ocean, включая установку (с последующей миграцией) через Communiteq (ранее DiscourseHosting), а также ручную установку по этой инструкции discourse/docs/INSTALL-cloud.md at main · discourse/discourse · GitHub — все они по умолчанию доступны небезопасно через IP-адрес. Две из них были установлены на прошлой неделе (по указанной выше инструкции с GitHub).

Возможно, я упускаю какой-то дополнительный шаг? Я бы сказал, что ответ 404 лучше, чем 301, учитывая, что большинство людей, просматривающих IP-адреса, вряд ли имеют добрые намерения. Однако ответ 301 всё же лучше, чем небезопасный доступ.

Не удалось воспроизвести..

http://38.242.24.122 корректно перенаправляет меня на https://discourse.codinghorror.com/

4 лайка

Хм, возможно, дело в шаблоне Cloudflare. Это, вероятно, единственное последовательное отличие от полностью стандартной установки у всех них.

1 лайк

Если вы предприняли шаги, которые не указаны в инструкции по установке Cloud, то по определению это не «чистая установка».

Шаблон Cloudflare явно не мешает перенаправлению:

run:
  - file:
      path: /tmp/add-cloudflare-ips
      chmod: +x
      contents: |
        #!/bin/bash -e
        # Загрузка списка IP-адресов CloudFlare
        wget https://www.cloudflare.com/ips-v4/ -O - > /tmp/cloudflare-ips
        wget https://www.cloudflare.com/ips-v6/ -O - >> /tmp/cloudflare-ips
        # Преобразование в команды nginx и экранирование для вставки в команду append sed
        CONTENTS=$(</tmp/cloudflare-ips sed 's/^/set_real_ip_from /' | sed 's/$/;/' | tr '\n' '\\' | sed 's/\\/\\n/g')
        
        echo CloudFlare IP-адреса:
        echo $(echo | sed "/^/a $CONTENTS")
        # Вставка в discourse.conf
        sed -i "/sendfile on;/a $CONTENTS\nreal_ip_header CF-Connecting-IP;" /etc/nginx/conf.d/discourse.conf
        # Очистка
        rm /tmp/cloudflare-ips

  - exec: "/tmp/add-cloudflare-ips"
  - exec: "rm /tmp/add-cloudflare-ips"

Скрипт загружает диапазоны IP-адресов, временно сохраняет их в файл cloudflare-ips и добавляет поддержку заголовка CF-Connecting-IP.

2 лайка

Верно. Я не утверждал, что это «чистые установки».

Поэтому я протестировал удаление официального шаблона Cloudflare на одной из них, а затем повторную сборку, но, к сожалению, это не дало результата. Доступ по IP всё ещё возможен без защиты.

Больше ничего необычного между этими установками я вспомнить не могу. На этом экземпляре были установлены только стандартные плагины: менеджер Docker и официальный плагин рекламы. Он работает на стабильной ветке, но другие сайты, которые ведут себя аналогично, находятся в разных ветках: стабильной, бета-версии и ветке с пройденными тестами.

Это не относится к какой-либо конкретной конфигурации или Cloudflare, а является просто ещё одним фактом и точкой зрения:

Мы можем настроить прокси для перенаправления «голового IP-адреса на порту 80» (в качестве примера) на любой другой FQDN несколькими способами как с помощью Apache2, так и Nginx.

Существует множество способов сделать это (перенаправление через перезапись, виртуальный хост с перенаправлением и т. д.).

Например, мы можем создать виртуальный хост на обратном прокси, который прослушивает IP-адрес на порту 80, и перенаправлять все такие запросы на любой выбранный нами FQDN (или IP-адрес).

Также это можно сделать с помощью обратного прокси, используя mod_rewrite в Apache2 и правила перезаписи в Nginx.

Для всех наших установок Discourse (в эксплуатации) перед Discourse стоит обратный прокси (часть на Apache2, часть на Nginx), и легко устранять подобные проблемы (по мере их возникновения), настраивая обратный прокси на обработку таких ситуаций и особых случаев.

Сказав это, я не использую специальный случай cloudflare в качестве прокси, но кажется, что любой прокси можно настроить для управления такими проблемами, точно так же, как любой обратный прокси можно настроить для перенаправления «почти чего угодно на что угодно».

Если пойти дальше, то если бы я был коммерческим пользователем прокси (например, Cloudflare) и хотел перенаправить (или заблокировать) определённый IP-адрес или доменное имя, я бы настроил (или запросил) у прокси (в данном случае Cloudflare) перенаправление «голового IP-адреса на порту 80» на выбранный мной FQDN (или куда угодно).

Именно такие задачи прокси предназначены для решения (по замыслу); и, как упоминалось, такой тип перенаправления легко реализовать с помощью Apache2 или Nginx, поэтому я предполагаю (не будучи пользователем Cloudflare), что коммерческий сервис, такой как Cloudflare, может легко управлять подобными тривиальными перенаправлениями.

3 лайка

Я использую это для сайта, чтобы перенаправлять ботов, обращающихся к нему по чистому IP, на специальную страницу:

server {
        listen 80;
        # listen [::]:80;

        server_name ~^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+;

        root /var/www/ip-address;
        default_type text/plain;
        index nothing.doing;
        location / {
                try_files $uri /nothing.doing;
        }
}

НО я согласен с другими: я не могу воспроизвести доступ по IP для своего частного форума. Меня перенаправляет. При этом у меня нет специальной конфигурации, нет Cloudflare, и я буквально запускаю виртуальный сервер за 0 долларов в месяц, который не предлагает никаких дополнительных услуг.

3 лайка

Но если подумать, можно понять, что все они работают на сбалансированных по нагрузке системах, размещённых на инфраструктуре стоимостью (десятки) миллионов долларов. Так что они тоже не являются репрезентативными.

При миграции настройки nginx не копируются, поэтому на самом деле это просто новая установка.

2 лайка

Отлично, спасибо за этот фрагмент, @elijah, очень ценю! Я заменю прописанный IP на ваше регулярное выражение или воспользуюсь полным фрагментом. :slight_smile:

2 лайка

Да, это ещё раз подтверждает, что эти сайты, скорее всего, недоступны через веб по любому прямому IP-адресу. В любом случае, никто не поддерживает возможность небезопасного прямого доступа по IP через веб.

Да, вы правы.

1 лайк

Я только что протестировал запуск двух экземпляров Discourse на Digital Ocean с использованием их приложения из маркетплейса для быстрого развёртывания.

Я хотел провести тестирование практически без кастомной конфигурации, просто изменив параметры smtp, dev email и discourse_hostname на вымышленные значения (чтобы разрешить пересборку).

Установщик остановился из-за того, что заданный мной домен/поддомен не прошёл этап проверки домена (и рекомендовал вручную отредактировать файл app.yml, а затем выполнить пересборку).

После редактирования app.yml и пересборки (изменены только smtp, dev email и discourse_hostname) сайт стал доступен небезопасно по IP-адресу без какого-либо участия Cloudflare. Перенаправления на установленный discourse_hostname не происходит.

Большинство моих установок не использовали приложение из маркетплейса Digital Ocean для настройки, а выполнялись вручную по стандартному руководству по установке Docker.

Обратите внимание, что остановка установщика из-за невозможности проверить домен также произошла на двух недавних установках, где использовался Cloudflare, вероятно, из-за проксирования. Остальные установки были выполнены до появления этапа проверки домена в установщике.

редактирование: Обратите внимание, что проблемы с проверкой домена во время начальной установки возникли только на 2 из 8 установок Discourse (не считая двух тестовых экземпляров, созданных выше). Скрипт настройки Discourse предлагает пользователю вручную отредактировать app.yml и выполнить пересборку при ошибке проверки домена. Если это не полезно, это не проблема; для меня это не стало решением.

редактирование: В целом используется гибкий SSL от Cloudflare, а не letsencrypt (что было бы лучше). Спасибо @neounix.

FYI @markersocial

Все наши установки Discourse перенаправляют http://the.ip.add.res на https://FQDN, настроенный через включенный LETSENCRYPT в файле контейнера Discourse .yml.

Для корректной работы всего этого и для того, чтобы сертификаты LETSENCRYPT функционировали, вам необходима полностью рабочая конфигурация SSL (обычно с использованием LETSENCRYPT), как вы, безусловно, уже знаете.

Просто напоминание… надеюсь, это поможет.

2 лайка

Vanilla предполагает наличие действительного домена и использование скрипта настройки Discourse.

Если вы не делаете ни того, ни другого, не стоит удивляться, что результат будет иным.

В этой теме нет никакой полезной информации, и мы не можем воспроизвести проблему, если следовать инструкциям.

7 лайков