LoginSignup
5
7

More than 5 years have passed since last update.

NGINXで特定の接続元IPのアクセスを制限する

Last updated at Posted at 2018-01-13

NGINXで特定の接続元IPのアクセスを制限します。
本番公開後、クローラのIPが動的に変更されない場合は必要になるかもしれません。
検証はdocker-composeで実施します。

 単純な流量制限

httpディレクティブにlimit_req_zoneを追加

http {
    #流量制限を追加
    limit_req_zone $binary_remote_addr zone=limit_req_by_ip:10m rate=50r/s;
    limit_req_log_level error;
    limit_req_status 503;

locationディレクティブに上記を設定し、ロケーション毎に制限を適応する

    location / {
        #制限なし
    }

    location /limit/ {
        #秒間50を超えたリクエストは503を返す
        limit_req zone=limit_req_by_ip burst=50 nodelay;
    }

 接続元IPでフィルタ

blacklist.confを準備

blacklist.conf
  limit_req zone=limit_req_limited burst=1;

  if ($remote_addr ~ " ?172\.20\.0\.4$" ) { set $limit_req_key $binary_remote_addr; } #ブラックリストのIPは遅延実行する
  if ($http_x_forwarded_for ~ " ?172\.20\.0\.4$" ) { set $limit_req_key $binary_remote_addr; } #ブラックリストのIPは遅延実行する

以下を参考に設定を実施しました。
Nginx の limit_req/limit_conn を特定の条件でのみ適用する/しない - Qiita

ロケーション毎に制限を適応する

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /limit/ {
        include /etc/nginx/conf.d/blacklist.conf; #blacklist設定をlocation毎に設定 -> 一部APIの許可のみ制限するなど
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

参考ソースコード

設定検証

  • コンテナ起動
bash
$ git clone https://github.com/Thirosue/docker-sample.git
$ cd docker-sample/nginx/
$ docker-compose up -d
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
4e25f9baf911        httpd:alpine        "httpd-foreground"       3 seconds ago       Up 4 seconds        80/tcp                 ab1
04343e39793c        httpd:alpine        "httpd-foreground"       3 seconds ago       Up 5 seconds        80/tcp                 ab2
f61bb508287c        nginx_limit         "nginx -g 'daemon of…"   3 seconds ago       Up 5 seconds        0.0.0.0:8080->80/tcp   nginx_limit
  • すべてのコンテナに入り、疎通及び接続元IP確認

ab1/ab2コンテナに入り、ab実行

bash
$ docker exec -ti ab1 /bin/ash
/usr/local/apache2 # ab -n 1 -c 1 http://nginx/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking nginx (be patient).....done


Server Software:        nginx/1.13.1
Server Hostname:        nginx
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      1
Time taken for tests:   0.000 seconds
Complete requests:      1
Failed requests:        0
Total transferred:      845 bytes
HTML transferred:       612 bytes
Requests per second:    2785.52 [#/sec] (mean)
Time per request:       0.359 [ms] (mean)
Time per request:       0.359 [ms] (mean, across all concurrent requests)
Transfer rate:          2298.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.0      0       0
Processing:     0    0   0.0      0       0
Waiting:        0    0   0.0      0       0
Total:          0    0   0.0      0       0

nginx_limitコンテナに入り、access.logを参照し、接続元IPを確認

bash
$ docker exec -ti nginx_limit /bin/ash
/ # tail -f /var/log/nginx/access.log
172.20.0.4 - - [13/Jan/2018:06:59:12 +0000] "GET / HTTP/1.0" 200 612 "-" "ApacheBench/2.3" "-"
172.20.0.3 - - [13/Jan/2018:06:59:22 +0000] "GET / HTTP/1.0" 200 612 "-" "ApacheBench/2.3" "-"

流量制限対象のIPからの接続確認

  • 遅延実行対象パスへのアクセスがエラーとなっていないことを確認
  • 遅延実行対象パスへのアクセスがエラー(503)となっていることを確認
bash
$ docker exec -ti ab1 /bin/ash
#対象IPからの流量制限対象外パスへのアクセス
/usr/local/apache2 # ab -n 10 -c 10 http://nginx/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking nginx (be patient).....done


Server Software:        nginx/1.13.1
Server Hostname:        nginx
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      10
Time taken for tests:   0.002 seconds
Complete requests:      10
Failed requests:        0 ######################### <------------------------------------ Fail=0
Total transferred:      8450 bytes
HTML transferred:       6120 bytes
Requests per second:    4280.82 [#/sec] (mean)
Time per request:       2.336 [ms] (mean)
Time per request:       0.234 [ms] (mean, across all concurrent requests)
Transfer rate:          3532.51 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      1       1
Processing:     0    1   0.4      1       1
Waiting:        0    1   0.4      1       1
Total:          1    1   0.2      1       2
ERROR: The median and mean for the initial connection time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      2
  80%      2
  90%      2
  95%      2
  98%      2
  99%      2
 100%      2 (longest request)

#対象IPからの流量制限対象パスへのアクセス
/usr/local/apache2 # ab -n 10 -c 10 http://nginx/limit/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking nginx (be patient).....done


Server Software:        nginx/1.13.1
Server Hostname:        nginx
Server Port:            80

Document Path:          /limit/
Document Length:        29 bytes

Concurrency Level:      10
Time taken for tests:   0.503 seconds
Complete requests:      10
Failed requests:        8 ######################### <------------------------------------ 3回目以降のアクセスが想定通りFailedとなっている
   (Connect: 0, Receive: 0, Length: 8, Exceptions: 0)
Non-2xx responses:      8
Total transferred:      6368 bytes
HTML transferred:       4354 bytes
Requests per second:    19.90 [#/sec] (mean)
Time per request:       502.620 [ms] (mean)
Time per request:       50.262 [ms] (mean, across all concurrent requests)
Transfer rate:          12.37 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        1    1   0.1      1       1
Processing:     1   51 158.4      1     501
Waiting:        0   51 158.4      1     501
Total:          1   52 158.4      2     502

Percentage of the requests served within a certain time (ms)
  50%      2
  66%      2
  75%      2
  80%      2
  90%    502
  95%    502
  98%    502
  99%    502
 100%    502 (longest request)

流量制限対象のIPからの接続確認

  • 対象外IPからの遅延実行対象パスへのアクセスがエラーとなっていないことを確認
  • 対象外IPからの遅延実行対象パスへのアクセスがエラーとなっていないことを確認
bash
$ $ docker exec -ti ab2 /bin/ash
#対象外IPからの流量制限外対象パスへのアクセス
/usr/local/apache2 # ab -n 10 -c 10 http://nginx/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking nginx (be patient).....done


Server Software:        nginx/1.13.1
Server Hostname:        nginx
Server Port:            80

Document Path:          /
Document Length:        612 bytes

Concurrency Level:      10
Time taken for tests:   0.002 seconds
Complete requests:      10
Failed requests:        0 ######################### <------------------------------------ Fail=0
Total transferred:      8450 bytes
HTML transferred:       6120 bytes
Requests per second:    5425.94 [#/sec] (mean)
Time per request:       1.843 [ms] (mean)
Time per request:       0.184 [ms] (mean, across all concurrent requests)
Transfer rate:          4477.46 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.2      1       1
Processing:     0    1   0.2      1       1
Waiting:        0    0   0.2      1       1
Total:          1    1   0.0      1       1
ERROR: The median and mean for the initial connection time are more than twice the standard
       deviation apart. These results are NOT reliable.
ERROR: The median and mean for the waiting time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%      1 (longest request)

#対象外IPからの流量制限対象パスへのアクセス
/usr/local/apache2 # ab -n 10 -c 10 http://nginx/limit/
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking nginx (be patient).....done


Server Software:        nginx/1.13.1
Server Hostname:        nginx
Server Port:            80

Document Path:          /limit/
Document Length:        29 bytes

Concurrency Level:      10
Time taken for tests:   0.002 seconds
Complete requests:      10
Failed requests:        0 ######################### <------------------------------------ Fail=0
Total transferred:      2600 bytes
HTML transferred:       290 bytes
Requests per second:    5330.49 [#/sec] (mean)
Time per request:       1.876 [ms] (mean)
Time per request:       0.188 [ms] (mean, across all concurrent requests)
Transfer rate:          1353.44 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.1      0       1
Processing:     0    1   0.2      1       1
Waiting:        0    1   0.2      1       1
Total:          1    1   0.1      1       1
ERROR: The median and mean for the initial connection time are more than twice the standard
       deviation apart. These results are NOT reliable.

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%      1 (longest request)
5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7