前言
使用 ngx_http_geoip_module 搭配國家阻擋, 要特別注意的是他和我們常用的 ngx_http_access_module, 是會互相打架的哦. 什麼意思哩? 就是如果比如你把某個國家阻擋掉, 那麼就算你特別配置允許該國家特定 ip allow A.B.C.D
, 也是沒有用的哦, 那整個國家就是被擋在外面啦! 下面我們就來看要怎麼配置阻擋國家和特定白名單吧.
事前準備
測試環境
Ubuntu 14.04 LTS
Ubuntu 16.04 LTS
首先呢, 既然要使用那個模塊, 就必須先確保你的 Nginx 有編譯該模塊. 可以用這個指令查看. nginx -V 2>&1 | grep -o with-http_geoip_module
如果輸出是空白的, 代表你的 Nginx 沒有這個模塊. 那麼恭喜你, 就可以繼續按照本課程繼續下一步. 我的也是熱騰騰編譯進去的, 如果你們的已經如下圖正確顯示, 那請跳到配置部份 ~
要加入這個模塊的話, 就必須從編譯開始. 但是要編譯之前呢, 請先 apt-get install libgeoip-dev
, 這個是 geoip 所需要的函式庫, 如果缺少安裝的話就會有下面錯誤:
configure: error: the GeoIP module requires the GeoIP library. You can either do not enable the module or install the library.
安裝好了就開始編譯吧! 請在 configure
步驟的時候加入 --with-http_geoip_module
,已經開始恍神的同學快到 Ubuntu16.04 從源安裝nginx 惡補一下.
configure
完了之後就是編譯 make
, 跑完之後, 記得先暫停服務 service nginx stop
, 然後安裝 make install
. 最後啟動服務 service nginx start
.
這時候再次執行 nginx -V 2>&1 | grep -o with-http_geoip_module
, 就可以看到已經加入模塊啦!
在配置之前, 還有個最重要的工作, 下載 geoip 的資料庫! 完成了就可以開始配置了.
cd /etc/nginx
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
gunzip GeoIP.dat.gz
配置
請在 /etc/nginx/nginx.conf
裡面的 http
區塊裡面加入這段, 請注意我使用 $remote_addr
這個變數, 如果你們的 Nginx 是躲在 proxy 後面的, 請先參照 Nginx 獲取 CDN X-Forwarded-For, 把表頭的 X-Forwarded-For 替換至 remote_addr. (如果覺的麻煩的話, 解決方法就是用別的變數取代也可以)
# 資料庫位址
geoip_country /etc/nginx/GeoIP.dat;
# 從 $remote_addr 這個變數, 來定義 $ip_whitelist 這個變數
geo $remote_addr $ip_whitelist {
default 0;
1.200.216.57 1;
}
接下來配置一個設定檔 /etc/nginx/conf.d/geoblock.conf
, 內容如下. 這邊配置阻擋了日本, 台灣, 新加坡. 其他的國家代碼可以在 maxmind 網站找到哦.
# 如果是白名單, 就不用繼續看下去了
if ($ip_whitelist = 1) {
break;
}
# 這些國家給他 403
if ($geoip_country_code ~ (JP|TW|SG)) {
return 403;
}
最後一步就是在你的 server
引用進來
server {
listen 80 default_server;
root /usr/share/nginx/html;
index index.html index.htm;
server_name localhost;
# 引用我們的 geoblock 配置
include /etc/nginx/conf.d/geoblock.conf;
location / {
try_files $uri $uri/ =404;
}
}
驗證
依照剛剛的配置, 就是阻擋日本, 台灣, 新加坡; 然後白名單是一個日本IP (118.11.213.239 );
實驗者一號, 日本, 阻擋!
實驗者二號, 新加坡, 阻擋!
實驗者三號, 台灣, 阻擋!
實驗者四號, 日本 白名單, pass!
(嘛, 相信以各位的功力, 這點馬賽克是傷不了你們的眼睛的)
這樣就達成今天的目的啦~ 我們下次見!
尾聲
一個 moment 就把整個國家 block 掉!