DiscourseでユーザーのIPアドレスとしてサーバーIP/localhostが表示される

こんにちは。自身のサーバーにDiscourseをデプロイしましたが、ユーザーのIPアドレスの検出以外はすべて正常に動作しています。IPアドレスを取得できるすべてのヘッダーを取得するために、PHPスクリプト(Dockerコンテナの外)さえ作成しました。

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

詳細:
サーバーには、ApacheとNginxがインストールされたBrainyCPパネルが搭載されています(現在、ウェブサイトはNginxを使用しており、Dockerコンテナにリバースプロキシしています)。
Dockerコンテナ内でHTTP_CF_CONNECTING_IP127.0.0.1を返しますが、外部では通常の値を返します。
カスタムコマンドを使用してヘッダーを変更せずに、DiscourseはサーバーのIPアドレスを表示します。

(Discourseインスタンスが現在再構築中のため、近日中に詳細を追加します)

Cloudflareの設定についてはよくわかりませんが、投稿でCloudflareに気づきました。アプリのymlファイルにCloudflareテンプレートを追加しましたか?

  - "templates/cloudflare.template.yml"

編集:間違った「」を使用しました

いいえ、テンプレートのリストに追加しました。再構築を待っています。

「いいね!」 1

再構築しましたが、まだサーバーIPが表示されます(カスタムコマンドをコメントアウトしました

## ビルド後に実行するカスタムコマンド
run:
  - exec: echo "カスタムコマンドの開始"
  ## 最初の登録の「送信元」メールアドレスを設定したい場合は、コメントを解除して変更してください。
  ## 最初のサインアップメールを取得した後、行を再度コメントアウトしてください。一度だけ実行する必要があります。
  - 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 "カスタムコマンドの終了"

それらをコメント解除する必要がありますか?(Cloudflareテンプレートをapp.ymlに追加する前でも機能しなかったこともお知らせしたいと思います)

コメントアウトされていない場合、$sent_http_cf_connection_ip127.0.0.1 を返します。
image

Nginx は、Discourse 自体ではなく 127.0.0.1 を報告している可能性が高いです。nginx で realip を設定する必要があるでしょう。

cloudflare.template.yml を追加して realip ディレクティブを追加しましたが、まだ機能していません。
カスタムヘッダーに変更するカスタムコマンドを削除したところ、Discourse はすべてのユーザーに対して localhost ではなくサーバー IP を報告するようになりました。

また、これはパネル自体が生成したドメイン 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 はポート 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 でしょうか?それとも別の内部アドレス?公開アドレス?どれを認識するかはわかりません。

それがどの IP アドレスかわかったら、Cloudflare のテンプレートはそのままにして、set_real_ip_from 用に新しい replace を追加するのが良いと思います。

それに加えて、プロキシ nginx が CF-Connecting-IP ヘッダーを渡すように設定されているか、またはデフォルトで渡すように設定されていない場合は、そのように設定する必要があります。この部分についてはあまりお手伝いできません。

私も同じような状況でした。私の問題は、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"
## Uncomment these two lines if you wish to add Lets Encrypt (https)
#  - "templates/web.ssl.template.yml"
#  - "templates/web.letsencrypt.ssl.template.yml"
#  - "templates/web.socketed.template.yml"
  - "templates/cloudflare.template.yml"
「いいね!」 4

これが問題の原因である可能性があります。パネルやリバースプロキシがインストールされていないサーバーにDiscourseをセットアップし、同じ問題が発生するかどうか報告してください。

最初のステップとして、Discourseのlocationブロックを、Run other websites on the same machine as Discourse

「いいね!」 1

それは問題の解決策ではありません。基本的に、月額30ユーロの新しい専用サーバーを購入すれば、すべてが解決します(このスレッドは存在しなくなります)。

結果はこちらに投稿します

Discourse Nginx 設定にもヘッダーを追加する必要がありますか? (Docker内) なぜなら、まだユーザーの代わりにサーバーのアドレスが表示されるからです。

そのパスでは意味がわかりません。

NginxがDockerのDiscourseに接続しているのに、Discourseが独自のNginxを使用する理由は何ですか?

わかりません。パネルからNginxディレクティブを自分のものに追加しましたが(SSHからも確認しました)、サーバーのIPが表示され続けます。

これは私の 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"
## Let's Encrypt (https) を追加したい場合は、これらの 2 行のコメントを解除してください
  #- "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% に設定します。
  ## ブートストラップによって検出された 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 コアに依存します。
  ## ブートストラップによって検出された 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"

  ## Let's 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 アドレスルックアップ用の MaxMindGeolocation 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 "カスタムコマンドの開始"
  ## 初回登録時の「From」メールアドレスを設定したい場合は、コメントを解除して変更してください:
  ## 初回サインアップメールを受信したら、行を再度コメントアウトしてください。一度だけ実行する必要があります。
  - exec: rails r "SiteSetting.notification_email='noreply@zeronet.space'"
  - exec: echo "カスタムコマンドの終了"

回答は上記でリンクされています。このようなものが必要です。

「いいね!」 4

これにより、IP検出の問題が修正されました(すべて正常に動作するようになりました)が、一部の画像が読み込まれなくなりました。

編集:これはキャッシュの問題でした。すべて正常に動作しています!皆さん、ありがとうございました!

「いいね!」 2

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.