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

2025.11.04

【AWS】[PrivateLink]PrivateLink接続元の情報をWEBサーバ側で取得する

はじめに

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

Proxy Protocol

何ぞやという感じですが、以下みたいな感じみたいです。詳しくはここを見てほしい。

clip-20240614235644.png

検証してみる

こんな感じの構成でやってみました。

clip-20240615000516.png

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だけは忘れずに有効化してください。

clip-20240615000728 (1).png

結果


[root@CompanyA-VM ~]# ip a
1: lo:  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:  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:  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:  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:  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:  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

clip-20240615002837.png

記事一覧に戻る