Closed9

AWS App RunnerでクライアントIPを取得する方法を調査する

shuntakashuntaka

go-chiで試してみる。RealIPミドルウェアを使ってみる

ベースのリポジトリはこちら
https://github.com/shuntaka9576/go_api_sqlite

import (
         ...
         "github.com/go-chi/chi/v5/middleware"
         ...
)

func NewMux(ctx context.Context, cfg *config.Config) (http.Handler, func(), error) {
	mux := chi.NewRouter()
	mux := chi.NewRouter()
	mux.Use(middleware.RealIP) // 👈 RealIPミドルウェアを利用
        ...
func (lt *ListTask) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	pp.Println(r.RemoteAddr)
...
}
X-Forwarded-Forヘッダなし
# ローカルホストから送信
$ curl -H -XGET localhost:8080/tasks

# r.RemoteAddrの出力結果
"[::1]:62028"
X-Forwarded-Forヘッダあり
# ローカルホストから送信
$ curl -H 'X-Forwarded-For: 127.0.0.1' -XGET localhost:8080/tasks

# r.RemoteAddrの出力結果
"127.0.0.1"

$ curl -H 'X-Forwarded-For: 8.8.8.8' -XGET localhost:8080/tasks

# r.RemoteAddrの出力結果
"8.8.8.8"
shuntakashuntaka

App Runner構成なら単に req.RemoteAddr を見て単に判定すればいい気がしてきたので、ログを追加してApp Runner上にデプロイ

https://github.com/shuntaka9576/go_api_sqlite/commit/661b4bc659c91628c93b01ef8b5aa546926d71f2

func (lt *ListTask) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	log.Printf("RemoteAddr: %s\n", r.RemoteAddr)
...

結果

VPN経由でもなしでも移動体でも、169.2xx.1xx.2xx:51260の単一IPからリクエストが来ていることがわかった。(勿論X-Forwarded-Forを偽装してもおなじ)
恐らくこれはApp Runner上にホスティングされているコンテナの前段にLBがいる可能性がありそう

メモ

AppRunnerコンテナのリデプロイに大体7分くらいかかる模様

shuntakashuntaka

X-Forwarded-For も出力するようにしてみる

https://github.com/shuntaka9576/go_api_sqlite/commit/efadc613d76e883cb3ae7218231a1a2ff563b336

func (lt *ListTask) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := r.Context()
	log.Printf("RemoteAddr: %s\n", r.RemoteAddr)

	fwdAddress := r.Header.Get("X-Forwarded-For")
	if fwdAddress != "" {
		ips := strings.Split(fwdAddress, ", ")

		for i, ip := range ips {
			log.Printf("X-Forwarded-For[%d]: %s", i, ip)
		}
	}
       ...

結果

XFF偽装なし

コマンド
curl -H -XGET https://[見せられないよ].ap-northeast-1.awsapprunner.com/tasks
出力
2022/08/06 22:41:38 RemoteAddr: 169.2xx.1xx.2xx:34480
2022/08/06 22:41:38 X-Forwarded-For[0]: 自宅のIPアドレス

XFF偽装あり

コマンド
curl -H 'X-Forwarded-For: 8.8.8.8' -XGET https://[見せられないよ].ap-northeast-1.awsapprunner.com/tasks
出力
2022/08/06 22:52:37 RemoteAddr: 169.254.175.249:60148
2022/08/06 22:52:37 X-Forwarded-For[0]: 8.8.8.8
2022/08/06 22:52:37 X-Forwarded-For[1]: 自宅のIPアドレス
shuntakashuntaka

👆より、App Runnerの前段にいると思われるLBは、X-Forwarded-ForヘッダーにIPを追記してくれることが分かる。
App Runnerの前段が多段プロキシではない場合、IPフィルタ設定をする場合は、X-Forwarded-For一番右側のIPを判定すれば良いことになる。

shuntakashuntaka

App Runnerのremote_addrには前段のLB(推測)のIPが入り、X-Forwarded-Forを追記してくれるという挙動が確認できた。
AWS App RunnerでクライアントIPを取得する方法が分かったためクローズ。

このスクラップは2022/08/07にクローズされました