AWS App RunnerでクライアントIPを取得する方法を調査する
AWS App Runnerだと現状AWS WAFは適用できないため、IPフィルタリング設定をかけたい場合アプリ側で実装する必要あり
WAFサポートは、ロードマップにあり、👍も多いためじきに対応されると思う
Go + echoのパターンはこちらの記事が参考になる
go-chiで試してみる。RealIPミドルウェアを使ってみる
ベースのリポジトリはこちら
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)
...
}
# ローカルホストから送信
$ curl -H -XGET localhost:8080/tasks
# r.RemoteAddrの出力結果
"[::1]:62028"
# ローカルホストから送信
$ 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"
👆より、RealIPミドルウェアは、X-Forwarded-For
を見てRealIPを判定しているように見える。ネットワーク層のREMOTE_ADDRを見ていない。この実装だと偽装が容易でフィルタ設定はできない。
別の方法を考える必要あり。
ここら辺の記事が参考になる
この問題に近いissueがあった
App Runner構成なら単に req.RemoteAddr
を見て単に判定すればいい気がしてきたので、ログを追加してApp Runner上にデプロイ
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分くらいかかる模様
X-Forwarded-For
も出力するようにしてみる
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アドレス
👆より、App Runnerの前段にいると思われるLBは、X-Forwarded-For
ヘッダーにIPを追記してくれることが分かる。
App Runnerの前段が多段プロキシではない場合、IPフィルタ設定をする場合は、X-Forwarded-For
一番右側のIPを判定すれば良いことになる。
App Runnerのremote_addr
には前段のLB(推測)のIPが入り、X-Forwarded-For
を追記してくれるという挙動が確認できた。
AWS App RunnerでクライアントIPを取得する方法が分かったためクローズ。