0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

IBM Cloud: Red Hat OpenShift on IBM Cloud(ROKS)におけるHAProxyでのX-Forwarded-Forヘッダの取扱い

Last updated at Posted at 2021-09-13

1. はじめに

https://github.com/nin2yasu/samplephp
にあるようなHTTPヘッダ情報を出力するようなPHPアプリを用意して、アプリ側でのHTTPヘッダの中身をチェックしてみた。

2. 事前準備

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

$ oc new-app php~https://github.com/nin2yasu/samplephp

$ oc expose svc samplephp

$ oc get pods -o wide
NAME                         READY   STATUS      RESTARTS   AGE    IP              NODE        NOMINATED NODE   READINESS GATES
samplephp-1-build            0/1     Completed   0          117m   172.17.37.110   10.0.0.19   <none>           <none>
samplephp-55c9fb7f6d-nngnz   1/1     Running     0          116m   172.17.37.122   10.0.0.19   <none>           <none>

$ oc get routes
NAME        HOST/PORT                                                                                                             PATH   SERVICES    PORT       TERMINATION   WILDCARD
samplephp   samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud          samplephp   8080-tcp                 None

対象にcurlでアクセスしてみると、

$ curl http://samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
User-Agent: curl/7.29.0 <br>
Accept: */* <br>
Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Port: 80 <br>
X-Forwarded-Proto: http <br>
Forwarded: for=10.0.0.19;host=samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud;proto=http <br>
X-Forwarded-For: 10.0.0.19 <br>

のようにX-Forwarded-ForがHAProxyによって追加されていることも確認できる。

3. haproxy.configの内容

上記アプリはhaproxy.configで以下のように構成されている。

$ oc exec -it router-default-68b7c6f6c8-9cdpf -n openshift-ingress -- cat /var/lib/haproxy/conf/haproxy.config

(途中略)

# Plain http backend or backend with TLS terminated at the edge or a
# secure backend with re-encryption.
backend be_http:syasuda1:samplephp
  mode http
  option redispatch
  option forwardfor
  balance leastconn

  timeout check 5000ms
  http-request add-header X-Forwarded-Host %[req.hdr(host)]
  http-request add-header X-Forwarded-Port %[dst_port]
  http-request add-header X-Forwarded-Proto http if !{ ssl_fc }
  http-request add-header X-Forwarded-Proto https if { ssl_fc }
  http-request add-header X-Forwarded-Proto-Version h2 if { ssl_fc_alpn -i h2 }
  http-request add-header Forwarded for=%[src];host=%[req.hdr(host)];proto=%[req.hdr(X-Forwarded-Proto)]
  cookie 5444480f934221e15be9da82d28a3823 insert indirect nocache httponly
  server pod:samplephp-55c9fb7f6d-nngnz:samplephp:8080-tcp:172.17.37.122:8080 172.17.37.122:8080 cookie c367f61b069035b158a420307b996c7f weight 256 check inter 5000ms
  • set-headerではなくadd-headerが使われている。よって、上記で指定したヘッダは置換ではなく追記されている。
  • HAProxyのdocsによるとoption forwardforという設定でX-Forwarded-Forヘッダが追加されている。実際、このdocsには以下のように記載されてもいる。

Since this header is always appended at the end of the existing header list

4. tcpdumpを実行して実際のHTTPヘッダを覗いてみる。

IBM Cloud: nsenterを使ったコンテナ上でのデバッグ方法(Red Hat OpenShift on IBM Cloudでの例)および80番ポートのHTTP GET requestの抽出方法を参照してtcpdumpを取得してみる。

4.1 通常アクセスの時

# curl http://samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
User-Agent: curl/7.29.0 <br>
Accept: */* <br>
Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Port: 80 <br>
X-Forwarded-Proto: http <br>
Forwarded: for=10.0.0.19;host=samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud;proto=http <br>
X-Forwarded-For: 10.0.0.19 <br>
tcpdumpによるHTTPリクエストヘッダ(GET)の情報
sh-4.4# nsenter -n -t ${pid} -- tcpdump -i any -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
03:52:45.082552 IP 172.17.37.45.39452 > kube-c3j463dt0o165mnm7be0-privonlysya-default-000005f4.webcache: Flags [P.], seq 2341353716:2341354263, ack 3432626976, win 57, options [nop,nop,TS val 371268340 ecr 371268340], length 547: HTTP: GET / HTTP/1.1
E..W"	@.?.t...%-..%z......8.... ...9.......
.!...!..GET / HTTP/1.1
User-Agent: curl/7.29.0
Accept: */*
Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
X-Forwarded-Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Forwarded: for=10.0.0.19;host=samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud;proto=http
X-Forwarded-For: 10.0.0.19

4.1 X-Forwarded-Forをリクエストヘッダに含めた時(ROKSの前段にReverse Proxyが存在していることを想定)

$ curl http://samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud -H "X-Forwarded-For: 192.168.100.100"
User-Agent: curl/7.29.0 <br>
Accept: */* <br>
X-Forwarded-For: 192.168.100.100, 10.0.0.19 <br>
Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud <br>
X-Forwarded-Port: 80 <br>
X-Forwarded-Proto: http <br>
Forwarded: for=10.0.0.19;host=samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud;proto=http <br>
tcpdumpによるHTTPリクエストヘッダ(GET)の情報
sh-4.4# nsenter -n -t ${pid} -- tcpdump -i any -s 0 -A 'tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420'
dropped privs to tcpdump
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
04:24:56.570989 IP 172.17.37.45.58842 > kube-c3j463dt0o165mnm7be0-privonlysya-default-000005f4.webcache: Flags [P.], seq 3632158659:3632159240, ack 4114263037, win 57, options [nop,nop,TS val 373199828 ecr 373199828], length 581: HTTP: GET / HTTP/1.1
E..y..@.?.....%-..%z.....~W..:.....9.5.....
.>...>..GET / HTTP/1.1
User-Agent: curl/7.29.0
Accept: */*
X-Forwarded-For: 192.168.100.100
Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
X-Forwarded-Host: samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Forwarded: for=10.0.0.19;host=samplephp-syasuda1.privonly-syasuda-roksvpc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-i000.jp-tok.containers.appdomain.cloud;proto=http
X-Forwarded-For: 10.0.0.19

つまり、

X-Forwarded-For: xxx.xxx.xxx.xxx(リクエスト時の情報)
その他の Header
X-Forwarded-For: yyy.yyy.yyy.yyy(HAProxyが追加した情報)
```

という形式で実際はヘッダは付与されている。この2つの`X-Forwarded-For`をどのように取り扱うのかはアプリ側やサーバー側での処理に依存するということなのであろう。PHP+Apacheだと上記の結果のようにマージされて表示されている。







0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?