ログインのロックとかで、アクセス元のIPを知りたいときってあるじゃないですか。
で、ASP.NET_Coreってなんていうか、ちょっとググっても全然欲しい情報に出会えなかっったりするので、備忘として。
環境
AWSで、ELB=>nginx=>app
nginxの設定
最低限、XFFは設定しとく
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
C#側
で、大体.netcore RemoteIp とかでググるとStackOverflowとかで
var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
使えだとか、
いやいや、ミドルウェアに
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor |
ForwardedHeaders.XForwardedProto
});
が必要だよとか言われるんだけど、それでもうまくいかなかったんだよね。
で、fargeteで構築してたので、いちいちちょっとした修正してみて、codecommitにpushしてパイプライン回してとかやっているととても手間だったので、ローカルでこんな環境を作って確認
nginx(elbの代わり)=>nginx=>app
version: '2'
services:
nginxelb:
build:
context: nginx
ports:
- "50001:80"
links:
- nginx
nginx:
build:
context: nginx
ports:
- "50002:80"
links:
- app
app:
build:
context: .
ports:
- "50003:5000"
以下のようなIpになってると仮定する
host : 172.18.0.1
nginxelb: 172.18.0.2
nginx:172.18.0.3
app:172.18.0.4
で、この状況でappのどっかでlogにrequest.HttpContext.Connection.RemoteIpAddressを吐くと、
- nginxelbからアクセス(localhost:50001)
remoteip:172.18.0.3
2.nginxからアクセス(localhost:50002)
remoteip:172.18.0.3
3.appに直接アクセス(localhost:50003)
remoteip:172.18.0.1
ってなるじゃん。
172.18.0.1が欲しいわけじゃん。でないじゃん。
requestのXFFがどうなってるか見ると
- [172.18.0.0.1,172.18.0.0.2,172.18.0.0.3]
- [172.18.0.0.1,172.18.0.0.3]
- null
ってなってるじゃん。
気付くよね。あ、そうか一番右の値使ってるんだって。公式ドキュメントにもそう書いてるし
とすると後はもう単純な話なんですけど、middlewareにknownとして指定すればいいって結論になるわけです。
services.Configure<ForwardedHeadersOptions>(options =>
{
options.ForwardedHeaders =
ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.All;
options.ForwardLimit = 5;
options.KnownProxies.Add(IPAddress.Parse("172.18.0.2"));
options.KnownProxies.Add(IPAddress.Parse("172.18.0.3"));
});
こうするとようやくmiddlewareがちゃんと?機能してくれるわけで、remoteIp取りに行くとちゃんと172.18.0.1が出ます。
ちゃんとっていうか、僕が無能というか。
あとは、AWS上でやる場合はこんなポイント絞ったプロキシなんてありえないので、ネットワークとして
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("XXX.XX.XXX.XXX"), XX));
とかやって。自分のVPCのCIDRをセットしてあげると、うれしい。となります。
やったね!