ay0ks
(ay0ks)
1
您好,我在自己的服务器上部署了 Discourse,一切正常,除了检测用户的 IP 地址。我甚至编写了一个 PHP 脚本(在 Docker 容器外部)来获取所有可能包含 IP 的标头:
REMOTE_ADDR: 212.58.xxx.xxx
SERVER_PORT: 80
SERVER_ADDR: 85.25.xxx.xxx
SERVER_SOFTWARE: Apache:
HTTP_CF_CONNECTING_IP: 212.58.xxx.xxx
HTTP_CDN_LOOP: cloudflare
HTTP_X_REAL_IP: 162.158.xxx.xxx
详细信息:
服务器安装了 BrainyCP 面板,带有 Apache 和 Nginx(目前网站使用 Nginx,它反向代理了 Docker 容器)。
HTTP_CF_CONNECTING_IP 在 Docker 容器内部显示为 127.0.0.1,但在外部它们具有正常值。
在不使用自定义命令更改标头的情况下,Discourse 显示的是服务器的 IP。
(很快会添加更多详细信息,因为我的 Discourse 实例正在重新构建)
MarcP
(MarcP)
2
我不确定你的设置,但注意到你在帖子中提到了 Cloudflare。你是否将 Cloudflare 模板添加到了你的 app.yml 文件中?
- "templates/cloudflare.template.yml"
编辑:使用了错误的“ ”
ay0ks
(ay0ks)
3
不,我已经将其添加到模板列表中,现在正在等待重新构建。
ay0ks
(ay0ks)
4
重建了,但仍然显示服务器 IP(我已经注释掉了自定义命令
## 任何要在构建后运行的自定义命令
run:
- exec: echo "Beginning of custom commands"
## 如果您想为第一次注册设置“发件人”电子邮件地址,请取消注释并更改:
## 获取第一封注册电子邮件后,请重新注释该行。它只需要运行一次。
- exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
#- replace:
# filename: /etc/nginx/conf.d/discourse.conf
# from: "types {"
# to: |
# set_real_ip_from 85.25.134.45;
# real_ip_header CF-Connection-IP;
# real_ip_recursive on;
# types {
#- replace:
# filename: /etc/nginx/conf.d/discourse.conf
# from: $proxy_add_x_forwarded_for
# to: $send_http_cf_connection_ip;
# global: true
- exec: echo "End of custom commands"
我需要取消注释它们吗?(还想注意到,即使在我将 Cloudflare 模板添加到 app.yml 之前,它们也无法正常工作)
ay0ks
(ay0ks)
5
取消注释后,$sent_http_cf_connection_ip 返回 127.0.0.1

Fma965
(Fma965)
6
Nginx 可能正在报告 127.0.0.1,而不是 Discourse 本身,您可能需要在 nginx 中设置 realip
ay0ks
(ay0ks)
7
我已经添加了 cloudflare.template.yml,它添加了 realip 指令,但仍然无效。
我甚至删除了更改为自定义标头的自定义命令,现在 Discourse 会报告所有用户的服务器 IP 而不是 localhost。
ay0ks
(ay0ks)
8
此外,这是面板本身为域名 zeronet.space 生成的 Nginx 配置
server {
listen 85.25.xxx.xx:443 ssl http2;
server_name zeronet.space www.zeronet.space;
root /home/ay0ks/workspace/sites/zeronet.space;
# ssl on;
ssl_certificate /etc/certs/ay0ks/zeronet.space_1655753906.crt;
ssl_certificate_key /etc/certs/ay0ks/zeronet.space_1655753906.key;
#ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
#ssl_ciphers "HIGH:!RC4:!aNULL:!MD5:!kEDH";
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
ssl_ciphers TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:ECDHE:!COMPLEMENTOFDEFAULT;
ssl_prefer_server_ciphers on;
add_header Strict-Transport-Security 'max-age=604800';
access_log /etc/nginx/vhost_logs/zeronet.space_access;
error_log /etc/nginx/vhost_logs/zeronet.space_error;
location ~ /.well-known {
allow all;
}
location ~ /\\.ht {
deny all;
access_log off;
log_not_found off;
}
location / {
root /home/ay0ks/workspace/sites/zeronet.space;
proxy_pass http://85.25.xxx.xx:31080; # Discourse is deployed on ports 31080/31443
proxy_redirect off;
proxy_force_ranges on;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header HTTPS $scheme;
proxy_cache off;
proxy_cache_key "$request_method|$http_if_modified_since|$http_if_none_match|$host|$request_uri";
#access_log /etc/nginx/vhost_logs//home/ay0ks/workspace/sites/zeronet.space;
proxy_cache_valid 3s;
proxy_cache_min_uses 2;
# proxy_cache_lock on;
# proxy_cache_use_stale error timeout;
# proxy_cache_use_stale updating http_502 http_504;
limit_conn lone 100;
# limit_req zone=ltwo burst=10;
client_body_buffer_size 128k;
client_max_body_size 1024m;
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
send_timeout 180;
proxy_buffer_size 4k;
proxy_buffers 8 32k;
proxy_busy_buffers_size 68k;
proxy_temp_file_write_size 10m;
}
# error_page 404 /404.html;
# error_page 500 502 503 504 /50x.html;
}
另外,我想说明一下请求的“路径”:
用户 -> Cloudflare -> 服务器 (Nginx -> Docker -> Discourse)
并请注意,用户的 IP 在 cloudflare 的 CF-Connecting-IP 标头中对于 Docker 外部是可见的
我不太清楚 Cloudflare 真实 IP 的工作原理,但我的猜测是,您的 Discourse nginx 需要将 set_real_ip_from 设置为它看到的代理 nginx 的 IP 地址。是 127.0.0.1 吗?还是其他内部地址?公网地址?不确定它会看到哪个地址。
一旦您知道了该地址,我认为我会保留 cloudflare 模板,然后添加一个新的 replace 仅用于 set_real_ip_from。
除此之外,您的代理 nginx 需要配置为传递 CF-Connecting-IP 标头,如果它尚未配置或默认不传递的话。这部分我帮不了您。
Fma965
(Fma965)
10
和我一样,我的问题是 nginx 没有配置将 docker IP 配置为 realip 的范围。
set_real_ip_from 172.18.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
set_real_ip_from 172.18.0.0/16;
所以我走的是 用户 > Cloudflare > 服务器 Nginx (SWAG Docker) > Discourse
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
## 如果您想添加 Lets Encrypt (https),请取消注释这两行
# - "templates/web.ssl.template.yml"
# - "templates/web.letsencrypt.ssl.template.yml"
# - "templates/web.socketed.template.yml"
- "templates/cloudflare.template.yml"
这可能是您遇到问题的原因。尝试在没有安装任何面板或反向代理的服务器上设置 Discourse,并报告是否遇到相同的问题。
作为第一步,请先修改 Discourse 的 location 块,使其与此处提供的信息匹配:Run other websites on the same machine as Discourse
ay0ks
(ay0ks)
12
那不是一个问题的解决方案,基本上购买一个新的每月 30 欧元的专用服务器可以解决任何问题,哈哈(这样这个帖子就不存在了)。
ay0ks
(ay0ks)
14
是否还需要在 Discourse Nginx 配置(在 Docker 内部)中添加标头?因为仍然显示服务器地址而不是用户地址。
Fma965
(Fma965)
15
根据您的路径,我无法理解。\n\n您的 nginx 指向 discourse 到 docker,为什么您的 discourse 还要使用自己的 nginx?
ay0ks
(ay0ks)
16
不知道,我已经通过面板(也通过 ssh 检查过)将您的 Nginx 指令添加到了我的指令中,但它仍然显示服务器的 IP 地址。
ay0ks
(ay0ks)
17
这是我的 app.yml:
## 这是独立运行的 Discourse Docker 容器模板
##
## 修改此文件后,您必须重建
## /var/discourse/launcher rebuild app
##
## 编辑时请*极其小心*!
## YAML 文件对空格或对齐的错误非常非常敏感!
## 如有需要,请访问 http://www.yamllint.com/ 来验证此文件
templates:
- "templates/postgres.template.yml"
- "templates/redis.template.yml"
- "templates/web.template.yml"
- "templates/web.ratelimited.template.yml"
- "templates/cloudflare.template.yml"
## 如果您想添加 Lets Encrypt (https),请取消注释这两行
#- "templates/web.ssl.template.yml"
#- "templates/web.letsencrypt.ssl.template.yml"
## 此容器应暴露哪些 TCP/IP 端口?
## 如果您希望 Discourse 与 Apache 或 nginx 等其他 Web 服务器共享端口,
## 请参阅 https://meta.discourse.org/t/17247 获取详细信息
expose:
- "31080:80" # http
- "31443:443" # https
params:
db_default_text_search_config: "pg_catalog.russian"
## 将 db_shared_buffers 设置为总内存的最多 25%。
## 将由 bootstrap 根据检测到的 RAM 自动设置,或者您可以覆盖它
db_shared_buffers: "4096MB"
## 可以提高排序性能,但会增加每个连接的内存使用量
#db_work_mem: "40MB"
## 此容器应使用哪个 Git 版本? (默认:tests-passed)
#version: tests-passed
env:
LC_ALL: ru_RU.UTF-8
LANG: ru_RU.UTF-8
LANGUAGE: ru_RU.UTF-8
DISCOURSE_DEFAULT_LOCALE: ru
## 支持多少并发 Web 请求?取决于内存和 CPU 核心。
## 将由 bootstrap 根据检测到的 CPU 自动设置,或者您可以覆盖它
UNICORN_WORKERS: 8
## TODO:此 Discourse 实例将响应的域名
## 必需。Discourse 不能使用纯 IP 地址运行。
DISCOURSE_HOSTNAME: 'zeronet.space'
## 如果您希望容器以与上面指定的相同主机名 (-h 选项) 启动,请取消注释
## (默认值为“$hostname-$config”)
#DOCKER_USE_HOSTNAME: true
## TODO:将成为初始注册管理员和开发人员的逗号分隔的电子邮件列表
## 示例:'user1@example.com,user2@example.com'
DISCOURSE_DEVELOPER_EMAILS: 'contact@zeronet.space'
## TODO:用于验证新帐户和发送通知的 SMTP 邮件服务器
# 需要 SMTP 地址、用户名和密码
# 警告:SMTP 密码中的字符 '#' 可能会导致问题!
DISCOURSE_SMTP_ADDRESS: smtp.zeronet.space
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: noreply@zeronet.space
DISCOURSE_SMTP_PASSWORD: "xxxxxxx"
DISCOURSE_SMTP_ENABLE_START_TLS: true
DISCOURSE_SMTP_AUTHENTICATION: login
DISCOURSE_SMTP_OPENSSL_VERIFY_MODE: none
DISCOURSE_NOTIFICATION_EMAIL: "noreply@zeronet.space"
#DISCOURSE_SMTP_DOMAIN: "zeronet.space"
## 如果您添加了 Lets Encrypt 模板,请取消注释下方以获取免费 SSL 证书
#LETSENCRYPT_ACCOUNT_EMAIL: me@example.com
## 此 Discourse 实例的 HTTP 或 HTTPS CDN 地址 (配置为拉取)
## 请参阅 https://meta.discourse.org/t/14857 获取详细信息
#DISCOURSE_CDN_URL: https://discourse-cdn.example.com
## 用于 IP 地址查找的 maxmind 地理位置 IP 地址密钥
## 请参阅 https://meta.discourse.org/t/-/137387/23 获取详细信息
#DISCOURSE_MAXMIND_LICENSE_KEY: 1234567890123456
## Docker 容器是无状态的;所有数据都存储在 /shared 中
volumes:
- volume:
host: /var/discourse/shared/standalone
guest: /shared
- volume:
host: /var/discourse/shared/standalone/log/var-log
guest: /var/log
## 插件在此处
## 请参阅 https://meta.discourse.org/t/19157 获取详细信息
hooks:
after_code:
- exec:
cd: $home/plugins
cmd:
- git clone https://github.com/discourse/docker_manager.git
## 构建后要运行的任何自定义命令
run:
- exec: echo "开始执行自定义命令"
## 如果您想设置首次注册的“发件人”电子邮件地址,请取消注释并进行更改:
## 在收到首次注册电子邮件后,重新注释该行。它只需要运行一次。
- exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
- exec: echo "自定义命令执行完毕"
ay0ks
(ay0ks)
19
这修复了 IP 检测问题(现在一切正常),但现在有些图片无法加载
编辑:这是一个缓存问题,现在一切正常!谢谢大家!