前言
公司项目已经处于试运行阶段,项目有安全需求,只能部分指定人员可以访问项目地址。考虑到管控方便,这里是通过nginx的ip限制实现该需求。
问题
nginx可以配置ip,指定的ip访问项目。其配置如图
location / {
allow 133.129.174.99;
deny all;
}
该配置表示只允许 133.129.174.99 可以访问项目。其他ip均返回403
由于试运行阶段,访问系统的人员存在变动,每次增加或者减少ip限制,都需要去修改nginx的配置文件。然后重启nginx。
另外存在多个项目均需要执行相同的限制。依次修改,相当繁琐。而且容易操作失误。
因此期望编写一个脚本,来完成该工作。提供效率。
解决过程
1、确定脚本的名词、选项、参数。
脚本名称 设置为 allowIp.sh
选项有 -add 和-delete 分别表示增加ip和移除ip
支持缩写-a 代表 -add 、-d 代表-delete
参数则就是 ip地址。
2、编写脚本。
该版本在centos7正常运行。
#!/bin/bash
#添加ip到nginx配置中。确保可以访问。
#-add 表示增加 -a
#-delete 表示减去 -d
#
#$1表示获取脚本的第一个参数。 -n 表示是否为空
while [[ -n "$1" ]]; do
case "$1" in
-a | -add )
param="$2"
echo "allow ip $param"
#先删除再添加。避免出现同ip有2条配置。
sed -i '/^allow.*'$param';$/d' 'test.cnf'
sed -i 's/deny all;/allow '$param';\n&/' 'test.cnf'
#移动参数。每执行1次,则位于第一个参数的被删除。
shift;;
-d | -delete)
param="$2"
echo "delete ip $param"
#删除指定的ip配置。
sed -i '/^allow.*'$param';$/d' 'test.cnf'
shift;;
--) shift
break ;;
#输入的选项不存在。
*)
echo "$1 is not an option";;
esac
shift
done
# #重启nginx 。我的nginx是位于容器,重启容器需要root权限。
# echo "root密码"|sudo -S docker restart ngxing容器的名字
- 测试脚本。
测试配置文件test.cnf如下。
location / {
root /www;
index index.html index.htm;
allow 143.139.174.99;
deny all;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
将2个文件放在同一目录下。
allowIp.sh 和 test.cnf
赋予allowIp.sh可执行权限。
chmod +x allowIp.sh
然后运行
./allowIp.sh -a 127.0.0.1 -d 143.139.174.99
再检查test.cnf即可发现文件被改变。
遇到的坑
该问题只出现在mac环境下。由于我使用mac编写脚本,在本地测试的时候,遇到一些问题。
- 该脚本在mac上执行时报错:sed: 1: "test.cnf": undefined label 'est.cnf'
解决方案:增加一个备份的追加名,例如.bak
【sed -i '.bak' '/^allow.'param';/d' 'test.cnf'】
原因:mac强制要求备份,否则报错。
如果不想产生备份。可以置空。
【sed -i '' '/^allow.'param';/d' 'test.cnf'】 - 该脚本在mac上执行后,所添加的ip没有换行。
解决方案:替换\n 为 '$\n
原因: mac上的sed版本是BSD版本。而linux的sed是GNU版本。二者对换行的定义不同。
可以通过如下命令查看版本
man sed
//或者
sed --version
image.png
image.png
最终在mac上可执行的版本如下:
#!/bin/bash
#添加ip到nginx配置中。确保可以访问。
#-add 表示增加 -a
#-delete 表示减去 -d
#
#$1表示获取脚本的第一个参数。 -n 表示是否为空
while [[ -n "$1" ]]; do
case "$1" in
-a | -add )
param="$2"
echo "allow ip $param"
#先删除再添加。避免出现同ip有2条配置。
sed -i '.bak' '/^allow.*'$param';$/d' 'test.cnf'
sed -i '.bak' 's/deny all;/allow '$param';\'$'\n&/' 'test.cnf'
#移动参数。每执行1次,则位于第一个参数的被删除。
shift;;
-d | -delete)
param="$2"
echo "delete ip $param"
#删除指定的ip配置。
sed -i '.bak' '/^allow.*'$param';$/d' 'test.cnf'
shift;;
--) shift
break ;;
#输入的选项不存在。
*)
echo "$1 is not an option";;
esac
shift
done
# #重启nginx 。我的nginx是位于容器,重启容器需要root权限。
# echo "root密码"|sudo -S docker restart ngxing容器的名字
批量修改nginx配置文件。
上面只是对一个文件进行了操作。实际项目中,我配置了多个项目。均需要相同的ip限制。
因此多个文件批量修改只需要替换
'test.cnf' 修改为 'xxx目录下/*.cnf'
这里记得使用绝对路径。相对路径的话,如果你移动了脚本的位置则会出现找不到文件的情况。
最后
当前的脚本只能在所在目录执行。切换到其他目录无法执行。
这里可以修改环境变量path实现任意位置执行编写的脚本。
通过修改.bashrc文件:
vim ~/.bashrc
//在最后一行添上:
export PATH=你的脚本存储目录:$PATH
生效方法:(有以下两种)
1、关闭当前终端窗口,重新打开一个新终端窗口就能生效
2、输入“source ~/.bashrc”命令,立即生效
有效期限:永久有效
用户局限:仅对当前用户
此时就可以随意目录下执行你编写的脚本了。
allowIp.sh -d 11 -a 22
网友评论