ModSecurity는 오픈 소스 웹 애플리케이션 방화벽(WAF)으로서, 들어오는 HTTP 요청을 분석하여 악의적인 공격 패턴(예: SQL 인젝션, XSS)을 탐지하고 해당 요청을 거부(Deny)하는 역할을 합니다
지속적, 반복적인 공격 시도를 하는 사람을 IP로 차단하기 위해서는 ModSecurity가 남긴 로그를 감시하면서 공격자를 감지, 차단하는 fail2ban이 추가적으로 필요합니다.
또, fail2ban 자체적으로 차단 기능을 가지고 있지는 않기 때문에 iptable이나 firewalld 같은 방화벽 프로그램이 활성화 상태여야 합니다.
ModSecurity 설치 및 사용 방법
(이하의 내용은 CentOS 7 환경을 기준으로 합니다.)
우선 mod_security와 mod_security_crs을 설치해줍니다.
crs(core rule set)는 기본적인 방화벽 규칙의 모음입니다.
# Red Hat 계열 - CentOS, Rocky 등
yum install mod_security mod_security_crs -y
# Debian 계열 - Ubuntu 등
apt-get install libapache2-mod-security2 -y
규칙 설정
crs를 설치한 경우 /etc/httpd/modsecurity.d 경로에 기본 보안 규칙이 생성되어 있을 것입니다.
이 설정을 직접 수정하여 사용할 수도 있지만,
방화벽에 의해서 사용자의 정상적인 요청이 차단되어서는 안 된다는 점도 중요한 부분이기 때문에 crs를 사용하는 대신 새로 규칙을 만들기로 했습니다.
저같은 경우는 한글이나 쿠키의 내용이 계속 탐지에 걸리더군요.
만약 기존에 공격을 당한 로그가 있다면 해당 패턴을 ai에게 넘겨주면 규칙을 생성해줍니다.
물론 꼼꼼한 테스트 및 점검은 필수입니다.
vi /etc/httpd/modsecurity.d/basic.conf
# SQL Injection 패턴 차단
SecRule ARGS "@detectSQLi" \
"id:1001,\
phase:2,\
deny,\
msg:'SQL Injection Attack Detected',\
logdata:'Matched Data: %{MATCHED_VAR} found within %{MATCHED_VAR_NAME}',\
tag:'attack-sqli',\
severity:CRITICAL"
# Time-based SQL Injection 차단
SecRule ARGS "@rx (?i:(sleep|waitfor|delay|benchmark)\s*\()" \
"id:1002,\
phase:2,\
deny,\
msg:'Time-based SQL Injection Attack',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-sqli',\
severity:CRITICAL"
# PostgreSQL sleep 함수 차단
SecRule ARGS "@rx (?i:pg_sleep\s*\()" \
"id:1003,\
phase:2,\
deny,\
msg:'PostgreSQL Sleep Function Detected',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-sqli',\
severity:CRITICAL"
# SQL 주석 패턴 차단
SecRule ARGS "@rx (?i:--\s*\/\*|\*\/|\/\*.*\*\/)" \
"id:1004,\
phase:2,\
deny,\
msg:'SQL Comment Pattern Detected',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-sqli',\
severity:HIGH"
# DECLARE/SET 구문 차단
SecRule ARGS "@rx (?i:declare\s*.*\s*char|set\s*.*\s*char)" \
"id:1005,\
phase:2,\
deny,\
msg:'SQL DECLARE/SET Statement Detected',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-sqli',\
severity:CRITICAL"
# 괄호를 이용한 SQL 구문 차단
SecRule ARGS "@rx \)\s*;\s*(SELECT|INSERT|UPDATE|DELETE|DROP)" \
"id:1006,\
phase:2,\
deny,\
msg:'SQL Statement After Closing Parenthesis',\
logdata:'Matched Data: %{MATCHED_VAR}',\
tag:'attack-sqli',\
severity:CRITICAL"
또 관리자, 테스트 사용자의 ip가 차단되는 것을 막기 위해 화이트리스트를 만들어 줍니다.
vi /etc/httpd/modsecurity.d/whitelist.conf
SecRule REMOTE_ADDR "@ipMatch 192.168.1.100" \
"id:2001,\
phase:1,\
pass,\
ctl:ruleEngine=Off,\
msg:'Admin IP whitelist'"
기본 설정 파일
이제 위에서 생성한 규칙을 기본 설정 파일에 적용해 줍니다.
규칙을 정의한 conf 파일을 포함하는 방식으로 간단하게 적용이 가능합니다.
vi /etc/httpd/conf.d/mod_security.conf
#IncludeOptional modsecurity.d/* #crs 설정 파일은 제외
IncludeOptional modsecurity.d/basic.conf
IncludeOptional modsecurity.d/whitelist.conf
SecRuleEngine DetectionOnly
#SecRuleEngine On
SecAuditLog /var/log/httpd/modsec_audit.log # 로그 파일 경로
SecRuleEngine을 DetectionOnly 모드로 설정하면 차단은 되지 않고, 감지된 내역을 확인할 수 있습니다.
apachectl configtest
apachectl graceful
tail -f /var/log/httpd/modsec_audit.log
변경 사항을 적용해 주고, 로그를 모니터링하면서 먼저 정상적인 사용이 감지되지는 않는지 테스트합니다.
문제가 없다면 On으로 변경하여 차단이 되도록 한 뒤, 다시 graceful 또는 restart를 통해 설정을 적용합니다.
Fail2ban 설치 및 사용 방법
# Red Hat
yum install fail2ban -y
# Devian
apt-get install fail2ban -y
기본 설정 파일은 jail.conf이지만 안전하게 설정 파일을 복사해서 사용합니다
jail.conf에서는 감시할 대상을 '감옥' 단위로 설정할 수 있습니다.
우리에게 필요한 HTTP servers 섹션을 보면 [apache-modsecurity] 가 있습니다.
이 곳에 enabled = true를 추가하면 해당 감옥이 활성화됩니다.
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
vi /etc/fail2ban/jail.local
#
# JAILS
#
#
# SSH servers
#
[sshd]
# To use more aggressive sshd modes set filter parameter "mode" in jail.local:
# normal (default), ddos, extra or aggressive (combines all).
# See "tests/files/logs/sshd" or "filter.d/sshd.conf" for usage example and details.
#mode = normal
port = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s
#
# HTTP servers
#
[apache-auth]
port = http,https
logpath = %(apache_error_log)s
...
[apache-modsecurity]
enabled = true
port = http,https
logpath = %(apache_error_log)s
maxretry = 5
bantime = 48h
maxretry는 감지 패턴에 대응되는 행동을 몇 번 반복했을 때 차단할 것인지를 말하고
bantime은 차단하는 시간입니다.
위와 같이 설정할 경우 5번 공격 시도를 하면 48시간 동안 차단이 됩니다.
잠시 다른 감옥들을 구경해보면,
[apache-auth] 는 HTTP 인증 실패 기록을 감시하고
[apache-badbots] 은 알려진 악성봇을 감지합니다.
[apache-nosciprt] 는 존재하지 않는 스크립트 요청을 감지합니다.
필요에 따라 적절히 추가해주면 되겠습니다.
systemctl enable fail2ban
systemctl start fail2ban
systemctl status fail2ban
설정이 완료되면 fail2ban을 실행하고 상태를 확인합니다.
fail2ban-client status
tail -f /var/log/fail2ban.log
설정한 대로 감옥들이 잘 활성화되었는지 확인하고
실시간으로 차단되는 내역을 모니터링합니다.
iptables 활성화
iptables는 커널에 내장된 유틸리티이므로 별도로 설치가 필요하진 않습니다.
아래와 같이 상태를 확인한 뒤, enabled active가 아니라면 활성화해줍니다.
systemctl status iptables
systemctl enbale iptables
systemctl start iptables
차단 내역을 확인하려면 다음 명령을 입력합니다.
iptables -L -n --line-numbers
차단 해제
일반 사용자가 차단된 경우라면 빠르게 해제를 해주어야 합니다.
fail2ban을 이용해 차단 내역 확인 및 차단 해제가 가능합니다
fail2ban-client status apache-modsecurity
fail2ban-client set apache-modsecurity unbanip 192.168.1.100
iptables를 이용하여 차단을 해제할 수도 있습니다.
iptables에는 Chain 별로 규칙들이 정의되어 있습니다.
Chain f2b-apache-modsecurity (1 references)
num target prot opt source destination
1 REJECT all -- 192.168.1.100 0.0.0.0/0 reject-with icmp-port-unreachable
2 RETURN all -- 0.0.0.0/0 0.0.0.0/0
여기서 1번 규칙을 삭제하면 192.168.1.100에 대한 차단이 해제됩니다.
iptables -D f2b-apache-modsecurity 1 #f2b-apache-modsecurity 체인의 1번 라인을 삭제
권장하지는 않으나 아래와 같이 파일을 직접 편집하는 것도 가능합니다. 다만, 수정 후 iptables를 재시작해야 변경된 규칙이 적용됩니다.
vi /etc/sysconfig/iptables
systemctl restart iptables
'Linux Unix' 카테고리의 다른 글
| Postfix error: File too large (0) | 2025.02.21 |
|---|---|
| Swatch로 로그 모니터링, 메일 발송하기 (0) | 2024.09.04 |
| Ubuntu Server에서 Wifi가 잡히지 않을 때 (1) | 2023.10.12 |
| [Linux] chmod로 권한 변경하기 (0) | 2023.02.20 |
| 리눅스 (AWS) - 스왑 메모리 설정 방법 (0) | 2022.08.03 |
댓글