μΌλ° μ 보:
λ°°ν¬: μ°λΆν¬ 18.04
νμΌν¬λ°΄ v0.10.2
μλ νμΈμ,
λλ μ§κΈ WAFλ₯Ό μ¬μ©νμ¬ λ΄ owncloud μΈμ€ν΄μ€λ₯Ό 보νΈνκ³ μμ΅λλ€.
Sophos UTMμλ 2κ°μ λΆνμ΄ νμν©λλ€. λ¨Όμ νΈμ€νΈ κ°μ²΄(곡격μ)λ₯Ό λ§λ€κ³ λ λ²μ§Έλ‘ μλ°©ν₯ νλ‘μ κ°μ²΄λ₯Ό μ
λ°μ΄νΈν©λλ€. RESTful APIλ λ΄ μ€ν¬λ¦½νΈμμ μλνμ§λ§ λ΄ μ¬μ©μ μ§μ μμ
νμΌμ μν΄ νΈλ¦¬κ±°λμ§λ μμ΅λλ€. κ°μ²΄λ₯Ό λ§λλ 1λ¨κ³λ μ μλν©λλ€. <ip>
λ³μλ μ¬κΈ°μμλ§ νμν©λλ€.
κ·Έλ¬λ λ΄ λ³μ μ μ λΈλ‘μΌλ‘ μΈν΄ λ λ²μ§Έ λΆλΆμ΄ μΆ©λν©λλ€.
2020-11-23 16:15:12,158 fail2ban.actions [28653]: NOTICE [owncloud] Ban 80.187.101.140
2020-11-23 16:15:12,175 fail2ban.utils [28653]: Level 39 7f612c005a90 -- exec: UTM2B=80.187.101.140;
UTM=${UTM2B//./};
REF="REF_NetHos";
REF_ID="${UTM:0:10}";
DN="$REF$REF_ID";
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'Authorization: Basic access_token' -d '{"address":"80.187.101.140","address6":"","comment":"","duids":[],"hostnames":[],"interface":"","macs":[],"name":"80.187.101.140","resolved":false,"resolved6":false,"reverse_dns":false}' \
'https://host.domain/api/objects/network/host/' > /dev/null
curl -X PATCH --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Restd-Err-Ack: all' \
--header 'X-Restd-Lock-Override: yes' \
--header 'Authorization: Basic access_token' -d \
'{"access_control":"1","allowed_networks":["REF_NetworkAny"],"auth_profile":"","backend":["REF_RevBacWEBHost"],"be_path":"","comment":"","denied_networks":["'"$DN"'"],"hot_standby":false,"name":"ProxyN","path":"/subtree","status":true,"stickysession_id":"ROUTEID","stickysession_status":false,"websocket_passthrough":true}' \
'https://my.fw/api/objects/reverse_proxy/location/REF_RevLocProxyN'
2020-11-23 16:15:12,175 fail2ban.utils [28653]: ERROR 7f612c005a90 -- stderr: '/bin/sh: 2: Bad substitution'
2020-11-23 16:15:12,175 fail2ban.utils [28653]: ERROR 7f612c005a90 -- returned 2
actionban = UTM2B=<ip>;
UTM=${UTM2B//./};
REF="REF_NetHos";
REF_ID="${UTM:0:10}";
DN="$REF$REF_ID";
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' \
--header 'Authorization: Basic access_token' -d '{"address":"<ip>","address6":"","comment":"","duids":[],"hostnames":[],"interface":"","macs":[],"name":"<ip>","resolved":false,"resolved6":false,"reverse_dns":false}' \
'https://my.fw/api/objects/network/host/' > /dev/null
curl -X PATCH --header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'X-Restd-Err-Ack: all' \
--header 'X-Restd-Lock-Override: yes' \
--header 'Authorization: Basic access_token' -d \
'{"access_control":"1","allowed_networks":["REF_NetworkAny"],"auth_profile":"","backend":["REF_RevBacWEBHost"],"be_path":"","comment":"","denied_networks":["'"$DN"'"],"hot_standby":false,"name":"ProxyN","path":"/subtree","status":true,"stickysession_id":"ROUTEID","stickysession_status":false,"websocket_passthrough":true}' \
'https://my.fw/api/objects/reverse_proxy/location/REF_RevLocProxyN' > /dev/null
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 492 100 307 100 185 291 175 0:00:01 0:00:01 --:--:-- 466
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 841 100 504 100 337 7411 4955 --:--:-- --:--:-- --:--:-- 12367
80.187.101.140
80187101140
REF_NetHos
8018710114
REF_NetHos8018710114
add_host.sh λ΄λΆμ actionban
λλ²κΉ
μ μν΄ λμ echo $VARλ₯Ό μΆκ°νμμμ€.
μ λ₯Ό λμμ£Όμκ³ μ΄κ²μ λν΄ μ‘°κΈμ΄λλ§ λ°ν μ£Όμκ² μ΅λκΉ? - μ΄λ»κ² λ³μλ₯Ό μ μΈν΄μΌ ν©λκΉ? λ΄κ° λ μλͺ»νκ³ μμ£ ?
λμμ μ£Όμλ©΄ μ λ§ κ°μ¬νκ² μ΅λλ€.
RESTful APIλ λ΄ μ€ν¬λ¦½νΈμμ μλνμ§λ§ λ΄ μ¬μ©μ μ§μ μμ νμΌμ μν΄ νΈλ¦¬κ±°λμ§λ μμ΅λλ€.
μ€ν¬λ¦½νΈμ bashλ₯Ό μ¬μ©νλ€κ³ κ°μ ν©λκΉ? ( ${UTM2B//./}
λ bashismμ΄κΈ° λλ¬Έμ).
sh(μμ€ν
μμ fail2banμ μ€ννλ μ¬μ©μμ κΈ°λ³Έ μ
Έ)λ₯Ό μ¬μ©νλ fail2banμ λ³Ό μ μμΌλ―λ‘ μ€κ³μ λ°λΌ μλνμ§ μμ΅λλ€.
λ€μ μλ₯Ό μλν΄ λ³΄μΈμ.
$ sh -c 'UTM2B=192.0.2.1; UTM=${UTM2B//./};'
sh: 1: Bad substitution
sh
μ
Έμμ μ§μλμ§ μλ κ΅¬μ± μμ΄ μμ
μ λ€μ μμ±νκ±°λ bashμ© shebangμ μ¬μ©νμ¬ μ€ν¬λ¦½νΈμ μμ±ν λ€μ μμ
μμ μ€ν¬λ¦½νΈλ₯Ό νΈμΆν΄μΌ ν©λλ€(λ°λΌμ μ€ν¬λ¦½νΈλ sh λμ bashμμ μ€νλ¨).
λΉ λ₯Έ νΌλλ°± κ°μ¬ν©λλ€.
λλ λΉμ μ μ μμ λ°λμ΅λλ€. μμ λ€μ μ°κΈ°κ° μμμλ₯Ό μΌμ΅λλ€!
κΈμ§λ λͺ¨λ IPλ‘ λ³μλ₯Ό μ»μ κ°λ₯μ±μ΄ μμ΅λκΉ?
κΈμ§λ λͺ¨λ IPλ‘ λ³μλ₯Ό μ»μ κ°λ₯μ±μ΄ μμ΅λκΉ?
?
κ°λ₯ν©λλ€(κ·Έλ¬λ μ΄λ€ νμμΌλ‘)...
κ·Έλ¦¬κ³ μ΄λ€ μ©λλ‘ μ’μ κ²μΈμ§λ κΆκΈν©λλ€.
fail2ban-client get <JAIL> banned
λ₯Ό μ¬μ©ν μλ μμ΅λλ€(μ΅μ λ²μ μΌλ‘ μΆμλ 54b2208690e3c2fff00fbd9b197984d880e29a02 μ°Έμ‘°).
κΈμ, λλ λ΄ κ΅¬μ±μ ν
μ€νΈνκ³ μμ΅λλ€ :D μ ν λμμ§ μμ§λ§ λͺ κ°μ§ μ΄λ¦¬μμ μ μ WAF
μ°¨λ¨ν νΈμ€νΈ κ°μ²΄λ§ μ²λ¦¬ν μ μμΌλ©° νΈμ€νΈ κ·Έλ£Ήμ μ²λ¦¬ν μ μμ΅λλ€. λ°λΌμ f2bκ° μ IPλ₯Ό κ°μ§ν λλ§λ€ λ΄ μ€ν¬λ¦½νΈλ κΈμ§ λͺ©λ‘μ μλ λͺ¨λ νλͺ©μ 보λ΄μΌ ν©λλ€! κ·Έλ μ§ μμ κ²½μ° νμ¬ μ΅μ ipλ§ μ°¨λ¨λ©λλ€. :( λ΄ κ³ κ°μ ꡬμμ΄μ§λ§ λλ ν¨κ» μΌν μ μμ΅λλ€.
fail2ban-client status owncloud |grep Banned
μλ£! μ΄μ λͺ¨λ μ°¨λ¨λ IP μ£Όμλ₯Ό μκ³ μλ νλ‘ν μ½μ΄ μμ±λ©λλ€.
λ€λ₯Έ μ¬λμ΄ μ£Όλ³μμ λκ³ μλ κ²½μ° μ¬κΈ°μ μΆκ°λκ³ μ€ν¬λ¦½νΈλ μ΄ λͺ¨λ κ²μ μ¬μ©νμ¬ "컬 ν¨μΉ"λ₯Ό ν λ²λ§ νΈμΆνμ¬ νλ‘μμμ access_control λͺ©λ‘μ μ
λ°μ΄νΈν©λλ€. κ·Έλμ μ무λ λ μ΄μ λ΄ μκ°λ½μ κ±°μΉμ§ μμ΅λλ€. D
γ
μλ§λ μ΄κ²μ μ¬μ©ν μ μμλ μ΄μ λ₯Ό μ¦μ νμΈν μ μμ΅λλ€.
λ΄ νμμ λ§κ² κ°μ νμννλ €λ©΄ λ€μμ μννμμμ€.
sh μ
Έμ λ¬Έμ μμ: sh -c 'VAR=${VAR1%?};'
νμ§λ§ fail2banμμ: fail2ban-server[4540]: Failed during configuration: Error in action definition 'UTM9': '%' must be followed by '%' or '(', found: '%?};\ncurl -X POST --header \'Content-Type: application
μ΄ μ λμ μΌλ‘ λ°μ΄λ μννΈμ¨μ΄μ κ°μ¬λ립λλ€!
μλ§λ λΉμ μ μ΄κ²μ μ¦μ μλ³ ν μ μμ΅λλ€ ...
κ΅¬μ± μ€ μ€ν¨: μμ μ μ 'UTM9' μ€λ₯: '%' λ€μμ '%' λλ ...
λ¬Όλ‘ μ€λ₯ λ©μμ§(λ° λ¬Έμ)μμ μ μ μλ―μ΄ (python) κ΅¬μ± νμΌμ % charλ %(var)s
λ±κ³Ό κ°μ λ³μ λ° λ§€κ°λ³μμ λ체μ μ¬μ©λλ νΉμ λ¬Έμμ
λλ€.
λ°λΌμ λ€μκ³Ό κ°μ΄ (μΆκ° %λ‘) μ΄μ€μΌμ΄ν μ²λ¦¬ν©λλ€.
- VAR=${VAR1%?};
+ VAR=${VAR1%%?};
ꡬμ±μ μ½μ΄μ λ¨μΌ %-charλ‘ λ³΄κ°λ©λλ€.
κ°μ₯ μ μ©ν λκΈ
λ¬Όλ‘ μ€λ₯ λ©μμ§(λ° λ¬Έμ)μμ μ μ μλ―μ΄ (python) κ΅¬μ± νμΌμ % charλ
%(var)s
λ±κ³Ό κ°μ λ³μ λ° λ§€κ°λ³μμ λ체μ μ¬μ©λλ νΉμ λ¬Έμμ λλ€.λ°λΌμ λ€μκ³Ό κ°μ΄ (μΆκ° %λ‘) μ΄μ€μΌμ΄ν μ²λ¦¬ν©λλ€.
ꡬμ±μ μ½μ΄μ λ¨μΌ %-charλ‘ λ³΄κ°λ©λλ€.