Nginx 阻擋國家並且配置白名單

前言

使用 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 掉!