Cloudfront + ELB 限制 IP 問題及解法

啊遠
verybuy-dev
Published in
3 min readSep 22, 2017

環境:

OS: centos 7
web server: Apache/2.4.6

問題說明:

staging environment 的網站要限制特定 ip 可存取

原架構:

外部 IP -> AWS ELB -> time out (504)
公司 IP -> AWS ELB -> EC2 INSTANCE -> OK

原本的做法是在 AWS 設定 ELB 的 security group

但是加上 cloudfront 之後,來源 ip 都是 cloudfront 的 ip

因為 ELB 的 security group 無法以原始 ip 做為限制條件

所以必須改用 apache 來做 ip 控管

新架構:

外部 IP -> CloudFront -> AWS ELB -> EC2 INSTANCE -> Apahce -> forbiddne (403)
公司 IP -> CloudFront ->AWS ELB -> EC2 INSTANCE -> Apache -> OK

Google 到在 apache 做 ip 限制的解法

<Directory "/var/html/www">
Require ip 1.2.3.4
</Directory>

但是怎麼嘗試都沒有用,後來才發現來源的 ip 是 ELB 的 ip

而不是我們公司的 ip ,所以怎麼試都是失敗

求救後的解法是需要判斷 request header 內的 X-Forwarded-For 裡面是否有我們允許的 ip

Google 後得到的解法是要先把 X-Forwarded-For 設定成 env

再 Require env 即可

範例

SetEnvIf X-Forwarded-For 1.2.3.4 staging_environment
Require env staging_environment

SetEnvIf 是第一次看到,看了官方文件的說明

Sets environment variables based on attributes of the request

以我的理解是
第一個參數我們要比對的參數
第二個是正規比對式
第三個是結果

所以當第三個參數回傳是 true 時,會 Require env true
代表這次的請求是可以過的

PS.
X-Forwarded-For 裡面是有兩組 ip
第一組是真實來源 ip
第二組是 CloudFront 的 ip

參考來源:
https://stackoverflow.com/questions/38685646/apache-access-control-to-ips-x-forwarded-for-or-valid-user
https://httpd.apache.org/docs/2.4/en/mod/mod_setenvif.html

--

--