9月に入ってしまった。8月は開発者の生活を思い出すための試行錯誤の月だった。よくもわるくもかな。

キャンセル料の支払い

この前の金曜日は しみん福祉スポーツセンター の体育館を借りてバドミントンを行う予定だった。木曜日は戻ってこれない可能性 があったし、前日の天気予報では金曜日の夕方が神戸に台風が来る予報になっていた。そこで木曜日の夜に参加者も少なかったしキャンセルすることに決めた。キャンセルは1週間前でないとできないため、これは自然災害だから仕方がないと体育館のキャンセル料金3,000円を支払うことにした。直接、しみん福祉スポーツセンターの窓口でないと支払いできない。窓口へ行って paypay で支払いしてきた。しみん福祉スポーツセンターの体育館を借りるのは値段が高いので参加者数が増えてから借りる運用を変えようと思う。

X-Forwarded-For ヘッダーの制御

先日の作業の続き 。本当は土曜日にやろうと思っていて、全然やる気がなくて、なにもやらないよりはちょっとでもやった方がよいかと、今日やり始めたら集中できて2-3時間で調査と対応を完了した。もともと構築しているリバースプロキシとしての nginx には次のヘッダーを扱う設定が追加されていた。

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 X-Forwarded-Host $server_name;

追加で remote_addr を置き換える設定を入れてみれば、リバースプロキシ経由でリクエストを受ける go の http Request が参照する RemoteAddr の値も置き換わるのかな?と検証してみた。

set_real_ip_from 172.29.0.0/16;
real_ip_header X-Forwarded-For;
real_ip_recursive on;
proxy_set_header REMOTE_ADDR $remote_addr;

結論としては RemoteAddr の値は置き換わらなかった。nginx の real_ip_header モジュールは nginx 環境における remote_addr の値を変更する設定であり、転送するときにパケットの値を置き換えるものではないようにみえる。そこで api サーバー側で X-Forwarded-For ヘッダーを参照するのが正しい対応方法だと理解できた。このヘッダーを参照することは一般的な用途に思えるので調べたら echo の IP Address のドキュメントにその設定方法やユーティリティの扱いなどが書いてあってすぐに参照できることもわかった。

X-Forwarded-For ヘッダーはクライアントが任意で偽装できる。デフォルトでは内部ネットワークから転送されたヘッダーの値のみを信頼するように設定されている。それが次の IPExtractor の設定になる。デフォルトの制約を変更することもできるが、コンテナで運用するとすべての通信はコンテナネットワークの gateway からリクエストされているようにみえるのでアクセス制御という側面ではこの設定そのものにあまり意味はない。

e := echo.New()
e.IPExtractor = echo.ExtractIPFromXFFHeader()

X-Forwarded-For ヘッダーの値を実際に参照するときは c.Request().RemoteAddr ではなく c.RealIP() を使う。api サーバーはこのぐらいの変更で実際のクライアントから転送されてきた ip アドレスを知ることができた。