
중요하지 않은 서버라서 보안에 신경 쓰지 않고 있었는데 1,000개 이상 무작위 접속이 확인되어 급하게 처리하게 되었다.
해외 IP 차단을 고민하게 된 계기
해외 SSH 접근을 다시 바라보게 된 시점
CentOS 서버를 일정 기간 운영하다 보면, 특별한 작업을 하지 않아도 SSH 관련 로그가 꾸준히 쌓이는 시점이 찾아옵니다. 접속에 성공하지는 못했지만, 시도 자체는 반복되고 있다는 사실이 눈에 들어오기 시작합니다.
이 글은 해외 SSH 접근을 “차단해야 한다”는 결론을 먼저 세워두고 접근 방법을 나열하는 글은 아닙니다. 오히려 왜 그런 방향으로 인식이 바뀌었는지를 하나씩 정리해보는 기록에 가깝습니다.
방화벽을 켜는 순간 바뀌는 기준
처음에는 단순히 firewalld가 실행 중인지부터 확인하게 됩니다. 서버에 방화벽이 켜져 있지 않다는 사실 자체가 어딘가 허술하게 느껴지는 지점이 되기 때문입니다.
firewall-cmd --state
방화벽이 동작하는 상태로 전환되면, 그다음부터는 “무엇을 막을 것인가”보다 “무엇을 열어둘 것인가”라는 질문이 먼저 떠오르게 됩니다.
SSH를 기본 허용으로 두지 않는다는 선택
SSH 서비스는 편리하지만, 항상 열려 있어야 할 이유는 많지 않아 보였습니다. 그래서 기본 서비스 허용 여부부터 다시 확인하게 됩니다.
firewall-cmd --list-all
이 시점에서 선택한 방향은 단순했습니다. SSH를 기본 허용 서비스로 두지 않고, 필요한 접근만 명시적으로 허용하는 방식입니다.
국가 단위 접근을 고민하게 된 이유
개별 IP를 하나씩 허용하는 방식은 명확하지만, 접속 환경이 고정되지 않은 경우에는 한계가 분명해집니다. 이때 자연스럽게 “국가 단위로 묶을 수는 없을까”라는 생각으로 이어집니다.
이 흐름에서 ipset은 차단 도구라기보다, 참조 가능한 목록으로 인식되었습니다. firewalld가 판단할 기준을 외부로 분리해두는 느낌에 가깝습니다.
한국 IP 대역을 하나의 묶음으로 준비
ipset create allow_region hash:net
이후 APNIC 공개 데이터를 기준으로 특정 국가의 IPv4 대역을 목록에 추가합니다. 명령어 자체보다, “이 목록은 언제든 교체·갱신 가능하다”는 점이 더 중요하게 느껴졌습니다.
허용 규칙만 남기는 구조로의 전환
여러 시행착오 끝에 남은 구조는 의외로 단순했습니다. 차단 규칙을 늘리는 대신, 허용 규칙만 조용히 남기는 방식입니다.
아래와 같은 규칙은, 특정 IP와 특정 IP 묶음만 SSH 접근을 허용합니다.
rule family="ipv4" source address="203.0.113.10/32" service name="ssh" accept
rule family="ipv4" source ipset="allow_region" service name="ssh" accept
이 상태에서는 별도의 drop 규칙이 없어도, 허용되지 않은 접근은 자연스럽게 닫힌 상태로 유지됩니다. 결과적으로 규칙 간 충돌을 고민할 필요가 줄어듭니다.
복잡해 보였던 이유를 돌아보며
해외 SSH 차단이 어렵게 느껴졌던 이유는, 기술적인 난이도보다는 여러 도구의 역할을 한 번에 이해하려 했기 때문으로 보입니다.
firewalld, ipset, fail2ban은 각각의 역할이 분명하지만, 그 경계가 머릿속에서 정리되지 않으면 설정은 쉽게 꼬여 보입니다.
현재 상태를 기록으로 남긴다는 의미
지금의 설정은 완벽한 정답이라기보다, 현 시점에서 납득 가능한 균형점에 가깝습니다. 그리고 이 글은 그 선택의 결과보다, 선택에 이르게 된 흐름을 남기기 위한 기록입니다.
나중에 다시 이 글을 읽게 된다면, “왜 이런 명령어를 썼는지”를 조금은 빠르게 떠올릴 수 있기를 기대해봅니다.