Nginx如何實現(xiàn)對城市以及指定IP的訪問限制
1.前言
在如何用Nginx代理MySQL連接,并限制可訪問IP一文中,我們實現(xiàn)了通過Nginx代理MySQL連接,并限制了指定IP才能通過Nginx進行連接,以提高數(shù)據(jù)安全性。
該場景適用于根據(jù)具體的IP地址來進行訪問限制,假如我們要上線一個新的功能,但是只想在某些地區(qū)進行小規(guī)模的測試,就無能為力了。
我們可以通過添加第三方模塊ngx_http_geoip2_module來實現(xiàn),其實Nginx也提供了ngx_http_geoip_module,至于我們?yōu)槭裁床皇褂盟覀兒罄m(xù)揭曉。
2.限制指定IP
我們先來回顧一下,如何通過指定IP來進行訪問限制。
Nginx提供了ngx_http_access_module和ngx_stream_access_module模塊,前者針對http請求,后者針對stream連接,它們的指令非常簡單,僅包含allow和deny指令,唯一區(qū)別就是作用域不同。
我們這里就以ngx_http_access_module模塊為例。
1)allow
該指令設(shè)置指定的IP允許訪問。可以和deny指令配合使用
作用域:http, server, location, limit_except
語法:allow address | CIDR | unix: | all;
示例:
# 允許192.168.110.1訪問 allow 192.168.110.1; # 允許192.168.110.1到192.168.255.254 allow 192.168.110.0/16; # 允許192.168.110.1到192.168.110.254 allow 192.168.110.0/24; # 允許所有的IP訪問 allow all;
2)deny
該指令設(shè)置指定的IP禁止訪問??梢院?code>allow指令配合使用。
作用域:http, server, location, limit_except
語法:deny address | CIDR | unix: | all;
# 禁止192.168.110.1訪問 deny 192.168.110.1; # 禁止192.168.110.1到192.168.255.254 deny 192.168.110.0/16; # 禁止192.168.110.1到192.168.110.254 deny 192.168.110.0/24; # 禁止所有的IP訪問 deny all;
3)配置示例
禁止所有的IP訪問,192.168.110.100除外。
http {
server {
listen 80;
server_name localhost;
allow 192.168.110.100;
deny all;
}
}Tips:如果指定了allow,需要配合deny使用,否則就是允許所有的IP地址訪問。
3.限制國家/城市
前面我們提到了Nginx也提供了ngx_http_geoip_module來實現(xiàn)根據(jù)國家/城市進行訪問限制。
官當(dāng)文檔:https://nginx.org/en/docs/http/ngx_http_geoip_module.html

從上圖可以得知該模塊需要maxmind的數(shù)據(jù)庫,并且格式為.dat,那好,我們來看看maxmind提供的數(shù)據(jù),如下圖:

其格式為.mmdb,與該模塊的數(shù)據(jù)格式不匹配,因此我們使用第三方模塊ngx_http_geoip2_module。
下載地址:https://github.com/leev/ngx_http_geoip2_module/archive/refs/heads/master.zip
3.1 安裝maxminddb library
首先,我們需要安裝用于讀取.mmdb的文件的依賴。
apt install libmaxminddb0 libmaxminddb-dev mmdb-bin
3.2 構(gòu)建模塊
對于添加第三方模塊,我們需要在configure時使用--add-module來實現(xiàn)。
例如:
./configure --sbin-path=/usr/local/nginx/nginx --conf-path=/usr/local/nginx/nginx.conf --pid-path=/usr/local/nginx/nginx.pid --with-stream --add-module=/home/stone/nginx-1.22.1/module/ngx_http_geoip2_module
其余步驟,可參照【Nginx基本命令&不停機版本升級】一文進行,這里不再贅述。
3.3 GEOIP數(shù)據(jù)下載
下載地址(需注冊賬號):https://dev.maxmind.com/geoip/geolite2-free-geolocation-data
國家?guī)欤?/strong>

城市庫:

通過解壓縮得到GeoLite2-Country.mmdb和GeoLite2-City.mmdb數(shù)據(jù)庫文件。
3.4 配置
3.4.1 初體驗
在進行配置之前,我們先通過第一步安裝的依賴庫來體驗一下。
mmdblookup --file /usr/local/nginx/GeoLite2-City.mmdb --ip 183.195.99.161
可以看到,其識別出這是一個來自上海的IP地址。

3.4.2 配置示例
接下來,我們開始配置。
http {
include mime.types;
default_type application/octet-stream;
# 自定義日志格式
log_format geoip '$http_x_forwarded_for_temp - $remote_user [$time_local] - $request - $status - $geoip2_country_name_en - $geoip2_city_name_en';
geoip2 /usr/local/nginx/GeoLite2-Country.mmdb {
auto_reload 5m;
$geoip2_metadata_country_build metadata build_epoch;
$geoip2_country_code source=$http_x_forwarded_for_temp country iso_code;
$geoip2_country_name_en source=$http_x_forwarded_for_temp country names en;
$geoip2_country_name_zh source=$http_x_forwarded_for_temp country names zh-CN;
}
geoip2 /usr/local/nginx/GeoLite2-City.mmdb {
auto_reload 5m;
$geoip2_city_name_en source=$http_x_forwarded_for_temp city names en;
$geoip2_city_name_zh source=$http_x_forwarded_for_temp city names zh-CN;
}
server {
listen 80;
server_name localhost;
access_log logs/geoip.log geoip;
default_type text/html;
# 正則匹配取反
if ($geoip2_city_name_en !~ 'Shanghai'){
return 403 "<h1>Forbidden!</h1><p>You don't have permission to access the URL on this server.</p>";
}
location / {
return 200 '<p>Real IP: $http_x_forwarded_for_temp</p><p>Country: $geoip2_country_name_en</p><p>City: $geoip2_city_name_en</p>';
}
}
}Tips:由于我們這里沒有外網(wǎng)環(huán)境,因此使用$http_x_forwarded_for_temp變量來模擬,只需在請求頭中加入X-Forwarded-For-Temp字段即可。實際環(huán)境還是使用$http_x_forwarded_for變量用來獲取請求的真實IP。
3.4.3 實戰(zhàn)
1)發(fā)起請求,X-Forwarded-For-Temp=183.195.99.161,上海IP,響應(yīng)碼200。

2)發(fā)起請求,X-Forwarded-For-Temp=221.192.127.124,唐山IP,響應(yīng)碼403。

3)日志記錄:

總結(jié)
以上就是Nginx限制可訪問IP的全部內(nèi)容,Nginx是多模塊化的,還有很多高級功能,我們后面繼續(xù)探索。
這些僅為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx如何獲取自定義請求header頭和URL參數(shù)詳解
這篇文章主要給大家介紹了關(guān)于Nginx如何獲取自定義請求header頭和URL參數(shù)的相關(guān)資料,本文適用于需要在nginx里獲取http請求頭信息或者傳遞的參數(shù)進行一些計算和處理的情況,需要的朋友可以參考下2022-07-07
Nginx(PHP/fastcgi)的PATH_INFO問題
PATH_INFO是一個CGI 1.1的標(biāo)準(zhǔn),經(jīng)常用來做為傳參載體. 比如, 我們可以使用PATH_INFO來代替Rewrite來實現(xiàn)偽靜態(tài)頁面, 另外不少PHP框架也使用PATH_INFO來作為路由載體.2011-08-08
WinPC搭建nginx服務(wù)器的實現(xiàn)步驟
本文主要介紹了WinPC搭建nginx服務(wù)器的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01

