ЁЯЫбя╕П рдзрдбрд╛ 24 тАФ WAF & Shield: gate рд╡рд░рдЪрд╛ bouncer
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 25 рдкреИрдХреА рдзрдбрд╛ 24 ┬╖ рдорд╛рдЧреАрд▓: lesson-23-route53-routing ┬╖ рдкреБрдвреАрд▓: lesson-25-api-gateway
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ24. Reception (рдзрдбрд╛ 15) рдареЛрдард╛рд╡рдгрд╛рд▒реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХрд╛рд▓рд╛ рдЖрдд рдШреЗрддреЗ. рдЖрддрд╛ reception рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрдгреНрдпрд╛рдЖрдзреА рдкрддреНрд░ рд╡рд╛рдЪрдгрд╛рд▒реНрдпрд╛ рдХреЛрдгрд╛рд▓рд╛ рддрд░реА рдХрд╛рдорд╛рд╡рд░ рдареЗрд╡рдгреНрдпрд╛рдЪреА рд╡реЗрд│. рдЦрд░реА file:
- waf/waf.tf тАФ managed rules + rate limit рдЕрд╕рд▓реЗрд▓реЗ web ACL, ALB рд▓рд╛ рдЬреЛрдбрд▓реЗрд▓реЗ
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
Security groups (рдзрдбрд╛ 10) рдкрд╛рд╣реБрдгрд╛ рдХреБрдареВрди рдпреЗрддреЛ рдЖрдгрд┐ рдХреЛрдгрддреНрдпрд╛ рджрд╛рд░рд╛рд╡рд░ рдареЛрдард╛рд╡рддреЛ рддреЗ рддрдкрд╛рд╕рддрд╛рдд тАФ рдкрд╛рд╣реБрдгрд╛ рдХрд╛рдп рдШреЗрдКрди рдЖрд▓рд╛ рдЖрд╣реЗ рддреЗ рддреЗ рдХрдзреАрдЪ рд╡рд╛рдЪрдд рдирд╛рд╣реАрдд. Web Application Firewall (WAF) ЁЯЫбя╕П рдореНрд╣рдгрдЬреЗ reception рд╕рдореЛрд░ рдЙрднрд╛ рдЕрд╕рд▓реЗрд▓рд╛ bouncer, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рдХреАрдЯ рдЙрдШрдбрддреЛ:
- Managed rule groups ЁЯУЛ тАФ AWS (рдЖрдгрд┐ vendors) рдирд┐рдпрдордкреБрд╕реНрддрдХреЗ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рддрд╛рдд: Common Rule Set (рдкрд╛рд░рдВрдкрд░рд┐рдХ web рд╣рд▓реНрд▓реЗ: injection, рд╡рд╛рдИрдЯ headers, рдкреНрд░рдорд╛рдгрд╛рдмрд╛рд╣реЗрд░ рдореЛрдареЗ bodies), Known Bad Inputs, SQL database, bot control. рддреБрдореНрд╣реА рдкреБрд╕реНрддрдХ рдЬреЛрдбрддрд╛; рддреЗ рд╕реНрд╡рддрдГрдЪ update рд╣реЛрддреЗ.
- Rate-based rules тП▒я╕П тАФ "5 рдорд┐рдирд┐рдЯрд╛рдВрдд 2,000 рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд requests рдХрд░рдгрд╛рд░рд╛ рдХреЛрдгрддрд╛рд╣реА рдПрдХрдЯрд╛ IP рдХрд╛рд╣реА рд╡реЗрд│рд╛рд╕рд╛рдареА block рд╣реЛрддреЛ." рд╕реЗрдХрдВрджрд╛рд▓рд╛ 500 рд╡реЗрд│рд╛ refresh рдХрд░рдгрд╛рд▒реНрдпрд╛ рдкреЛрд░рд╛рд▓рд╛ рдерд╛рдВрдмрд╡рдгрд╛рд░рд╛ рдПрдХрдореЗрд╡ рдирд┐рдпрдо.
- рддреБрдордЪреЗ рд╕реНрд╡рддрдГрдЪреЗ рдирд┐рдпрдо тЬНя╕П тАФ IP sets (office рд▓рд╛ allow, рдПрдЦрд╛рджреА range block), geo-match (рддреБрдореНрд╣реА рд╕реЗрд╡рд╛ рджреЗрдд рдирд╛рд╣реА рдЕрд╢рд╛ рджреЗрд╢рд╛рдВрддреВрди traffic рдирд╛рд╣реА), paths рдХрд┐рдВрд╡рд╛ headers рд╡рд░ string/regex matches.
- рдЖрдзреА Count mode ЁЯзк тАФ рдкреНрд░рддреНрдпреЗрдХ рдирд┐рдпрдо block рдРрд╡рдЬреА count рдХрд░реВ рд╢рдХрддреЛ. рдиреЗрд╣рдореА count рдиреЗ рд╕реБрд░реБрд╡рд╛рдд рдХрд░рд╛, рдПрдХ рджрд┐рд╡рд╕ logs рд╡рд╛рдЪрд╛, рдЖрдгрд┐ рдордЧрдЪ block рдХрдбреЗ рд╡рд│рд╛. рдкрд╣рд┐рд▓реНрдпрд╛рдЪ рджрд┐рд╡рд╢реА block рдХрд░рдгрд╛рд░реЗ bouncers рдореБрдЦреНрдпрд╛рдзреНрдпрд╛рдкрд┐рдХреЗрд▓рд╛рдЪ рдмрд╛рд╣реЗрд░ рдХрд╛рдврддрд╛рдд.
Bouncer рд▓рд╛ ALB, API Gateway (рдзрдбрд╛ 25), рдХрд┐рдВрд╡рд╛ CloudFront рд▓рд╛ рдЬреЛрдбрд╛ тАФ рдкрд╛рд╣реБрдгреЗ рдпреЗрддрд╛рдд рддреНрдпрд╛ рддреАрди рдЬрд╛рдЧрд╛. рдЖрдгрд┐ рдпрд╛ рд╕рдЧрд│реНрдпрд╛рдЦрд╛рд▓реА, Shield Standard (рдореЛрдлрдд, рдЖрдкреЛрдЖрдк) рдврдХрд▓рд╛рдврдХрд▓реА рдХрд░рдгрд╛рд▒реНрдпрд╛ рдореЛрдареНрдпрд╛ рдЧрд░реНрджреА (network-layer DDoS) рдкрдЪрд╡рддреЗ; Shield Advanced (рд╕рд╢реБрд▓реНрдХ) response team рдЖрдгрд┐ cost protection рдЬреЛрдбрддреЗ, рддреНрдпрд╛ рджрд┐рд╡рд╕рд╛рдВрд╕рд╛рдареА рдЬреЗрд╡реНрд╣рд╛ рд╕рдЧрд│реЗ рдЧрд╛рд╡ рд░рд╛рдЧрд╛рдиреЗ рд▓реЛрдЯрддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
net["ЁЯМН internet"]
waf["ЁЯЫбя╕П WAF web ACL<br/>ЁЯУЛ managed rules ┬╖ тП▒я╕П rate 2k/5min<br/>ЁЯЧ║я╕П geo ┬╖ ЁЯУЗ IP sets"]
alb["ЁЯЫОя╕П ALB"]
desks["ЁЯЦея╕П desks"]
logs["ЁЯз╛ WAF logs тЖТ S3 / CloudWatch"]
net -->|"1 request"| waf
waf -->|"2 clean тЖТ forward"| alb --> desks
waf -->|"тЬЧ SQLi / flood тЖТ 403"| net
waf -->|"3 every decision"| logs
тЭУ рдХрд╛рдп
- Web ACL = рдХреНрд░рдорд╛рдиреЗ рд▓рд╛рд╡рд▓реЗрд▓реЗ рдирд┐рдпрдо + рдПрдХ default action; рдПрдХ рдХрд┐рдВрд╡рд╛ рдЕрдзрд┐рдХ resources рдирд╛ рдЬреЛрдбрд▓реЗрд▓реЗ. рдирд┐рдпрдорд╛рдВрдЪрд╛ рдЦрд░реНрдЪ рдкреНрд░рддрд┐ ACL, рдкреНрд░рддрд┐ рдирд┐рдпрдо, рдкреНрд░рддрд┐ рджрд╣рд╛ рд▓рд╛рдЦ requests.
- Scope: ALB/API Gateway рд╕рд╛рдареА
REGIONAL, edge рд╕рд╛рдареАCLOUDFRONT. - Rate limit рдЪреА рд╕реВрдХреНрд╖реНрдорддрд╛: рдореБрд│рд╛рдд рдкреНрд░рддрд┐ IP; рдирд╡реЗ рдкрд░реНрдпрд╛рдп headers/paths рд╡рд░ key рдХрд░рддрд╛рдд (рдкреНрд░рддрд┐-user, рдкреНрд░рддрд┐-endpoint).
- Logging: рддреЗ рдЪрд╛рд▓реВ рдХрд░рд╛; false positives (SQLi рдирд┐рдпрдорд╛рд▓рд╛ рди рдЖрд╡рдбрдгрд╛рд░реА рдПрдЦрд╛рджреА рдЦрд░реА form post) рдХрдореА рдХрд░рдгреНрдпрд╛рдЪрд╛ рддреЛрдЪ рдорд╛рд░реНрдЧ рдЖрд╣реЗ.
- WAF рдХреБрдареЗ рдорджрдд рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА: auth bugs, business-logic рдЪрд╛ рдЧреИрд░рд╡рд╛рдкрд░, рд╕рдореЛрд░ рдХрд╛рд╣реАрд╣реА рдирд╕рд▓реЗрд▓реНрдпрд╛ service рдкрд░реНрдпрдВрдд TLS рдЪреНрдпрд╛ рдЖрдд рдЕрд╕рд▓реЗрд▓реЗ рдХрд╛рд╣реАрд╣реА. Defense in depth: SG (рджрд╛рд░) + WAF (рдкрд╛рдХреАрдЯ) + app validation (рдЖрддрд▓рд╛ рдордЬрдХреВрд░).
ЁЯдФ рдХрд╛
рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рджрд┐рд╡рд╢реАрд╕реБрджреНрдзрд╛ internet 40% bots рдЕрд╕рддреЗ. Bouncer рд╢рд┐рд╡рд╛рдп, reception рдЪрд╛
рджрд┐рд╡рд╕ /wp-admin рд╕рд╛рдареАрдЪреНрдпрд╛ probes рдирд╛ рдЙрддреНрддрд░реЗ рджреЗрдгреНрдпрд╛рдд рдЬрд╛рддреЛ рдЖрдгрд┐ рддреБрдордЪреЗ logs рдореНрд╣рдгрдЬреЗ
рдиреБрд╕рддрд╛ рдЧреЛрдВрдЧрд╛рдЯ. WAF рд╕реНрд╡рд╕реНрдд, managed рдЖрд╣реЗ, рдЖрдгрд┐ "рдХрд╛рд▓ рд░рд╛рддреНрд░реА рдЖрдкрд▓реНрдпрд╛рд╡рд░ рд╣рд▓реНрд▓рд╛ рдЭрд╛рд▓рд╛"
рдпрд╛рд▓рд╛ рдПрдХрд╛ рдирдЬрд░реЗрдд рдкрд╛рд╣рд╛рдпрдЪреНрдпрд╛ graph рдордзреНрдпреЗ рдмрджрд▓рддреЗ. рдЖрдзреА-count-рдордЧ-block рдЪреА рд╕рд╡рдп рд╣реЗрдЪ
рдЦрд░реЗ рдХреМрд╢рд▓реНрдп рдЖрд╣реЗ.
ЁЯФз рдХрд╕реЗ
# what the bouncer has been doing (top blocked rules, last hour):
aws wafv2 get-sampled-requests --web-acl-arn $ACL --rule-metric-name RateLimit \
--scope REGIONAL --time-window StartTime=$(date -u -v-1H +%s),EndTime=$(date -u +%s) --max-items 20
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛ (~15 рдорд┐рдирд┐рдЯреЗ, ~5┬в тАФ рдзрдбрд╛ 15 рдЪреНрдпрд╛ ALB рд▓рд╛ рдЬреЛрдбрддреЗ, рджреЛрдиреНрд╣реА destroy рдХрд░рд╛)
cd waf && terraform apply -var alb_arn=$ALB_ARN # common rules (count) + rate limit (block)
for i in $(seq 1 3000); do curl -s -o /dev/null $ALB_URL/ & done; wait # the refresh kid
curl -i $ALB_URL/ # тЖТ 403 from the bouncer, for a while
terraform destroy
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
curl -i ALB_URL 200 рджреЗрддреЛ; flood loop рдирдВрддрд░ рдХрд╛рд╣реА рд╡реЗрд│ рддреЛ 403 рджреЗрддреЛ; WAF sampled requests rate рдирд┐рдпрдо рд▓рд╛рдЧреВ рд╣реЛрддрд╛рдирд╛ рджрд╛рдЦрд╡рддрд╛рдд.
ЁЯз╣ рд╕рд╛рдлрд╕рдлрд╛рдИ тАФ рдЪрд╛рд▓реВ рдареЗрд╡реВ рдирдХрд╛
рдЗрдереЗ terraform destroy рдХрд░рд╛ рдЖрдгрд┐ рдзрдбрд╛ 15 рдЪрд╛ ALB рд╕реБрджреНрдзрд╛ тАФ рджреЛрдиреНрд╣реА рддрд╛рд╕рд╛рдкреНрд░рдорд╛рдгреЗ bill рдХрд░рддрд╛рдд
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдкрд╣рд┐рд▓реНрдпрд╛рдЪ рджрд┐рд╡рд╢реА block mode рдордзреНрдпреЗ managed rules тАФ рдЦрд▒реНрдпрд╛ form post рд▓рд╛ 403 рдорд┐рд│рддреЛ
- WAF рд▓рд╛ рдлрдХреНрдд ALB/API Gateway/CloudFront рдкрд░реНрдпрдВрдд рдкреЛрд╣реЛрдЪрдгрд╛рд░реЗрдЪ рджрд┐рд╕рддреЗ рд╣реЗ рд╡рд┐рд╕рд░рдгреЗ
- Logging рдЪрд╛рд▓реВ рдирд╛рд╣реА, рддреНрдпрд╛рдореБрд│реЗ false positives рдХрдореА рдХрд░рдгреНрдпрд╛рдЪрд╛ рдХреЛрдгрддрд╛рд╣реА рдорд╛рд░реНрдЧ рдирд╛рд╣реА
тПня╕П рдкреБрдвреЗ
Websites рдирд╛ reception рдЖрд╣реЗ. APIs рдирд╛ рддреНрдпрд╛рдВрдЪреЗ рд╕реНрд╡рддрдГрдЪреЗ front desk рд╣рд╡реЗ тАФ рдЬреЗ рддрд┐рдХрд┐рдЯреЗ рдореЛрдЬрддреЗ, рдУрд│рдЦрдкрддреНрд░реЗ рддрдкрд╛рд╕рддреЗ, рдЖрдгрд┐ рдХрд╛рдореЗ рдереЗрдЯ Lambda рдХрдбреЗ рд╕реЛрдкрд╡рддреЗ. рдзрдбрд╛ 25: API Gateway.