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

投稿 2022年7月17日

更新 2022年7月17日

専門用語の数:

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

~ 目次 ~

ハマったこと

解決方法

Dockerアクセスの仕組み

X-Forwarded-Forとは?

ロードバランサも同じ

まとめ

ハマったこと

サーバ構成

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って便利なようで、案外使いにくい部分もあるのだなと感じました。

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


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

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

コメント一覧

コメントがまだありません

コメントを投稿してみる

コメント(必須※500文字以内)

お名前(必須※30文字以内)

※日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)