使用nginx 限制不受允许的ip访问

2020-05-19 18:18:57   工作备份

 

需求如下:在没有公网ip的情况下,不部署vpn,尽可能简单的

nignx配置

  1. server
  2. {
  3. listen 80;
  4. server_name *.*.*.*;
  5. index index.php index.html index.htm default.php default.htm default.html;
  6. root ****;
  7. #SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则
  8. #error_page 404/404.html;
  9. #SSL-END
  10. #ERROR-PAGE-START 错误页配置,可以注释、删除或修改
  11. #error_page 404 /404.html;
  12. #error_page 502 /502.html;
  13. #ERROR-PAGE-END
  14. #PHP-INFO-START PHP引用配置,可以注释或修改
  15. include enable-php-70.conf;
  16. #PHP-INFO-END
  17. #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效
  18. include /www/server/panel/vhost/rewrite/www.cyyw.com.conf;
  19. #REWRITE-END
  20. #禁止访问的文件或目录
  21. location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md)
  22. {
  23. return 404;
  24. }
  25. #一键申请SSL证书验证目录相关设置
  26. location ~ \.well-known{
  27. allow all;
  28. }
  29. location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
  30. {
  31. expires 30d;
  32. error_log off;
  33. access_log /dev/null;
  34. }
  35. location ~ .*\.(js|css)?$
  36. {
  37. expires 12h;
  38. error_log off;
  39. access_log /dev/null;
  40. }
  41. access_log /www/wwwlogs/www.cyyw.com.log;
  42. error_log /www/wwwlogs/www.cyyw.com.error.log;
  43. }

伪静态配置

  1. location / {
  2. try_files $uri $uri/ /index.php$is_args$query_string;
  3. #以下是ip白名单
  4. include /www/wwwroot/allow_ip/allow_ip.conf;
  5. deny all;
  6. }

