OpenVPN Access Server용 Fail2ban 필터: real_ip와 jail
Access Server는 자체 로그 형식을 쓰기 때문에 기본 필터로는 아무것도 잡히지 않습니다. real_ip에 고정하고, jail을 접점별로 나누고, 주소가 프록시인지 확인하세요.
커뮤니티 글에서 OpenVPN jail을 복사하고 fail2ban을 다시 시작했지만 어떤 주소도 차단되지 않습니다. 원인은 거의 항상 로그 형식입니다. Access Server는 기본 필터가 기대하는 인증 실패 줄을 쓰지 않습니다. 필터를 건드리기 전에 기록이 실제로 있는지 확인하세요. 서비스가 한 번도 기록하지 않은 것에는 패턴이 일치할 수 없습니다.
제가 Access Server 호스트에서 따르는 절차는 이렇습니다. 기록의 모양을 확인하고, 고정된 표현식을 하나 작성하고, 실제 로그로 시험하고, 공격받는 접점별로 jail을 나눈 뒤 차단이 방화벽까지 도달하는지 확인합니다.
실패 기록이 있는지 확인하세요
Access Server는 자체 구조화된 줄을 /var/log/openvpnas.log에 기록하고, 클라이언트 주소는 syslog 줄 맨 앞이 아니라 따옴표로 감싼 real_ip 필드에 있습니다. 패턴을 쓰기 전에 실제로 일어난 것을 아는 실패 로그인을 찾아보세요:
grep -i 'LOG ERR' /var/log/openvpnas.log | tail -20아무것도 나오지 않으면 다음 용의자는 로그 수준입니다. Access Server에는 /usr/local/openvpn_as/etc/as.conf 파일에 로그 데이터베이스 디버그 스위치가 있고(DEBUG_LOGDB=1), 이를 바꾼 뒤에는 서비스를 다시 시작해야 합니다. 그 스위치는 패턴이 완성되면 다시 내려야 하는 진단용 설정으로 다루고, 영구 설정으로 여기지 마세요.
파일을 보는 김에 어떤 접점이 그 파일에 기록하는지 확인하세요. 클라이언트 포털, 관리자 인터페이스, 터널 인증의 실패는 같은 파일에 서로 다른 표식으로 들어가고, 이 차이가 나중에 jail 구성을 결정합니다.
real_ip에 필터 하나를 고정하세요
표현식을 좁게 유지하세요. IP 주소가 들어간 모든 줄을 차지하는 필터는 평범한 연결 끊김에도 사람을 차단하고, 바쁜 서버에서는 노트북을 닫았다는 이유로 잠겼다는 불만만이 유일한 증상이 됩니다. 오류 기록만 차지하고 따옴표 안의 주소를 캡처하세요:
# /etc/fail2ban/filter.d/openvpnaccess.local
[Definition]
failregex = ^ .*LOG ERR.*"real_ip": "<HOST>".*
ignoreregex =맨 앞의 공백은 장식이 아닙니다. Access Server는 기록을 들여 쓰므로, 그 지점에 고정하면 같은 파일에 기록하는 무관한 서비스의 줄까지 차지하는 것을 막을 수 있습니다. 기록이 대신 맨 앞에 타임스탬프를 가진다면 그 접두사에 맞추되, 차지하려는 모든 기록에 실제로 존재하는 것에 고정하세요.
접점별 정밀도가 필요하면 같은 줄에 접점 표식(WEB_CLIENT, WEB_ADMIN, VPN)을 요구해 더 좁히세요. 패턴 세 개를 가진 필터 하나가 한 단어만 다른 필터 세 개보다 검사하기 쉽습니다.
jail을 켜기 전에 표현식을 시험하세요
운영 로그에 실행해 보지 않은 필터는 절대 켜지 마세요. 문서화된 시험은 필터를 두 번 넘깁니다. 한 번은 불러오기, 한 번은 적용을 위해서이고, 놓친 줄 보고서가 읽을 가치가 있는 부분입니다.
fail2ban-regex --print-all-missed /var/log/openvpnas.log \
/etc/fail2ban/filter.d/openvpnaccess.local \
/etc/fail2ban/filter.d/openvpnaccess.local > missed.txt첫 단계에서 확인한 실패와 일치 건수를 비교하세요. 일치가 없으면 패턴이 틀린 것입니다. 인증 실패가 아닌 줄에 일치하면 너무 넓은 것입니다. 차지하지 않기로 한 모든 줄을 설명할 수 있을 때까지 missed.txt를 읽으세요.
로그가 크면 사본에서 이 시험을 하고, Access Server를 업그레이드할 때마다 다시 실행하세요. 로그 형식은 대조하는 인터페이스이며 안정적인 API가 아닙니다.
jail은 데몬이 아니라 접점으로 나누세요
Access Server 하나가 여러 인증 접점을 제공합니다. 클라이언트와 관리자 웹 인터페이스는 943/tcp, 터널은 대부분의 배포에서 1194/udp 또는 443/tcp입니다. 모두를 덮는 jail 하나는 터널에서의 추측 시도가 관리자 경로이기도 한 주소를 차단하게 만들고, 어느 접점이 실제로 공격받는지 감춥니다. 접점마다 자체 포트와 임계값을 가진 jail을 주세요:
# /etc/fail2ban/jail.d/openvpnaccess.local
[openvpnas-web-client]
enabled = true
port = 943
protocol = tcp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 3
findtime = 10m
bantime = 1h
[openvpnas-tunnel]
enabled = true
port = 443
protocol = udp
filter = openvpnaccess
logpath = /var/log/openvpnas.log
maxretry = 5
findtime = 10m
bantime = 1h작은 카운터와 짧은 차단으로 시작하고, 일주일의 실제 트래픽을 지켜본 뒤 올리세요. 공유 사무실 주소에 관대한 임계값을 두면 하나의 NAT 뒤에 있는 모든 사용자가 벌을 받고, 터널 접점의 공격적인 차단은 밤사이 자격 증명이 만료된 정상 클라이언트를 끊습니다.
차단, 백엔드, 부작용을 확인하세요
다시 시작한 뒤에는 상태 출력이 jail이 존재하고 집계하는지 확인하는 가장 빠른 방법입니다.
fail2ban-client status
fail2ban-client status openvpnas-tunnel그다음 차단이 실제로 운영하는 방화벽까지 도달하는지 확인하세요. 아무도 적용하지 않는 백엔드로 설정한 jail은 아무것도 보호하지 않습니다. iptables 액션이면 주소가 jail 이름을 딴 체인에 나타나고(f2b-openvpnas-tunnel), nftables 액션이면 fail2ban 자체 테이블의 집합에 들어갑니다. 가정하지 말고 호스트가 쓰는 쪽을 확인하세요.
부작용 점검 두 가지가 차단 자체보다 중요합니다. 첫째, real_ip가 클라이언트 주소이며 로드 밸런서나 리버스 프록시가 아닌지 확인하세요. 프록시 뒤에서는 모든 차단이 프록시에 걸리고 서비스 전체를 함께 끌고 내려갑니다. 둘째, 차단 해제 절차를 적어 두세요. 02:00에 임계값을 넘는 주소는 대개 당직 엔지니어의 것입니다: fail2ban-client set openvpnas-tunnel unbanip 203.0.113.24.
조정할 때 경계를 염두에 두세요. Fail2ban은 한 인증 접점의 속도 제한기이며 접근 제어 계층이 아닙니다. MFA, 계정별 제한, 관리자 인터페이스를 공용 인터넷에서 떼어 두는 일을 대신하지 못하며, Access Server에는 자체 autoban 설정이 있으므로 같은 포트에 두 개의 속도 제한기를 쌓기 전에 확인할 가치가 있습니다.