九州インフラ交流勉強会(Kixs) Vol.002 https://kixs.connpass.com/ ホスティングにおける柔軟かつ軽量なアクセス制御の必要性とその実装 @takumakume
ٱถഅ(.01FQBCP *ODभΠϯϑϥަྲྀษڧձ,*94WPM!(.0ϖύϘԬࢧࣾϗεςΟϯάʹ͓͚Δॊೈ͔ͭܰྔͳΞΫηε੍ޚͷඞཁੑͱͦͷ࣮
View Slide
ࣗݾհٱถ അ (@takumakume)ߴߍଔۀʙ6ؒΠϯλʔωοταʔϏεϓϩόΠμͰۈωοτϫʔΫʙϛυϧΣΞͷߏஙϓϦηʔϧεΤϯδχΞ20164݄͔ΒϖύϘʹೖࣾϩϦϙοϓʂͷΠϯϑϥΤϯδχΞ
࣍ϗεςΟϯάʹ͓͚Δॊೈ͔ͭܰྔͳΞΫηε੍ޚͱmrubyΛ༻͍ͨ࣍ੈΞΫηε੍ޚͷ࣮·ͱΊ
ϗεςΟϯάʹ͓͚Δॊೈ͔ͭܰྔͳΞΫηε੍ޚͱ
ॊೈ͔ͭܰྔͳΞΫηε੍ޚ
ϗεςΟϯάʹ͓͚ΔΞΫηε੍ޚϗεςΟϯάͦͷಛੑ্ɺ͓٬༷ͷ༷ʑͳίϯςϯπΛ͓༬͔Γ͍ͯ͠ΔɻதʹҟৗʹߴෛՙʹͳΔͷɺDDoSͷରʹͳΔίϯςϯπͳͲ༷ʑͰ͋Δɻ͔͠͠ɺ͜ͷΑ͏ͳҰ෦ͷίϯςϯπʹΑΓɺͦͷαʔόΛ͝ར༻͍͍ͯΔେଟͷଞͷ͓٬༷͕շదʹ8Λར༻Ͱ͖ͳ͘ͳͬͯ͠·͏͜ͱɺ͋ͬͯͳΒͳ͍ͱզʑߟ͍͑ͯ·͢ɻ
ຊηογϣϯͰͦͷղܾखஈͷ̍ͭͱͯ͠ɺϩϦϙοϓʂͰߦ͍ͬͯΔଟ͘ͷ͓٬༷ʹ8Λշదʹ͝ར༻͍ͨͩͨ͘Ίͷ࣍ੈΞΫηε੍ޚʹ͍ͭͯ͝հ͠·͢ɻ
ݱঢ়ͷΞΫηε੍ޚͷ՝
͜Ε·Ͱʹར༻ͨ͠ΞΫηε੍ޚखஈmod_cbandΛར༻ͨ͠ΞΧϯτ୯ҐͰͷτϥϑΟοΫ੍ޚͱಉ࣌ΞΫηε੍ޚmod_vhost_maxclientsΛར༻ͨ͠υϝΠϯ୯ҐͰͷಉ࣌ΞΫηε੍ޚͦΕͧΕ՝͕͋ͬͨ
[email protected]Λར༻੍ͨ͠ޚʹΑΔ՝ΞΧϯτ୯ҐͷτϥϑΟοΫͱಉ࣌ΞΫηε੍ݶΛ͍ͯͨ͠ɻCBandSpeed 10Mb/s 30 30mod_cbandΛ༗ޮʹ͢Δ͜ͱͰ70%ఔͷύϑΥʔϚϯεྼԽ͕ੜ͡ɺ੍ޚػߏࣗମ͕ϘτϧωοΫͱͳͬͨɻ
[email protected]@NBYDMJFOUTΛར༻੍ͨ͠ޚmod_cbandͷύϑΥʔϚϯεྼԽ͕େ͖͍ͨΊͪ͜ΒΛ࠾༻ɻಋೖʹΑΔύϑΥʔϚϯεྼԽ2%ͱߴͳιϑτΣΞɻҎԼͷΑ͏ʹυϝΠϯ୯Ґͷಉ࣌ΞΫηε੍ݶΛߦ͏ɻDocumentRoot /path/to/webServerName hoge.example.jpVhostMaxClients 30͔͠͠ɺ࣍ͷΑ͏ͳύλʔϯͰ՝͕ੜͨ͡ɻ
[email protected]@NBYDMJFOUTΛͲ͏͍ͬͯΔ͔ڞ༻8αʔόIPHFDPNmod_vhost_maxclientsͷ੍ݶZDPNYDPNஶ͘͠Ϧιʔε༻ྔ͕ภΒͳ͍Α͏ʹେͷϦιʔεׂͱͯ͠ɺ֤υϝΠϯʹಉ࣌ଓͷ੍ݶΛ͔͚͍ͯ·͢ɻ
ڞ༻8αʔόIPHFDPNॲཧͷॏ͍ϓϩάϥϜʹΞΫηε͕ूத͠αʔό͕ߴෛՙͱͳͬͨmod_vhost_maxclientsͷ੍ݶZDPNYDPN
ڞ༻8αʔόIPHFDPNmod_vhost_maxclientsͷ੍ݶZDPNYDPN[email protected]@NBYDMJFOUTͷ੍ݶΛڧΊΔඞཁ͕͋Δ
ڞ༻8αʔόIPHFDPN ZDPNYDPN੍ݶΛڧΊͨ ܰྔͳίϯςϯπʹΞΫηεͰ͖ͳ͘ͳΔ
ڞ༻8αʔόIPHFDPN ZDPNYDPNຊདྷ੍ޚ͞ΕΔඞཁ͕ͳ͍ϑΝΠϧ·ͰΞΫηεͰ͖ͳ͘ͳͬͯ͠·͏ɻ
ղܾํ๏ڞ༻8αʔόIPHFDPN ZDPNYDPNϑΝΠϧ୯ҐͰ੍ޚmod_vhost_maxclients
ղܾํ๏ڞ༻8αʔόIPHFDPN ZDPNYDPNϑΝΠϧ୯ҐͰ੍ޚmod_vhost_maxclientsαʔόͷෛՙΛԼ͛ͭͭɺ੍ޚʹΑΔӨڹΛۃখԽͰ͖Δɻ
࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌͋ΔαʔόͷϦιʔεফඅྔ<>
࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌શମ͋ΔαʔόͷϦιʔεফඅྔ<>ಛఆͷϑΝΠϧಛఆͷ࣌ؒʹେྔʹΞΫηε͕͋Δ
࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌શମ͋ΔαʔόͷϦιʔεফඅྔ<>ಛఆͷϑΝΠϧಛఆͷϑΝΠϧͷॲཧͰϦιʔεͷ΄ͱΜͲΛফඅ͠ఆظతʹଞͷ͓٬༷ͷαʔϏεఏڙʹࢧোΛ͖͍ͨͯͨ͠ɻ
࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌ ࣌શମಛఆͷϑΝΠϧղܾํ๏<>ෛՙͷߴ͍ϑΝΠϧʹରͯ࣌ؒ͠ࢦఆͰ੍ޚ͢Δ
ॊೈͳΞΫηε੍ޚͷ·ͱΊݱঢ়ΑΓࡉ͔͍ɺϑΝΠϧ୯ҐͰΞΫηε੍ޚͰ͖ΔΑ͏ʹͯ͠ɺ੍ޚʹΑΔӨڹΛۃখԽ͢Δ͜ͱɻಛఆͷ࣌ؒͷΈΞΫηε੍ޚΛ༗ޮԽͰ͖Δ͜ͱɻ
ϗεςΟϯάͰ1ͷαʔόΛଟ͘ͷ͓٬༷ʹ͝ར༻͍ͨͩ͘͜ͱͰ҆Ձʹఏڙ͍ͯ͠ΔɻࠓޙͰ͖Δ͚ͩ҆ՁʹշదͳαʔϏεΛఏڙ͍ͨ͠ɻΞΫηε੍ޚͷػߏ͕ϘτϧωοΫʹͳͬͯɺͦΕΛୡͰ͖ͳ͘ͳΔɻܰྔͳΞΫηε੍ޚͷඞཁੑ
ॊೈ͔ͭܰྔͳΞΫηε੍ޚͱ
ϑΝΠϧ୯ҐͰΞΫηε੍ޚͰ͖Δ͜ͱɻಛఆͷ࣌ؒଳͷΈΞΫηε੍ޚΛ༗ޮԽͰ͖Δ͜ͱɻύϑΥʔϚϯεྼԽΛۃྗى͜͞ͳ͍͜ͱɻॊೈ͔ͭܰྔͳΞΫηε੍ޚͱͲͷΑ͏ʹ࣮ݱ͢Δ͔ʁ
ϑΝΠϧ୯ҐͷΞΫηε੍ޚطʹ"QBDIFͷϞδϡʔϧ͕ଘࡏ͢Δɻ
[email protected]mod_vlimithttps://github.com/matsumoto-r/mod_vlimitϑΝΠϧσΟϨΫτϦ୯ҐͰಉ࣌ΞΫηε੍ޚΛ͢Δ͜ͱ͕Ͱ͖ΔɻVlimitIP 30 /path/to/hoge.phpϑΝΠϧ୯ҐͰͷΞΫηε੍ޚΛߦ͏ػೳ͋Δ͕ࠓճಋೖʹࢸΒͳ͔ͬͨɻ
[email protected]Λ࠾༻͠ͳ͔ͬͨཧ༝࣌ؒࢦఆͰ੍ݶΛ༗ޮԽͰ͖Δػೳ͕ͳ͍ɻApacheͷϞδϡʔϧͳͷͰCݴޠͰ࣮͞Ε͍ͯΔɻӡ༻ܥͷπʔϧ࣌ؒͷܦաʹରͯ͠ॊೈͳมߋ͕ཁٻ͞ΕΔɻCݴޠͰͷ։ൃͱͳΔͱ։ൃ্͕͕Δɺ։ൃऀ͕ݶΒΕΔɻ
ͰɺͲͷΑ͏ʹ࣮ݱ͢Δ͔ʁ
“mruby” ͳΒղܾͰ͖Δɻ
NSVCZRubyͷύύ͜ͱ “Matz” ͞Μ͕։ൃ͍ͯ͠ΔɻলϝϞϦͷΈࠐΈ͚ͷRuby࣮ɻCݴޠ͕ۤखͳͻͱͰɺmrubyΛ͑RubyͰΈࠐΈ։ൃΛߦ͏ࣄ͕Ͱ͖Δɻ
ApacheNginxͰmrubyΛ༻͍ͨΈࠐΈ։ൃΛ࣮ݱͨ͠ιϑτΣΞ͕ଘࡏ͢Δ
[email protected]@NSVCZฐࣾͷ@matsumotory͕։ൃ͍ͯ͠Δɻmod_mrubyApacheͰmrubyΛར༻͢ΔͨΊͷϞδϡʔϧngx_mrubynginxͰmrubyΛར༻͢ΔͨΊͷ֦ு࣮CݴޠͰϞδϡʔϧΛ࣮͠ͳ͚Ε࣮ݱͰ͖ͳ͔ͬͨڍಈΛmrubyΛ͙ͬͯ͢ʹ࣮Ͱ͖ͯɺ࠷খݶͷύϑΥʔϚϯεྼԽʹཹΊΔ͜ͱ͕Ͱ͖ΔιϑτΣΞɻ
[email protected]mod_mruby -1.5%ngx_mruby +17.5%੩తίϯςϯπʹର͢ΔύϑΥʔϚϯεܭଌ݁Ռ
mrubyΛ༻͍Ε֦ுੑɺอकੑΛଛͳΘͣ࠷খݶͷύϑΥʔϚϯεྼԽʹཹΊͯιϑτΣΞΛ։ൃ͢Δ͜ͱ͕Ͱ͖Δɻ
NSVCZΛ༻͍ͨ࣍ੈΞΫηε੍ޚͷ࣮
࣮ʹ͋ͨͬͯར༻ͨ͠ιϑτΣΞ
IUUQBDDFTTMJNJUFSฐࣾͷ @matsumotory ͕։ൃ͍ͯ͠Δɻhttps://github.com/matsumoto-r/http-access-limitermod_mruby͘͠ngx_mrubyͰऔಘͨ͠ҙͷϦΫΤετύϥϝʔλΛ༻͍ͯಉ࣌ଓΛΧϯτ͢ΔmrubyϛυϧΣΞऔಘͰ͖ΔϦΫΤετύϥϝʔλʹΞΫηεઌͷϑΝΠϧͷϑϧύεΛ࢝ΊɺଓݩͷIPΞυϨεɺURLͳͲΛऔಘͰ͖ΔͨΊ༷ʑͳ༻్Ͱ༻Ͱ͖Δɻ
ಈ࡞֓ཁ NSVCZ8PSLFSNSVCZ8PSLFSNSVCZIUUQEڞ༗ϝϞϦglobalmutexಉ࣌ଓΧϯλʔKVSಉ࣌ଓΧϯλʔlocalmemcacheΛ༻͍ͨKey-Value-StoreΩʔͱͨ͠ϦΫΤετύϥϝʔλΛݩʹಉ࣌ΞΫηεΛΧϯτ͢Δɻglobal mutex֤Worker͔Βಉ࣌ଓΧϯλʔΛૢ࡞͢ΔͨΊෆ߹͕ൃੜ͠ͳ͍Α͏ʹϩοΫΛߦ͏ɻKEY/path/to/hoge.phpVALUE1
ಈ࡞֓ཁ NSVCZ8PSLFSNSVCZ8PSLFSNSVCZIUUQEڞ༗ϝϞϦglobalmutexಉ࣌ଓΧϯλʔKVSϦΫΤετϦΫΤετNVUFYΛϩοΫMPDLϦΫΤετύϥϝʔλΛΩʔʹΠϯΫϦϝϯτΠϯΫϦϝϯτKEY/path/to/hoge.phpVALUE1VOMPDLNVUFYΛΞϯϩοΫ
ಈ࡞֓ཁ NSVCZ8PSLFSNSVCZ8PSLFSNSVCZIUUQEڞ༗ϝϞϦglobalmutexಉ࣌ଓΧϯλʔKVSίϯςϯπͷॲཧΛߦ͏NVUFYΛϩοΫMPDLσΫϦϝϯτσΫϦϝϯτVOMPDLNVUFYΛΞϯϩοΫKEY/path/to/hoge.phpVALUE0ίϯςϯπͷॲཧ
ಈ࡞֓ཁͷ·ͱΊϦΫΤετ͕͋ͬͨ࣌ʹɺϦΫΤετύϥϝʔλΛmod_mrubyngx_mrubyΛ༻͍ͯऔಘ͢ΔɻΞΫηε੍ޚΛ͍ͨ͠୯ҐΛΩʔͱͯ͠ɺಉ࣌ଓΛΧϯτ͢ΔɻෳͷWorker͔ΒΧϯλʔૢ࡞͢ΔͨΊɺglobal mutexΛͬͯෆ߹͕ى͖ͳ͍Α͏ʹ੍ޚ͢Δɻ
ػೳՃΛ͢Δhttp-access-limiterʹϑΝΠϧຖͷ࠷େಉ࣌ଓͷઃఆػೳɺ੍ޚΛ༗ޮԽ͢Δ࣌ؒଳΛઃఆ͢ΔػೳΛՃ͍ͨ͠ɻmrubyͰॻ͔Ε͍ͯΔͨΊ؆୯ʹػೳՃ͕Ͱ͖Δʂ
ػೳՃΠϝʔδNSVCZ8PSLFSNSVCZ8PSLFSNSVCZIUUQEڞ༗ϝϞϦglobalmutexಉ࣌ଓΧϯλʔKVS੍ޚ݅localmemcacheΛ༻͍ͨKey-Value-StoreϑΝΠϧͷϑϧύε͕Ωʔ࠷େಉ࣌ଓ੍ݶΛ༗ޮԽ͢Δ࣌ؒଳKVS੍ޚ݅
੍ݶ݅ͷσʔλ/path/to/hoge.php{"max_clients" : 30, # ࠷େಉ࣌ଓ"time_slots" : [ # ༗ޮʹ͢Δ࣌ؒଳ{ "begin" : 1200, "end" : 1800 },{ "begin" : 2100, "end" : 2200 }]}KEYVALUEA AͷؒAQBUIUPIPHFQIQAͷ࠷େଓΛAA·Ͱʹ੍ݶ͢Δɻ
ػೳՃޙͷಈ࡞֓ཁNSVCZ8PSLFSNSVCZ8PSLFSNSVCZIUUQEڞ༗ϝϞϦglobalmutexಉ࣌ଓΧϯλʔKVSKVS੍ޚ݅ϦΫΤετϦΫΤετ੍ޚ݅Λࢀর੍ޚ݅Λࢀরɹɹଘࡏ͠ͳ͚ΕॲཧऴྃNVUFYΛϩοΫMPDLϑΝΠϧͷϑϧύεΛΩʔʹΠϯΫϦϝϯτΠϯΫϦϝϯτ੍͠ݶ͕༗ޮͳ࣌ؒଳͰಉ࣌ଓ੍ݶΛա͍ͯ͠ΕΤϥʔΛฦ͢
͍ํ IUUQEDPOGLoadModule mruby_module modules/mod_mruby.so# Apacheͷϓϩηε͕ىಈͨ࣌͠ʹϑοΫ͞ΕΔ# http-access-limiterͷΫϥεΛఆٛɺ࣍ʹىಈ͢ΔWorker͕ࢀরͰ͖ΔΑ͏ʹ͢ΔɻmrubyPostConfigMiddle /etc/httpd/conf.d/access_limiter/access_limiter_init.rb cache# ΞΫηε͕ൃੜͨ͠ͱ͖ʹϑοΫ͞ΕΔ# ಉ࣌ଓΧϯλΛΠϯΫϦϝϯτ͢Δ# ͞Βʹɺ࠷େಉ࣌ଓΛաͨ͠߹ʹ503ΤϥʔΛฦ͢ͳͲͷΞΫγϣϯΛهड़͢ΔɻmrubyAccessCheckerMiddle /etc/httpd/conf.d/access_limiter/access_limiter.rb cache# ίϯςϯπͷॲཧ͕ऴΘͬͨͱ͖ʹϑοΫ͞ΕΔ# ಉ࣌ଓΧϯλΛσΫϦϝϯτ͢ΔmrubyLogTransactionMiddle /etc/httpd/conf.d/access_limiter/access_limiter_end.rb cache
ؾʹͳΔύϑΥʔϚϯε
ಋೖʹΑΔύϑΥʔϚϯεྼԽ3ˋ
ύϑΥʔϚϯεςετ݁ՌabΛͬͯύϑΥʔϚϯεΛଌఆ͠·ͨ͠ɻςετύλʔϯ ྼԽhttpd 0%httpd + http-access-limiter 3%httpd + http-access-limiter (੍ݶର) 5%WordPressͷΞΫηε10ສϦΫΤετ100ଟॏ / CPU24ίΞɾRAM32GBςετύλʔϯ ྼԽhttpd 0%httpd + http-access-limiter 3%httpd + http-access-limiter (੍ݶର) 30%phpinfo()ͷΞΫηεࢀߟࢿྉ
ύϑΥʔϚϯεςετ݁Ռʹର͢Δߟaccess-limiterͷಋೖʹੜ͡ΔύϑΥʔϚϯεྼԽ3%ͱߴͰ͋Δ͜ͱ͕͔ͬͨɻDBΛ͏WordPressͰɺΞϓϦέʔγϣϯͷॲཧ͕Φʔόϔουͱͳͬͯaccess-limiterΛಋೖ͢Δ͜ͱʹΑΔΦʔόϔουޡࠩఔͱͳͬͨɻphpinfo()ͷΑ͏ͳܰྔͳॲཧͷ߹ʹɺ੍ݶରͱͨ͠ͱ͖ʹ3ׂఔύϑΥʔϚϯεྼԽ͕ੜͨ͡ɻࢀߟࢿྉ
·ͱΊ
·ͱΊϗεςΟϯάڞ༗αʔόͰ͋ΔͷͰɺΑΓଟ͘ͷਓ͕҆ՁͰշదʹ͝ར༻͍ͨͩͨ͘ΊʹΞΫηε੍ޚඞཁɻΞΫηε੍ޚͷ୯ҐΛΑΓࡉ੍͔ͯ͘͠ޚʹΑΔӨڹΛۃখԽ͠ɺదͳΞΫηε੍ޚΛ࣮ݱͨ͠ɻ࣮ݱखஈͱͯ͠อकੑɺ֦ுੑɺੑೳͷόϥϯε͕Α͍mrubyΛ༻͍ͨɻ