设置Nginx禁止某些地区IP的访问

闲来无事就去玩一下Nginx

大概两年前,我刚开始接触Python,最先的练手项目就是爬虫.当然那个时候还没有找到一本关于这个话题的书籍,所以就到网络上找相关 的博客,其中找到了一个叫fuckbilibili的网站,现在应该是没了.它有一段时间是可以直接访问的,后面就直接451了.忘了在哪他们说了 为什么451,还有给出了Nginx的配置.那个时候我还没接触Nginx呢,觉得很高深.在昨天的时候,不知道为什么会想这个,于是就有折腾一下 的想法,折腾过后发现其实不难.

最终的效果,判断客户端IP决定是否禁止它访问,非真实IP,也就是所对于使用了代理的用户还是暂时没有办法.如果这不是你想要的效果 的话那就节省自己的时间吧.

我的折腾环境

假定你有一定的Ngnix使用经验下,你还可能会用这些的资料,

操作步骤

ngnix -V                        # 检查里面有没有 --with-http_geoip_module,没有就是没有支持这个模块了
if ! [ -d /usr/share/geoip ]; then mkdir /usr/share/geoip && \
cd - && \
wget http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz && \
gunzip GeoIP.dat.gz ; fi
geoip_country /usr/share/geoip/GeoIP.dat; # 配置geoip数据库,就是指定数据库的路径而已
map $geoip_country_code $allowed_country {
    default yes; # 默认情况下,allowed_country会赋值为yes
    CN no;       # geoip_country_code为CN时,allowed_country会赋值为no;
    US no;       # 同CN
}
server {
  listen 80 default_server;
  server_name star.yourdomain.com *.yourdomain.com;
  root /path/to/project;
  error_page 404 errors/404.html;
  access_log logs/star.yourdomain.com.access.log;
  index index.html;
  location ~ /test/(.*) {
       proxy_pass http://127.0.0.1:1080/$1
  }
 }

你可以在里面加入判断的配置,最后如下

server {
  listen 80 default_server;
  server_name star.yourdomain.com *.yourdomain.com;
  root /path/to/project;
  error_page 404 errors/404.html;
  access_log logs/star.yourdomain.com.access.log;

  if ($allowed_country = no) {
       return 502;              # 可以改成你想要的返回码或者页面,等等
  }

  index index.html;
  location ~ /test/(.*) {
       proxy_pass http://127.0.0.1:1080/$1
  }
 }

重启Nginx后如果有来自中国和美国的IP进行访问,就会给他们返回502页面(自己测试的时候有可能有因为某些原因显示不了, 我遇到过两种情况,其中一种是浏览器缓存,可以对浏览器Ctrl+F5解决,另外一种就比较难以说明,应该是本地访问的缘故吧). 注意,你也可以针对一个location level来进行判断,把插入的代码放到location level就可以了.总之注意context就好.

最后,看吧,挺简单的对吧,不过我在开头也说了,这种配置方法是搞不定用了梯子的访问者,所以以后我还可能还会再写一篇 可以检测真实IP的方法.这种配置除了可以过滤掉一部分IP外,也可以用来针对不同的地区提供不同的服务,还有很多别的其他 用途,看你的决定了.

Author: saltb0rn (asche34@outlook.com)

Date: 2018-07-04

Emacs 28.2 (Org mode 9.5.5)

Validate