インフラエンジニアの隙間時間 Infrastructure Engineer's Spare Time

はじめに
外部AWSアカウントとPrivateLink接続を使用すると、送信元IPアドレスがすべて同じになってしまうという問題がある。
複数のNLBを作成して、IPアドレスを変えるという手もあるが、金額的にも設計・構築の手間的にも、
運用的にもうれしい設計ではない。
こんな状態になったとき、ProxyProtocolという存在を知ったので共有します。
補足ですが、PrivateLink本当に高いです。一時間で7ドル(執筆時で1,101円)くらいとられます。
こんな検証はやるべきではありません。会社の環境を使用しましょう。
会社の環境は守るべきルールがあるから、自由に破壊活動ができない!!という変わった意思をお持ちの方は個人で頑張りましょう。そうです。私は後者です。
Proxy Protocol
何ぞやという感じですが、以下みたいな感じみたいです。詳しくはここを見てくれ。
検証してみる
こんな感じの構成でやってみました。

WEBサーバーにはNGINXを選択しました。理由は検索したら一番上にProxy Protocolの設定が出てきたからです。
構築方法は、ここ見てください。一応変更点だけ書いておく。
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'$proxy_protocol_addr - $remote_user [$time_local] ';-----------> ログを出力するように変更
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
types_hash_max_size 4096;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
server {
listen 0.0.0.0:80 proxy_protocol; -----------> ProxyProtocolを追加
そのほかは適当に構築してください。
PrivateLinkの作成方法がわからないよって人はここ見てください。
ターゲットグループのProxy Protocolだけは忘れずに有効化してください。

結果
[root@CompanyA-VM ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000
link/ether 06:ce:4f:36:2a:4d brd ff:ff:ff:ff:ff:ff
altname eni-0ce3df91ea28146ba
altname device-number-0
inet 10.0.128.121/24 metric 512 brd 10.0.128.255 scope global dynamic enX0
valid_lft 1268sec preferred_lft 1268sec
inet6 fe80::4ce:4fff:fe36:2a4d/64 scope link
valid_lft forever preferred_lft forever
[ec2-user@CompanyB-VM ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000
link/ether 06:d2:1b:ec:f1:8d brd ff:ff:ff:ff:ff:ff
altname eni-06eaff365b1e8a220
altname device-number-0
inet 10.10.128.136/24 metric 512 brd 10.10.128.255 scope global dynamic enX0
valid_lft 3158sec preferred_lft 3158sec
inet6 fe80::4d2:1bff:feec:f18d/64 scope link
valid_lft forever preferred_lft forever
[ec2-user@CompanyB-VM ~]$
[ec2-user@CompanyC-VM ~]$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host noprefixroute
valid_lft forever preferred_lft forever
2: enX0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9001 qdisc fq_codel state UP group default qlen 1000
link/ether 06:17:67:92:ba:b1 brd ff:ff:ff:ff:ff:ff
altname eni-0485d4e3eb8a3f21b
altname device-number-0
inet 10.100.128.193/24 metric 512 brd 10.100.128.255 scope global dynamic enX0
valid_lft 3162sec preferred_lft 3162sec
inet6 fe80::417:67ff:fe92:bab1/64 scope link
valid_lft forever preferred_lft forever
[ec2-user@CompanyC-VM ~]$
CompanyB、CでCurl実行
ドメインはそれぞれ生成されたやつ使ってください。
[ec2-user@CompanyC-VM ~]$ curl http://vpce-0fee89bea86be6614-1eymsu6s.vpce-svc-0dd13df5841165527.ap-northeast-1.vpce.amazonaws.com
---
[ec2-user@CompanyB-VM ~]$ curl http://vpce-0ccc08029e7962fdf-1v5yhyws.vpce-svc-0dd13df5841165527.ap-northeast-1.vpce.amazonaws.com
結果はこんな感じで送信元アドレスが同一の値だが、クライアントのIPアドレスが取得できる。
10.0.15.124 - - [14/Jun/2024:15:13:02 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-"10.100.128.193 - - [14/Jun/2024:15:13:02 +0000]
10.0.15.124 - - [14/Jun/2024:15:13:09 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-"10.10.128.136 - - [14/Jun/2024:15:13:09 +0000]
追加
正直PrivateLink越しに送信元の実IPアドレスが取得できても、重複している可能性等を考慮すると、
あんまりうれしくない。
ほんとはPrivateLink毎、接続元ごとに知りたいというのが本音。
わかっています。Amazonにはすべて御見通しです。
nginx.conf へ"$proxy_protocol_tlv_0xEA"を追記すると。。。
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'
'"$proxy_protocol_addr" - "$proxy_protocol_tlv_0xEA" '; --------->"$proxy_protocol_tlv_0xEA"を追記
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
エンドポイントIDが取得できた。
これはうれしい!
10.0.15.124 - - [14/Jun/2024:15:27:27 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-""10.100.128.193" - "\x01vpce-0fee89bea86be6614"
10.0.15.124 - - [14/Jun/2024:15:27:28 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-""10.10.128.136" - "\x01vpce-0ccc08029e7962fdf
