Установка Discourse на домашнем интернете с помощью Cloudflare Tunnel

Привет, @Falco, доходит ли до тебя в логах nginx реальный IP (который предоставляет Cloudflare через заголовок CF-Connecting-IP)? У меня нет — я вижу только IP cloudflared.

Думаю, нужно сделать одно или оба из следующих действий (после расследования вернусь с уточнениями):

  • добавить в конфигурацию nginx строку set_real_ip_from для IP cloudflared. Если проблема именно в этом, то, вероятно, ни одна из остальных строк set_real_ip_from (предоставленных в templates/cloudflare.template.yml) не нужна пользователям argotunnel. В таком случае, возможно, стоит добавить отдельный шаблон для argotunnel в репозиторий Docker, который будет брать IP cloudflared из переменной окружения или из твоего основного файла app.yml.
  • исправить log_format. Хотя, думаю, это, скорее всего, не проблема. подтверждено: не требуется

Редактирование:

Вот что я делаю, чтобы это заработало:

Не используй шаблон Cloudflare — в этом нет смысла.
Вместо этого добавь следующее в свой app.yml:

hooks:
  after_web_config:
    - file:
        path: /etc/nginx/conf.d/cloudflare_tunnel_real_ip.conf
        contents: |
          # Восстанавливаем оригинальные IP посетителей (ngx_http_realip_module)
          set_real_ip_from 10.100.20.200/32; # твой диапазон IP cloudflared/argotunnel
          real_ip_header CF-Connecting-IP;

Кстати, это автоматически попадает в контекст http в nginx, что вполне уместно.

P.S. На мой взгляд, для чистоты кода шаблон Cloudflare должен также генерировать свою конфигурацию nginx в отдельный файл, а не использовать sed -i для добавления её в /etc/nginx/conf.d/discourse.conf.

1 лайк

Да, @shyguy, я следую шагам, мистер @Falco. Да, я в туннеле. Раньше я получал защиту от DDoS от Cloudflare. DDoS-атака заставляла мой сервер сильно загружать процессор. В логе доступа было 20 МБ, и я видел только IP-адрес моего Docker. Я бросил вызов посетителю по пути URL /, чтобы защитить сервер, но истёкший кэш вызывал ошибку Discourse.



У меня возникла та же проблема, что и на сайте Falco: при DDoS-атаке нагрузка на процессор возрастает.

2 лайка

@shyguy, где я могу получить этот диапазон IP-адресов? Извините за вопрос.

А как насчет этого?.. Я должен выполнить эту команду внутри или снаружи контейнера?

1 лайк

На всякий случай, если было неясно, мой пост там касался только исправления логирования nginx.

Если вы не исправите это, все запросы в логах nginx будут выглядеть так, будто они исходят с одного IP-адреса (вашего cloudflared), а не с реальных IP-адресов клиентов.

Этот IP-адрес (или диапазон IP-адресов) — тот, с которого ваш cloudflared подключается к Discourse, поэтому это зависит от вашей конфигурации. Один из способов убедиться — посмотреть в файл логов nginx и взять оттуда IP-адрес, а затем добавить к нему /32.

Если вы следуете его руководству буквально, я предполагаю, что это 127.0.0.1/32.

Нет, это было просто предложение для шаблона cloudflare.template.yml, который вам не следует использовать в данной конфигурации.

Просто следуйте его руководству в первом посте, но проигнорируйте шаг добавления этого шаблона в вашу конфигурацию. Вместо этого добавьте хук, который я предоставил.

1 лайк

Я следовал вашей инструкции по настройке, но это не сработало.

[27/May/2023:15:49:45 +0000] "sub.domain.ltd" 172.17.0.1 "POST /
[27/May/2023:15:49:45 +0000] "sub.domain.ltd" 172.17.0.1 "POST /
[27/May/2023:15:49:46 +0000] "sub.domain.ltd" 172.17.0.1 "GET /chat
[27/May/2023:15:49:46 +0000] "sub.domain.ltd" 172.17.0.1 "POST /message-bus
[27/May/2023:15:49:54 +0000] "sub.domain.ltd" 172.17.0.1 "POST /message-bus/

hooks:
  after_web_config:
    - file:
        path: /etc/nginx/conf.d/cloudflare_tunnel_real_ip.conf
        contents: |
          # восстановить оригинальные IP-адреса посетителей (ngx_http_realip_module)
          set_real_ip_from 172.17.0.1/32; # ваш диапазон IP-адресов cloudflared/argotunnel
          real_ip_header CF-Connecting-IP;

Где я ошибся? Пожалуйста, помогите @shyguy

Обидно. Для меня всё выглядит правильно, так что я не уверен, в чём проблема.

