Fail2ban: μ‚¬μš©μž 지정 μž‘μ—… μ‹€νŒ¨ | 잘λͺ»λœ λŒ€μ²΄

에 λ§Œλ“  2020λ…„ 11μ›” 23일  Β·  6μ½”λ©˜νŠΈ  Β·  좜처: fail2ban/fail2ban

ν™˜κ²½:

일반 정보:
배포: μš°λΆ„νˆ¬ 18.04
페일투밴 v0.10.2

  • Fail2Ban 버전(κ°€λŠ₯ν•œ λͺ¨λ“  배포 접미사 포함):
  • 릴리슀 이름/버전을 ν¬ν•¨ν•œ OS:
  • [x] OS/배포 λ©”μ»€λ‹ˆμ¦˜μ„ 톡해 μ„€μΉ˜λœ Fail2Ban
  • [ ] μ½”λ“œλ² μ΄μŠ€μ— μΆ”κ°€ μ™ΈλΆ€ 패치λ₯Ό μ μš©ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.
  • [ ] ꡬ성에 일뢀 μ‚¬μš©μž μ •μ˜κ°€ μˆ˜ν–‰λ˜μ—ˆμŠ΅λ‹ˆλ‹€(μ•„λž˜μ— μ„ΈλΆ€ 정보 제곡).

문제:

μ•ˆλ…•ν•˜μ„Έμš”,

λ‚˜λŠ” μ§€κΈˆ 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λ₯Ό μΆ”κ°€ν•˜μ‹­μ‹œμ˜€.

μ €λ₯Ό λ„μ™€μ£Όμ‹œκ³  이것에 λŒ€ν•΄ μ‘°κΈˆμ΄λ‚˜λ§ˆ λ°ν˜€ μ£Όμ‹œκ² μŠ΅λ‹ˆκΉŒ? - μ–΄λ–»κ²Œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•΄μ•Ό ν•©λ‹ˆκΉŒ? λ‚΄κ°€ 뭘 잘λͺ»ν•˜κ³  있죠?
도움을 μ£Όμ‹œλ©΄ 정말 κ°μ‚¬ν•˜κ² μŠ΅λ‹ˆλ‹€.

3rd party issue

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

μ•„λ§ˆλ„ 당신은 이것을 μ¦‰μ‹œ 식별 ν•  수 μžˆμŠ΅λ‹ˆλ‹€ ...
ꡬ성 쀑 μ‹€νŒ¨: μž‘μ—… μ •μ˜ 'UTM9' 였λ₯˜: '%' λ‹€μŒμ— '%' λ˜λŠ” ...

λ¬Όλ‘  였λ₯˜ λ©”μ‹œμ§€(및 λ¬Έμ„œ)μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ (python) ꡬ성 파일의 % charλŠ” %(var)s λ“±κ³Ό 같은 λ³€μˆ˜ 및 λ§€κ°œλ³€μˆ˜μ˜ λŒ€μ²΄μ— μ‚¬μš©λ˜λŠ” 특수 λ¬Έμžμž…λ‹ˆλ‹€.
λ”°λΌμ„œ λ‹€μŒκ³Ό 같이 (μΆ”κ°€ %둜) μ΄μŠ€μΌ€μ΄ν”„ μ²˜λ¦¬ν•©λ‹ˆλ‹€.

- VAR=${VAR1%?};
+ VAR=${VAR1%%?};

ꡬ성을 μ½μ–΄μ„œ 단일 %-char둜 λ³΄κ°„λ©λ‹ˆλ‹€.

λͺ¨λ“  6 λŒ“κΈ€

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둜 λ³΄κ°„λ©λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