ヘッダー画像

Docker内Webサーバでアクセス元IPアドレスを取得する方法

投稿 2022年7月17日 最終更新 2022年7月17日 専門用語多め

ハマったこと

サーバ構成

DockerでApacheを起動していたシンプルな構成でした。

ロードバランサなども導入せず、Apacheへ直接アクセスする環境です。

アクセス元IPアドレスが取れない

上記環境でApacheのログにアクセス元IPを出力したい。

しかし誰がアクセスしても、同じIPアドレスになってしまいました。

解決方法

リバースプロキシ配置

Dockerの外側にリバースプロキシを配置し、
アクセス元IPアドレスを連携することです。

私の場合は「nginx」を、ロードバランサとして配置しました。

アクセスの流れでいうと、nginx(Docker外)からApache(Docker内)となります。

そのnginxに以下の設定をしました。

# ロードバランサ

upstream loadbalancer {
  # Apacheへ接続
  server 127.0.0.1:8080;
}

server {
  # 開放ポート番号
  listen 443 ssl;
  listen [::]:443 ssl;

  # その他設定省略

  location / {
    # ロードバランサへ接続
    proxy_pass http://loadbalancer;
    # IPアドレスを連携
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    # ポート番号を連携
    proxy_set_header X-Forwarded-Port $server_port;
  }
}

nginxでは「$proxy_add_x_forwarded_for」という変数に、
アクセス元IPアドレスが格納されています。

そのIPアドレスを「X-Forwarded-For」という

HTTPヘッダに保存するという設定です。

Apacheで取得

Apacheでの受け取り方を以下のように変更しました。

LogFormat "%{%Y.%m.%d %H:%M:%S}t|%a" commonAccessLogFormat

↓↓↓

LogFormat "%{%Y.%m.%d %H:%M:%S}t|%{X-Forwarded-For}i" commonAccessLogFormat

「%a」が通常IPアドレスになりますが、今回はそれで取得できないため、
「%{X-Forwarded-For}i」でnginxで設定したIPアドレスを取得します。

Dockerアクセスの仕組み

私も詳しくは理解していませんが、簡単に言うと、
Docker内のコンテナにアクセスする際、
Docker自体のネットワークにアクセスしてから、各コンテナにアクセス

という流れになっています。

そのため、アクセス元IPアドレスを取得しようとすると、
DockerネットワークのIPアドレスになってしまっていた、、、
というのが原因でした。

アクセス元IPを取りたければ、Dockerにアクセスする前に保存する必要がある

ということで、Dockerの外側にリバースプロキシを配置したということです。

X-Forwarded-Forとは?

通称XFFとも呼ばれる「X-Forwarded-For」

こいつはいったい何者かというと、
アクセス元IPアドレスを特定するためにある、
HTTPヘッダのデファクトスタンダードです。

そのほかにも、似たようなものでいうと以下のようなものがあります。

項目 設定値
IPアドレス X-Forwarded-For
ポート番号 X-Forwarded-Port
ホスト X-Forwarded-Host
プロトコル X-Forwarded-Proto

ロードバランサも同じ

Dockerに限らずにロードバランサなど、アクセスしてくるまでに
何かしらのサーバを挟んで(経由して)いる場合は、同じ現象になります。

ロードバランサの管理画面があるなら、XFFを使用するか
みたいな設定があるはず・・・?(私は持ってないのでわかりませんが)

なければ今回みたいに、サーバ設定を直接いじってみましょう。

まとめ

Dockerって便利なようで、案外使いにくい部分もあるのだなと感じました。

ついでにロードバランサの勉強も兼ねれたので、よかったです。

以上、ここまで見ていただきありがとうございます。

皆さまの快適な開発ライフに、ほんの少しでもお役に立てれば幸いです。

コメント

この記事のコメントはありません。