Вот как это должно работать:

  • прокси Cloudflare добавляет заголовок CF-Connecting-IP, содержащий IP-адрес клиента
  • nginx в Discourse скомпилирован с модулем ngx_http_realip_module — программным обеспечением, которое читает этот заголовок и исправляет логи и прочее, чтобы отображать реальный IP-адрес клиента
  • set_real_ip_from включает эту функцию для подключений из указанных диапазонов IP-адресов. Обычно это диапазоны IP-адресов Cloudflare (предоставляемые шаблоном cloudflare.template.yml), но так как вы используете argotunnel, вам нужно указать IP-адрес argotunnel.

Попробуйте отключить мой хук. Видите ли вы тот же IP-адрес в логах nginx до и после?


Вероятно, единственное различие в наших настройках заключается в том, что я запускаю argotunnel (cloudflared) в Docker.

Если вы хотите попробовать…

Я создал сеть специально для cloudflared:

docker network create --subnet 10.200.10.0/24 cf_tunnel

Вот файл compose:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    command: tunnel run
    restart: unless-stopped
    networks:
      wan:
      cf_tunnel:
        # для ngx_http_realip_module
        # установите высокий IP, чтобы Docker, скорее всего, не назначил
        # этот IP другому контейнеру, если он запустится раньше cloudflared
        ipv4_address: 10.200.10.200 # это IP для `set_real_ip_from` в nginx

    volumes:
      # должно принадлежать uid:gid 65532:65532
      - ./conf:/home/nonroot/.cloudflared

networks:
  cf_tunnel:
    external: true # просто означает сеть, не управляемую compose

# для производительности:
# https://github.com/quic-go/quic-go/wiki/UDP-Receive-Buffer-Size
# sudo nano /etc/sysctl.conf
  # добавьте эту строку:
  # net.core.rmem_max=2500000
  # (мое старое значение было 212992 — проверьте его командой: sudo sysctl net.core.rmem_max)

Вы можете перенести свой конфиг/сертификат в эту папку conf (не забудьте выполнить chown, как указано в примечании в файле compose) или просто пройти процедуру настройки заново. Вы можете запускать команды cloudflared для входа в систему или других действий вот так:

docker run -it --rm -v /path/to/conf:/home/nonroot/.cloudflared cloudflare/cloudflared:latest ВАША_КОМАНДА_ЗДЕСЬ

Затем вам нужно подключить ваш контейнер Discourse к этой сети. Это можно сделать, добавив следующее в конец вашего файла конфигурации контейнера:

docker_args:
  - '--network=cf_tunnel' # опционально, здесь также можно задать статический IP
1 лайк

У кого-нибудь получилось настроить контейнер входящей почты Discourse через туннель Cloudflare?

Раньше у меня возникали проблемы с настройкой другого почтового сервера за туннелем Cloudflare, но приложения на моём Raspberry Pi, использующие порты 80 и 443, работают без проблем.

Я уже много раз устанавливал Discourse на серверы, поэтому пока не особо беспокоюсь о основном контейнере Discourse.

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

Спасибо.

Я почти уверен, что туннель Cloudflare предназначен только для веб-трафика и не поддерживает другие порты.

Это подтверждает мою точку зрения: https://community.cloudflare.com/t/can-i-create-a-mail-server-with-cloudflare-tunnel/386089

2 лайка

Я пользовался сервисом Argo. Я отказался от него, когда заплатил 28 евро за первый месяц. Разница действительно составляла не менее 200 мс. Однако я отменил подписку, потому что не мог позволить себе платить 28 евро каждый месяц ради 200 мс. Учтите, что на крупных сайтах расходы будут выше.

На сайте 800–1000 уникальных посетителей в месяц. Вы можете рассчитать расходы accordingly.

1 лайк

Кроме того, с тех пор как я начал использовать tunnel, загрузка медиафайлов стала проблемой или практически невозможной.
Загрузка обычно проходит нормально, но затем я получаю эту ошибку:

При запуске apt-get update возникла следующая ошибка

Вам нужна 64-разрядная операционная система :sweat_smile:

Вот в чём дело, lol, это 64-битная система. Но я разобрался. Я выполнил apt-get upgrade, перезапустил службу Cloudflare, и загрузка прошла. Также знаешь ли ты, ограничивает ли Cloudflare загрузку видео через туннель? У меня возникли проблемы с загрузкой видео размером около 20 МБ, хотя раньше такого не было.

Я настроил туннель Cloudflare, и он также активен:

Однако во время установки постоянно возникает ошибка, что Discourse не может достичь домена.
Я указал DISCOURSE_FORCE_HTTPS: true в файле App.yml.

Однако я не отменял установку вручную — она была автоматически прервана до того, как я успел изменить App.yml. Может ли это быть причиной ошибки?

1 лайк

То же самое, @Tobiasp, ты уже исправил? Если да, то как? Спасибо

1 лайк

У меня есть публичный IP-адрес, и я использовал его для установки. Затем я установил Cloudflare Tunnel.

1 лайк

Можешь прислать мне свои настройки и прочее, а также рассказать, как ты это сделал? Спасибо!

1 лайк

И просто чтобы всё и решения были в одном месте:

4 лайка

При следовании руководству нас просят выбрать: подключать сеть или приложение. Что из этого следует выбрать?

1 лайк