새 서버를 받으면 보통 서비스부터 올립니다. 웹서버 설치하고 DB 붙이고 소스 올리고, 잘 돌아가는 걸 확인하면 그걸로 끝이죠. 그런데 인터넷에 노출된 서버는 켜진 지 몇 분 만에 자동화된 스캔이 들어옵니다. 서비스를 올리기 전에 먼저 잠가둬야 할 것들이 있어요.

접속 통로부터 좁히기
가장 먼저 볼 것은 SSH입니다. 기본 포트인 22번을 그대로 두면 자동 스캔의 첫 표적이 돼요. 포트를 다른 번호로 옮기는 것만으로도 무작위 대입 시도가 눈에 띄게 줄어듭니다. 물론 포트 변경은 보안 자체가 아니라 소음을 줄이는 조치라, 다음 두 가지를 함께 해야 의미가 있습니다.
하나는 root 직접 로그인 차단입니다. 일반 계정으로 접속한 뒤 필요할 때만 권한을 올리는 방식으로 바꾸면, 공격자가 계정명까지 알아내야 하므로 난이도가 확 올라갑니다. 다른 하나는 비밀번호 대신 키 인증이에요. 키 인증으로 바꾸고 비밀번호 로그인을 아예 꺼두면 무작위 대입 자체가 성립하지 않습니다. 다만 키를 잃어버리면 본인도 못 들어가니, 콘솔 접속 수단을 미리 확인해두고 바꾸세요.
열어둘 포트만 열기

방화벽은 “필요한 것만 열고 나머지는 전부 막는다”가 원칙입니다. 웹 서비스라면 80과 443, 그리고 관리용 SSH 포트 정도면 충분해요. 문제는 설치 과정에서 열어둔 포트를 나중에 닫는 걸 잊는 경우입니다.
특히 데이터베이스 포트가 외부에 열려 있는지 꼭 확인하세요. 웹서버와 DB가 같은 서버에 있다면 DB는 외부에 열려 있을 이유가 전혀 없습니다. 실제로 사고가 나는 경로 중 상당수가 여기입니다. 관리 도구 포트나 개발 중에 띄워둔 임시 서비스 포트도 같이 점검하는 게 좋아요.
컨테이너가 연 통로는 따로 확인하기
Docker로 서비스를 올릴 때는 컨테이너의 포트 공개 설정도 따로 봐야 해요. 기본 브리지 네트워크에서 포트 공개는 컨테이너 안의 포트를 서버 주소에 연결하는 기능입니다. 기본 설정에서 호스트 주소를 생략하고 '-p 8080:80'처럼 실행하면 서버의 모든 주소에 연결돼 외부에서도 접근할 수 있어요. 컨테이너 안에서만 쓰려고 만든 서비스라도 실행 옵션 하나로 공개 범위가 달라지는 셈입니다.
특히 Ubuntu의 UFW를 쓴다면 방화벽 화면만 보고 안심하면 안 돼요. Docker 공식 문서는 공개된 컨테이너 포트의 트래픽이 UFW 규칙을 거치기 전에 다른 경로로 전달돼 해당 차단 설정이 적용되지 않을 수 있다고 설명합니다. 컨테이너를 추가한 뒤에는 포트 연결 설정과 실제 외부 접근 가능 여부를 함께 확인하세요. 서버 내부에서 접속이 된다는 사실만으로 외부 차단까지 확인한 것은 아니에요.
호스트에서만 접근해야 하는 서비스는 기본 NAT 방식의 브리지 네트워크에서 '127.0.0.1:8080:80'처럼 루프백 주소를 명시하는 방법이 있어요. 다만 Docker 28.0.0보다 오래된 버전은 같은 네트워크 스위치에 연결된 다른 장비가 이렇게 공개한 포트에 접근할 수 있다는 공식 경고가 있습니다. 적용 전에는 엔진 버전과 네트워크 모드를 확인하세요. 문제를 피하려고 Docker의 방화벽 규칙 생성 기능을 통째로 끄면 컨테이너 통신이 깨질 수 있어요.