服务端程序

  1. <?php
  2. /**
  3. * created by zhang
  4. */
  5. header("content-type:text/html;charset=utf-8");
  6. error_reporting(E_ALL|E_STRICT);
  7. ini_set("display_errors",'1');
  8. date_default_timezone_set("PRC");
  9. $data = json_decode(file_get_contents('php://input'), true);
  10. $from_ip = getIp();
  11. if(!isset($data['time']) && !isset($data['token'])){
  12. returnMsg($from_ip,403,"param error!");
  13. }
  14. $secret = "自定义的秘钥";
  15. $file = "./allow_ip.conf";
  16. if(checkToken($data['time'],$secret,$data['token'])){
  17. $origin = file_exists($file);
  18. if(!$origin){
  19. //创建文件
  20. file_put_contents("allow_ip.conf","");
  21. }
  22. if(is_writable($file)){
  23. //读取原本文件内容
  24. $ip_info = explode(';',str_replace(PHP_EOL,"",file_get_contents($file)));
  25. if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/",$from_ip)){
  26. $new_add = "allow ".$from_ip;
  27. if($ip_info){
  28. if(in_array($new_add,$ip_info)) returnMsg($from_ip,"200",'existed already!');
  29. }
  30. array_push($ip_info,$new_add);
  31. $ip_info = array_filter(array_unique($ip_info));
  32. $open_files = fopen($file,'w+');
  33. $string = "";
  34. foreach ($ip_info as $k=>$value){
  35. if(!empty($value)){
  36. $ip = trim($value);
  37. $string.=$ip.";".PHP_EOL;
  38. }
  39. }
  40. fwrite($open_files,$string);
  41. fclose($open_files);
  42. $result = shell_exec("sudo nginx -s reload");
  43. returnMsg($from_ip,200,"add complete ".$result);
  44. }
  45. returnMsg($from_ip,"200","IP address is not correct");
  46. }else{
  47. returnMsg($from_ip,"500","file is not writable");
  48. }
  49. }else{
  50. returnMsg($from_ip,'403',"token is not right!");
  51. }
  52. /**
  53. * 访问日志
  54. * @param $ip
  55. * @param $result
  56. */
  57. function recordLog($ip,$result){
  58. $now_time = date("Y-m-d H:i:s");
  59. $file = "./log/access_log_".date("Y-m-d").".log";
  60. if(!file_exists("./log")){
  61. mkdir("./log");
  62. }
  63. $dir = opendir("./log");
  64. while(($f1 = readdir($dir)) !== false){
  65. if($f1 != "." && $f1 != ".." && !is_dir($f1)){
  66. preg_match("/\d{4}-\d{2}-\d{2}/",basename($f1,'.log'),$create_time);
  67. if(isset($create_time[0]) && $time = $create_time[0]){
  68. if(mktime(0,0,0,date("m"),date("d"),date("Y"))-strtotime($time) >= 4*86400){
  69. unlink("./log/".$f1);
  70. };
  71. }
  72. }
  73. }
  74. closedir($dir);
  75. $log = fopen($file,'a+');
  76. $content = $now_time.":ip -> ".$ip." accessed,result ->".$result.PHP_EOL;
  77. fwrite($log,$content);
  78. fclose($log);
  79. }
  80. /**
  81. * 前台响应函数
  82. * @param $ip
  83. * @param $code
  84. * @param $message
  85. */
  86. function returnMsg($ip,$code,$message){
  87. echo json_encode(array(
  88. 'error'=>$message,
  89. 'code'=>$code
  90. ));
  91. recordLog($ip,$message);
  92. die();
  93. }
  94. /**
  95. * 获取用户IP
  96. * @return array|false|string
  97. */
  98. function getIp(){
  99. global $_SERVER;
  100. if (getenv('HTTP_CLIENT_IP')) {
  101. $ip = getenv('HTTP_CLIENT_IP');
  102. } else if (getenv('HTTP_X_FORWARDED_FOR')) {
  103. $ip = getenv('HTTP_X_FORWARDED_FOR');
  104. } else if (getenv('REMOTE_ADDR')) {
  105. $ip = getenv('REMOTE_ADDR');
  106. } else {
  107. $ip = $_SERVER['REMOTE_ADDR'];
  108. }
  109. return $ip;
  110. }
  111. /**
  112. * token验证
  113. * @param $time
  114. * @param $secret
  115. * @param $ip
  116. * @param $from_token
  117. * @return bool
  118. */
  119. function checkToken($time,$secret,$from_token){
  120. $origin_token = sha1(md5($time).md5($secret));
  121. return $origin_token === $from_token?true:false;
  122. }

客户端程序

  1. <?php
  2. /**
  3. * created by zhang
  4. */
  5. header("content-type:text/html;charset=utf-8");
  6. $destination = "服务端访问地址";
  7. $time = time();
  8. $secret = "约定好的访问秘钥";
  9. $data = json_encode(array(
  10. 'time'=>$time,
  11. 'token'=>sha1(md5($time).md5($secret))
  12. ));
  13. $curl = curl_init();
  14. curl_setopt_array($curl, array(
  15. CURLOPT_PORT => "约定好的访问端口",
  16. CURLOPT_URL => $destination,
  17. CURLOPT_RETURNTRANSFER => true,
  18. CURLOPT_ENCODING => "",
  19. CURLOPT_MAXREDIRS => 10,
  20. CURLOPT_TIMEOUT => 30,
  21. CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  22. CURLOPT_CUSTOMREQUEST => "POST",
  23. CURLOPT_POSTFIELDS => $data,
  24. CURLOPT_HTTPHEADER => array(
  25. "content-type: application/json",
  26. ),
  27. ));
  28. $response = curl_exec($curl);
  29. $err = curl_error($curl);
  30. curl_close($curl);
  31. if ($err) {
  32. echo "cURL Error #:" . $err;
  33. } else {
  34. echo $response;
  35. }

配置客户端定时任务,服务端就会将客户端的ip地址自动写入ip白名单中,并限制未经授权的ip地址访问