ããã«ã¡ã¯ãã¤ã³ãã©ãã¼ã ã®é島ã§ãã
æè¿ãcybozu.com ã¯ãã¼ããã©ã³ãµã Apache ãã nginx ã«ç½®ãæãã¾ããã (åè: cybozu.com ã®ãªãã¼ã¹ãããã·ã nginx ã«ãªãã¬ã¤ã¹)
ç½®ãæãã®ä¸ç°ã¨ãã¦ãApache ã«å®è£ ãã¦ãã DoS 対çã®ä»çµã¿ã nginx ã®æ¡å¼µã¢ã¸ã¥ã¼ã«ã«ããå½¢ã§ç§»æ¤ãã¾ãããä»åããã®æ¡å¼µã¢ã¸ã¥ã¼ã« nginx-maxconn-module ã OSS ã¨ãã¦å ¬éãã¾ããã®ã§ç´¹ä»ãã¾ãã
- èæ¯
- DoS 対ç
- ç§éãªã¯ã¨ã¹ãæ° v.s. ç¬éåæãªã¯ã¨ã¹ãæ°
- å®è£ æ¹é
- nginx-maxconn-module
- ãããã«
èæ¯
æ¬é¡ã«å ¥ãåã«ãcybozu.com ã«ããã¦ãHTTP ãªã¯ã¨ã¹ããã©ã®ããã«å¦çããã¦ãããã説æãã¾ãã cybozu.com ã§ã¯ãè² è·åæ£ã®ããã«å¤æ°ã®ããã¯ã¨ã³ããµã¼ãã«ãªã¯ã¨ã¹ããå²ãæ¯ã£ã¦ãã¾ãã ããã§ããããã¯ã¨ã³ããµã¼ãã¯ãå®éã«ã¯ AP ãµã¼ãã DB ãµã¼ããªã©ã«åå²ããã¦ãã¾ãããä»åã®è©±ã®æ¬çã¨ã¯é¢ä¿ããªãã®ã§ããã®å³ã§ã¯ï¼å°ã®ãµã¼ãã¨ãã¦æ¸ãã¦ãã¾ãã
DoS 対ç
cybozu.com ã§ã¯ããã«ãããã³ãæ¹å¼ããæ¡ç¨ãã¦ãã¾ãã ã¤ã¾ããä¸ã¤ã®ããã¯ã¨ã³ããè¤æ°ã®ã客æ§ã§å ±æãã¦ãã¾ãã å³ã§ã¯ããââ³â¡æ ªå¼ä¼ç¤¾ãã¨ãÃ÷ï¼æ ªå¼ä¼ç¤¾ããåããµã¼ã Backend-1 ã使ã£ã¦ãã¾ãã ãããããã§ãââ³â¡æ ªå¼ä¼ç¤¾ããï¼DoS æ»æãèªåããã°ã©ã ã®æ´èµ°ãªã©ã«ããï¼å¤§éã¢ã¯ã»ã¹ã cybozu.com ã«è¡ããBackend-1 ããã¦ã³ãã¦ãã¾ã£ãå ´åããÃ÷ï¼æ ªå¼ä¼ç¤¾ãããµã¼ãã¹ãå©ç¨ã§ããªããªã£ã¦ãã¾ãã¾ãã ãããã£ã¦ãããã客æ§ã®ç°å¢ã«å¯¾ãã大éã¢ã¯ã»ã¹ããã£ãã¨ãã«ãä»ã®ã客æ§ã®ç°å¢ã¾ã§å·»ãè¾¼ã¾ãã¦ãã¾ããã¨ãé²ãä»çµã¿ãå¿ è¦ã§ãã
ããã§ã以ä¸ã®ãããªä»çµã¿ãç¨æãã¾ããã
- ã客æ§æ¯ ã«åæãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ãããã
- ãããããã客æ§ã®ç°å¢ã«å¯¾ãã¦äºã決ããããä¸éãè¶ ããåæãªã¯ã¨ã¹ããæ¥ãã¨ãã¯ããã®ã客æ§ã®ã¢ã¯ã»ã¹ã ãé®æããã
大éã¢ã¯ã»ã¹ããã¦ããã客æ§ã ããé®æãã¦ããã以å¤ã®ã¢ã¯ã»ã¹ã¯ãã®ã¾ã¾éããã¨ãéè¦ã§ãã
ç§éãªã¯ã¨ã¹ãæ° v.s. ç¬éåæãªã¯ã¨ã¹ãæ°
ãªã¯ã¨ã¹ãæ°ãå¶éããæ¹æ³ã¨ãã¦ã¯ãç§éãªã¯ã¨ã¹ãæ°ãå¶éããæ¹æ³ã¨ç¬éåæãªã¯ã¨ã¹ããå¶éããæ¹æ³ãããã¾ããä¾ãã°ãnginx ãæ¨æºã§æã£ã¦ãã limit_req ãã£ã¬ã¯ãã£ãã¯ç§éãªã¯ã¨ã¹ãæ°ã§å¶éãããã¦ãã¾ãã ä¸æ¹ãcybozu.com ã§ã¯ç¬éåæãªã¯ã¨ã¹ãæ°ã«å¯¾ãã¦å¶éãããããã¨ã«ãã¾ããã ããã¯ãã¢ã¯ã»ã¹ãã URL ã«ãã£ã¦ã¬ã¹ãã³ã¹æéãç°ãªãããã§ãã
ä¸ç¬ã§ã¬ã¹ãã³ã¹ãè¿ããã㪠URL ã§ããã°å¥ã«å¤§éã«ã¢ã¯ã»ã¹ããã¦ã大ããªåé¡ã«ã¯ãªãã¾ãããã巨大ãªãã¼ã¿ãä½ã£ã¦è¿ããããªéãã URL ã¸ã®ã¢ã¯ã»ã¹ã¯ãããã¾ã§ã®é«é »åº¦ã§ãªãã¦ã DoS ã«ãªããã¨ãããã¾ãã ç¬éåæãªã¯ã¨ã¹ãæ°ã«å¯¾ãã¦å¶éãããã¦ããã°ãã¬ã¹ãã³ã¹ãéãã¦ãé ãã¦ãæ£ããå¶éãæ¸ãããã¨ãã§ãã¾ãã
å®è£ æ¹é
ç¬éåæãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ããããã®ã§ããªã¯ã¨ã¹ããæ¥ãæã«ã«ã¦ã³ã¿ãã«ã¦ã³ãã¢ãããã¦ãã¬ã¹ãã³ã¹ãè¿ããå¾ã®ã«ã¦ã³ããã¦ã³ããã°ããããã§ãã åé¡ã¯ã誰 ããªã¯ã¨ã¹ããã«ã¦ã³ããããã¨ãããã¨ã§ãã
ã²ã¨ã¤ç®ã®é¸æè¢ã¯ nginx ã®ã¯ã¼ã«ã¼ããã»ã¹ãããããåæãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ãããæ¹æ³ã§ãã ãã®æ¹æ³ã ã¨ã¯ã¼ã«ã¼ããã»ã¹ã®ã¡ã¢ãªã ãã§å¦çãå®çµããã®ã§å®è£ ãé常ã«æ¥½ã§ãããå®éã«éç¨ããã«ã¯ããããã¨åé¡ãããã¾ãã ç¹ã«ã¯ã¼ã«ã¼ããã»ã¹æ°ã¯ãã¼ããã©ã³ãµã®ã¯ã©ã¹ã¿å ¨ä½ã§æ°ç¾ã«ä¸ãããããããã 1 ãªã¯ã¨ã¹ãã«å¶éãã¦ãããã¯ã¨ã³ãã«ã¯ãããªãã®åæãªã¯ã¨ã¹ããè¡ã£ã¦ãã¾ãã¾ãããéã«éã®æªãã¯ã©ã¤ã¢ã³ãããã¾ãã¾ä¸ã¤ã®ã¯ã¼ã«ã¼ããã»ã¹ã«ï¼ã³ãã¯ã·ã§ã³å¼µã£ã¦ãã¾ãã¨ãªã¯ã¨ã¹ããå¼¾ããã¦ãã¾ãã¾ãã ãããã£ã¦ãnginx ã®ã¯ã¼ã«ã¼ããã»ã¹ã§ã«ã¦ã³ãããã¨ããé¸æè¢ã¯å´ä¸ãã¾ããã
ãµãã¤ç®ã®é¸æè¢ã¯ LB ã®ãã¹ãåä½ã§å ±æã¡ã¢ãªãååä»ããã¤ããªã©ã使ã£ã¦ã«ã¦ã³ããå ±æããæ¹æ³ã§ãã ããã¯ãlimit_req ãªã©ã® nginx ã®æ¨æºçãªãã£ã¬ã¯ãã£ãããã£ã¦ããæ¹æ³ã§ãããã¾ãã ã¯ã¼ã«ã¼ããã»ã¹ã§ã«ã¦ã³ãããæ¹æ³ã¨æ¯ã¹ãã¨ã¯ã¼ã«ã¼ããã»ã¹æ°ã®å½±é¿ãåããªãããããã便å©ã§ããããã¼ããã©ã³ãµã¯ä¸å°ã§ã¯ãªãããããã£ã±ãã«ã¦ã³ããã主ä½ãè¤æ°ããç¶æ ã«ã¯ãªã£ã¦ãã¾ãã¾ãã ããã«ããã¼ããã©ã³ãµã®æ°ã¯ãåèµ·åã®éç¨ãå ¥ãæ¿ãã®é½åãªã©ã«ããå¤åãããããåæãªã¯ã¨ã¹ãæ°ã®å¶éã®ä¸éãå®è³ªçã«å¢ãããæ¸ã£ãããã¦ãã¾ãã¾ãã ã¨ãããã¨ã§ããã®æ¹æ³ã«ãåé¡ãããã¾ãã
æå¾ã®é¸æè¢ã¯ããã¼ããã©ã³ãµã®ã¯ã©ã¹ã¿ã«ä¸ã¤ã ãã«ã¦ã³ãããããã®ãµã¼ããç«ã¦ãããã§åæãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ãããã¨ããæ¹æ³ã§ãã å®ã¯ cybozu.com ã Apache ã§éç¨ãã¦ããã¨ãã¯ãã®æ¹æ³ã使ã£ã¦ DoS 対çããã¦ããã®ã§ããã®æã®è³ç£ã使ãã¾ãããã¨ãã§ãã¾ãã ãããã£ã¦ãnginx ã§ããã®æ¹æ³ã§ DoS 対çããã¦ãããã¨ã«ãã¾ããã
cybozu.com ã«ããã DoS 対çã®å ¨ä½åã¯ä»¥ä¸ã®ããã«ãªã£ã¦ãã¾ãã
yrmcds ã¯ãµã¤ãã¦ãºãéçºãã¦ãã memcached äºæ KVS ã§ãã yrmcds ã«ã¯ counter extension ããããããã»ã¹ã®çªç¶æ»ãªã©ã«å¯¾ãã¦ããã¹ããªæ¹æ³ã§ãªã½ã¼ã¹ã®å©ç¨éãã«ã¦ã³ããããã¨ãã§ãã¾ãã yrmcds ã使ãã°ã以ä¸ã®ããã«åæãªã¯ã¨ã¹ãæ°å¶éãå®è£ ã§ãã¾ãã
ãªã¯ã¨ã¹ããæ¥ãæã« yrmcds ã« Acquire ã³ãã³ããéã£ã¦ã«ã¦ã³ããä¸ããã ä¸éå¤ã«éãã¦ããã Not Acquired ã¨ããã¨ã©ã¼ãè¿ã£ã¦ããã®ã§ããã®æã¯ã¢ã¯ã»ã¹ãé®æããã ããã§ãªãã¨ãã¯ã¢ã¯ã»ã¹ã許å¯ããã
ã¬ã¹ãã³ã¹ãè¿ããããyrmcds ã«å¯¾ã㦠Release ã³ãã³ããéã£ã¦ã«ã¦ã³ããä¸ããã
nginx-maxconn-module
nginx-maxconn-module ã¯ãä¸ã§è¿°ã¹ããããªæ¹æ³ã§åæãªã¯ã¨ã¹ãæ°ãå¶éããã¢ã¸ã¥ã¼ã«ã§ãã
åºæ¬çãªä½¿ãæ¹
åºæ¬çãªä½¿ãæ¹ã¯ä»¥ä¸ã®ããã«ãªãã¾ãã
server { # ã«ã¦ã³ãã«ä½¿ç¨ãã yrmcds ã®ã¢ãã¬ã¹ãæå®ããã maxconn_server 127.0.0.1:11215; location / { # ã¢ã¯ã»ã¹å IP ã¢ãã¬ã¹æ¯ã«æ大 10 åæãªã¯ã¨ã¹ãã¾ã§è¨±å¯ããã set $maxconn_key $remote_addr; set $maxconn_limit 10; maxconn_acquire; # ä¸éãè¶ ãããªã¯ã¨ã¹ããæ¥ãæã®ã¨ã©ã¼ãã¼ã¸ (429 Too Many Requests) error_page 429 /path/to/429.html; ... } location /foobar/ { # ã¢ã¯ã»ã¹å IP ã¢ãã¬ã¹ã¨ãªã¯ã¨ã¹ã URI ã®çµãã¨ã«ãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ãããã set $maxconn_key $remote_addr:$uri; set $maxconn_limit 6; maxconn_acquire; ... } }
ã¾ããmaxconn_server
㧠yrmcds ã®ã¢ãã¬ã¹ãæå®ãã¾ãã yrmcds ã¯è¨å®ãã¡ã¤ã«ã®ä»¥ä¸ã®è¡ãç·¨éã㦠counter extension ãæå¹ã«ãã¦ããå¿
è¦ãããã¾ãã
# If true, the counter extension is enabled. (default: false) counter.enable = true
次ã«ã$maxconn_key
ã¨ããå¤æ°ã«ã«ã¦ã³ãã«ç¨ãããã¼ãã$maxconn_limit
ã«åæãªã¯ã¨ã¹ãæ°ã®ä¸éãæå®ãã¾ãã ä¸ã®ä¾ã® /
ã§ã¯ $maxconn_key
ã« $remote_addr
ãæå®ãã¦ãããããã¢ã¯ã»ã¹å
IP ã¢ãã¬ã¹æ¯ã«ã«ã¦ã³ãããæåã«ãªãã¾ãã ã¾ãã/foobar/
ã§ã¯ã$maxconn_key
ã« $remote_addr
㨠$uri
ãã³ãã³ã§é£çµããæååãæå®ãã¦ãããããã¢ã¯ã»ã¹å
IP ã¢ãã¬ã¹ã¨ãªã¯ã¨ã¹ã URI ã®çµã«å¯¾ãã¦åæãªã¯ã¨ã¹ãæ°ãã«ã¦ã³ãããã¨ããåä½ã«ãªãã¾ãã
ã«ã¦ã³ã¿ã®ãã¼ãä¸éå¤ã maxconn_acquire
ã®å¼æ°ã«ããå¤æ°ã«ãã¦ããã®ã¯ããã¼ãä¸éå¤ã決å®ããå ´æã¨å®éã«å¶éããããã location ãç°ãªãå ´åã§ã使ããããã«ããããã§ãã
maxconn_acquire
ã§ã«ã¦ã³ãã¢ããããã«ã¦ã³ã¿ã¯ãã¬ã¹ãã³ã¹ãã¯ã©ã¤ã¢ã³ãã«è¿ãçµããå¾ã«èªåçã«ã«ã¦ã³ããã¦ã³ããã¾ãã ã¾ããnginx ãä½ããã®çç±ã§çªç¶æ»ããå ´åã§ããyrmcds å´ã§èªåçã«ã«ã¦ã³ããã¦ã³ãããã®ã§ãã«ã¦ã³ãã¢ããããã£ã±ãªãã«ãªããã¨ã¯ããã¾ããã
é«åº¦ãªä½¿ãæ¹
ç»åãåç»ãzip ãã¡ã¤ã«ãªã©ã大ããã®éçãã¡ã¤ã«ã¯ AP ãµã¼ããç´æ¥è¿ãã®ã§ã¯ãªããããããµã¼ãã代ããã«è¿ããããªä»çµã¿ã«ãªã£ã¦ããå ´åãå¤ãã¨æãã¾ãã nginx ã§ã¯ãX-Accel-Redirect
ã¨ããããããããã¯ã¨ã³ããµã¼ããã¬ã¹ãã³ã¹ã«å«ãã¦ããã¨ããã®ãããã®å¤ãæã location ã«ãªã¯ã¨ã¹ããå
é¨ãªãã¤ã¬ã¯ãã§ããã¨ããä»çµã¿ãããã¾ãã ããã使ãã°ããªã¯ã¨ã¹ãã®èªè¨¼ã AP ãµã¼ãã§è¡ããã¬ã¹ãã³ã¹ã®éä¿¡ãããããµã¼ããè¡ãã¨ãã£ãåæ
ãå¯è½ã§ãã
ãã®ããã«ä¸ã¤ã®ãªã¯ã¨ã¹ããAP ãµã¼ãã¨ããããµã¼ãã«ã¾ããã£ã¦å¦çãããå ´åãåæãªã¯ã¨ã¹ãæ°å¶éã次ã®ããã«ããããã¨æããã¨ãããã¾ãï¼
- AP ãµã¼ãã¸ã®ã¢ã¯ã»ã¹ã¯åæãªã¯ã¨ã¹ãæ°ã®ã«ã¦ã³ãã«å«ããã
- ããããµã¼ãã¸ã®ã¢ã¯ã»ã¹ã¯åæãªã¯ã¨ã¹ãæ°ã®ã«ã¦ã³ãã«å«ããªããï¼é·æéãã¦ã³ãã¼ããªã©ãããããï¼
maxconn ã«ã¯ maxconn_release
ã¨ãããã£ã¬ã¯ãã£ããç¨æããã¦ãããããã使ãã°ãªã¯ã¨ã¹ãå¦çã®ä»»æã®ã¿ã¤ãã³ã°ã§ã«ã¦ã³ã¿ãä¸ãããã¨ãã§ãã¾ãã ï¼ã«ã¦ã³ã¿ãä¸ããã®ã¯åããªã¯ã¨ã¹ã㧠maxconn_acquire
ãæåãã¦ããå ´åã ãã§ããï¼
server { maxconn_server 127.0.0.1:11215; location / { # ã¢ã¯ã»ã¹å IP ã¢ãã¬ã¹æ¯ã«æ大 10 åæãªã¯ã¨ã¹ãã¾ã§è¨±å¯ããã set $maxconn_key $remote_addr; set $maxconn_limit 10; maxconn_acquire; # ãªãã¼ã¹ãããã·ã¨ maxconn ãåæã«ä½¿ãã¨ãã¯ãã®ãã£ã¬ã¯ãã£ãã # on ã«ãã¦ããã¨ããã proxy_ignore_client_abort on; proxy_pass http://backend; } location /blob/ { # ãã® location ã¯ãããã¯ã¨ã³ãã X-Accel-Redirect ãããã使ã£ã¦ # ãªã¯ã¨ã¹ããå é¨ãªãã¤ã¬ã¯ããããã¨ã§å°éããã internal; # blob ã¸ã®ã¢ã¯ã»ã¹ã¯åæãªã¯ã¨ã¹ãæ°ã®ã«ã¦ã³ãã«å«ããªãããã«ããããã # ãã㧠release ããã maxconn_release; proxy_pass http://blob; } }
ã¤ã³ã¹ãã¼ã«
nginx ã® addon ã¨ãã¦å®è£ ããã¦ãããããæ®éã® addon ã¨åãããã«ã¤ã³ã¹ãã¼ã«ã§ãã¾ãã
ã¾ããgithub ããã½ã¼ã¹ã³ã¼ããåã£ã¦ãã¾ãã
git clone https://github.com/cybozu/nginx-maxconn-module
次㫠nginx ã®ã½ã¼ã¹ã³ã¼ããå±éããconfigure ã®å¼æ°ã« --add-module=nginx-maxconn-module
ã追å ãã¦å®è¡ãã¾ããå¾ã¯æ®éã« make && make install ããã° OK ã§ãã
cd /path/to/nginx ./configure --add-module=/path/to/nginx-maxconn-module make make install
â» å¤ãã®å ´å㯠nginx-maxconn-module
以å¤ã®ã¢ã¸ã¥ã¼ã«ãå¿
è¦ã«ãªãå ´åãå¤ãã¨æãã¾ããå®éã«ä½¿ãå ´å㯠./configure --help
ãè¦ãªãã欲ããã¢ã¸ã¥ã¼ã«ãå
¨é¨æå®ããããã«ãã¦ä¸ããã
ãããã«
nginx-maxconn-module ãçæ§ã® DoS 対çã©ã¤ãã®ä¸å©ã¨ãªãã°å¹¸ãã§ãã