프로그램의 행동 범위도 제한하기
문을 잠근 다음에는 안에서 실행되는 프로그램이 어디까지 접근할 수 있는지도 확인해야 해요. SELinux와 AppArmor는 프로그램의 파일 접근이나 권한 사용을 정책으로 제한하는 보안 기능입니다. 일반적인 파일 권한에 통제를 더하는 방식이라, 서비스에 필요한 범위만 허용하는 데 쓰여요. 사용자 계정에 어떤 권한을 줬는지와 별개로 실행 중인 프로그램에도 경계를 두는 장치라고 생각하면 이해하기 쉽습니다.
여기서는 기능이 켜져 있다는 표시와 실제로 차단한다는 표시를 구분해야 해요. SELinux는 'getenforce' 또는 'sestatus'로 상태를 확인할 수 있습니다. Enforcing은 정책을 적용하지만 Permissive는 위반 내용을 기록하면서 동작을 허용해요. Ubuntu의 AppArmor도 'aa-status'로 확인할 수 있고, 프로필이 enforce 모드인지 complain 모드인지 봐야 합니다. 프로필은 프로그램별 접근 규칙이라, 설치 여부만 확인하고 끝내지 말고 운영할 서비스에 어떤 규칙이 적용되는지도 확인하세요.
서비스가 동작하지 않을 때 이 기능부터 꺼버리면 원인 확인을 위한 변경이 그대로 운영 설정에 남을 수 있어요. Ubuntu 문서는 AppArmor가 막은 동작이 프로그램에서는 엉뚱한 오류처럼 보일 수 있다고 안내합니다. 거부 기록에 나온 프로그램과 대상 경로를 먼저 확인하고 필요한 규칙을 조정하세요. SELinux를 비활성화한 서버는 파일에 보안 라벨이 남지 않아 다시 활성화할 때 재설정이 필요할 수 있으니, 상태 변경 자체도 작업 내용에 기록해두는 게 좋아요.
업데이트와 계정 정리
보안 업데이트는 미루면 쌓입니다. 알려진 취약점은 공개되는 순간부터 자동 공격 도구에 들어가기 때문에, 패치가 늦을수록 위험이 커져요. 서비스 재시작이 부담스러워 미루는 경우가 많은데, 최소한 보안 패치만이라도 정기적으로 적용하는 습관이 필요합니다.
계정도 정리 대상입니다. 테스트용으로 만들었다가 잊은 계정, 퇴사한 담당자 계정, 설치 과정에서 자동 생성된 계정이 그대로 남아 있는 경우가 흔해요. 쓰지 않는 계정은 지우고, 살아 있는 계정은 어떤 권한을 갖고 있는지 확인해두세요. 반대로 아무나 sudo를 쓸 수 있게 열어둔 설정도 위험합니다.
흔적을 남기고 지켜보기

침입 시도는 대부분 로그에 먼저 나타납니다. 인증 실패가 몰리는 시간대나 낯선 IP의 반복 접속 같은 신호를 놓치지 않으려면 로그를 주기적으로 볼 수 있어야 해요. 반복되는 접속 실패를 자동으로 차단해주는 도구를 함께 쓰면 손이 훨씬 덜 갑니다.
그리고 잊기 쉬운 게 디스크 용량 감시입니다. 로그가 쌓여 디스크가 가득 차면 서비스가 통째로 멈추는데, 이건 공격이 아니라도 흔히 겪는 장애예요. 용량 임계치 알림을 걸어두고 로그 순환 설정을 확인해두면 예방됩니다.
마지막으로 백업입니다. 앞의 여섯 가지를 다 해도 뚫릴 가능성은 0이 되지 않아요. 되돌릴 수단이 있느냐가 사고의 크기를 결정합니다. 서버 안에만 있는 백업은 서버가 잘못되면 함께 사라지니, 별도 저장소에 남기는 백업을 꼭 확보하세요.
TIDC는 서버관리 서비스에서 이런 초기 보안 설정과 상시 모니터링을 함께 제공합니다. 운영 인력을 따로 두기 어렵다면 어떤 부분부터 맡기는 게 좋을지 편하게 문의해주세요.