서버 초기 보안 강화: 반드시 비활성화해야 할 기본 설정 변경 실전 루틴
서버를 처음 구축할 때, 많은 분들이 최신 기술이나 복잡한 솔루션에 집중하기 쉽습니다. 하지만 제가 여러 해 동안 서버를 운영하며 깨달은 가장 중요한 사실은, 바로 '서버 보안을 위해 반드시 꺼야 하는 기본 설정들'의 중요성입니다. 기본적인 부분에서 발생한 작은 취약점이 결국 큰 보안 문제로 이어지는 것을 여러 번 직접 겪었습니다. 초기 설정 단계에서 편리함을 위해 기본값으로 두었던 사소한 부분이 예상치 못한 공격의 통로가 되곤 했습니다. 이 글에서는 제가 직접 확인하고 조치했던, 서버 보안을 위해 반드시 비활성화하거나 변경해야 할 기본 설정들과 그 해결 방법을 공유하고자 합니다. 이는 단순히 '해야 한다'는 지시가 아니라, '내가 직접 해보니' 정말 중요하고 효과적이었던 실전 루틴입니다.
1. SSH 기본 포트 변경 및 Root 로그인 비활성화 전략
제가 직접 겪은 문제: 초보 시절, SSH 기본 포트인 22번을 그대로 사용하다가 무수히 많은 무작위 대입 공격(Brute-force attack) 시도를 로그에서 발견했습니다. 서버 자원을 불필요하게 소모하고 심리적으로 불안감을 주었죠. 또한, root 계정으로 직접 로그인하는 습관은 관리 실수 시 치명적인 결과를 초래할 수 있었습니다. 해결 방법:- SSH 포트 변경: `/etc/ssh/sshd_config` 파일에서 `Port 22`를 다른 임의의 높은 번호(예: 22222)로 변경했습니다.
- Root 로그인 비활성화: 같은 파일에서 `PermitRootLogin yes`를 `PermitRootLogin no`로 변경하고, 일반 사용자 계정으로 로그인 후 `sudo`를 사용하는 방식으로 전환했습니다.
- 핵심 전략: 변경 후에는 반드시 새 포트로 접속 테스트를 완료한 후 기존 세션을 종료해야 합니다. 실수로 접속이 끊기면 다시 연결하기 어려울 수 있습니다.
2. 불필요한 서비스 및 데몬 제거/비활성화 실전 루틴
제가 직접 겪은 문제: 서버에 설치된 운영체제는 기본적으로 다양한 서비스(telnet, rsh, rlogin 등)를 포함하고 있습니다. 제가 필요하지 않은데도 기본으로 활성화되어 있던 이 서비스들이 잠재적인 공격 벡터가 될 수 있음을 알게 되었습니다. 불필요한 서비스는 더 많은 패치 관리를 필요로 하며, 알려지지 않은 취약점이 발견될 가능성을 높였습니다. 해결 방법:- 서비스 목록 확인: `systemctl list-units --type=service --state=running` 명령으로 현재 실행 중인 서비스를 확인했습니다.
- 불필요한 서비스 비활성화: telnet, rsh, rlogin, nfs 등 사용하지 않는 서비스를 `sudo systemctl disable --now [서비스명]` 명령으로 비활성화하고 제거했습니다.
- 핵심 전략: 어떤 서비스가 필요한지 명확히 파악하는 것이 중요합니다. 불필요하다고 판단되는 서비스는 과감히 비활성화하거나 제거하여 공격 표면(attack surface)을 최소화했습니다.
3. 웹 서버(Apache/Nginx) 기본 설정 강화: 디렉터리 리스팅 방지 및 불필요한 모듈 제거 주의사항
제가 직접 겪은 문제: 웹 서버를 처음 설정할 때, `index.html` 파일이 없는 디렉터리에 접속했을 때 파일 목록이 그대로 노출되는 '디렉터리 리스팅' 문제에 직면했습니다. 이는 웹 사이트의 구조를 노출하고 민감한 파일에 접근할 수 있는 경로를 제공할 수 있어 매우 위험했습니다. 또한, 사용하지 않는 웹 서버 모듈이 로드되어 성능 저하와 보안 취약점 증가의 원인이 되기도 했습니다. 해결 방법:- Apache 디렉터리 리스팅 방지: `.htaccess` 파일이나 가상 호스트 설정에 `Options -Indexes`를 추가하여 디렉터리 리스팅을 비활성화했습니다.
- Nginx 디렉터리 리스팅 방지: Nginx 설정 파일에서 `autoindex on;` 지시어를 `autoindex off;`로 변경했습니다.
- 불필요한 모듈 제거/비활성화: Apache의 경우 `a2dismod` 명령, Nginx의 경우 컴파일 옵션 조정을 통해 사용하지 않는 모듈을 제거하거나 비활성화하여 서버의 경량화와 보안을 동시에 확보했습니다.
- 핵심 전략: 웹 서버 설정은 외부 노출이 가장 심한 부분이므로, `ServerTokens Prod`, `ServerSignature Off` 등 서버 정보 노출을 최소화하는 설정도 함께 적용했습니다.
4. 데이터베이스(MySQL/PostgreSQL) 기본 계정 및 원격 접속 설정 보안 강화
제가 직접 겪은 문제: 데이터베이스 설치 후 `root`와 같은 기본 계정의 비밀번호를 설정하지 않거나 너무 단순하게 설정하여 무방비 상태로 방치했던 경험이 있습니다. 또한, 불필요하게 외부에서의 원격 접속을 허용하여 데이터베이스가 공격에 직접 노출될 위험을 키웠습니다. 해결 방법:- 기본 계정 비밀번호 강화: MySQL의 경우 `mysql_secure_installation` 스크립트를 실행하여 root 비밀번호를 설정하고 익명 사용자 및 테스트 데이터베이스를 제거했습니다. PostgreSQL의 경우 `postgres` 사용자 비밀번호를 즉시 변경했습니다.
- 원격 접속 제한: 데이터베이스 설정 파일(MySQL의 `my.cnf`, PostgreSQL의 `postgresql.conf`)에서 `bind-address` 또는 `listen_addresses`를 `127.0.0.1`(로컬 호스트만 허용)으로 설정하여 내부에서만 접근 가능하도록 제한했습니다. 외부 접근이 필요한 경우, 특정 IP만 허용하도록 방화벽 규칙을 적용했습니다.
- 핵심 전략: 데이터베이스는 가장 민감한 정보가 저장되는 곳이므로, 접속 권한을 최소화하고 강력한 비밀번호 정책을 적용하는 것이 필수적입니다.
5. 방화벽(iptables/firewalld) 기본 정책 수립 및 포트 제어 핵심 전략
제가 직접 겪은 문제: 서버를 처음 구축했을 때, 방화벽 설정을 제대로 하지 않아 모든 포트가 외부에 열려 있었습니다. 이는 서버를 무방비 상태로 인터넷에 노출하는 것과 같았고, 언제든 침입의 대상이 될 수 있음을 뒤늦게 깨달았습니다. 필요한 포트만 개방하고 나머지는 차단하는 것이 얼마나 중요한지 직접 경험했습니다. 해결 방법:- 기본 정책 설정: `INPUT` 정책은 `DROP` 또는 `REJECT`로 설정하여 기본적으로 모든 외부 접속을 차단했습니다.
- 필요한 포트만 개방: SSH(변경한 포트), 웹 서비스(80, 443), 데이터베이스(내부 전용) 등 실제로 필요한 서비스 포트만 명시적으로 허용하는 규칙을 추가했습니다.
- 도구 활용: CentOS/RHEL 계열에서는 `firewalld`, Debian/Ubuntu 계열에서는 `ufw`나 `iptables`를 사용하여 규칙을 효율적으로 관리했습니다.
- 핵심 전략: 방화벽은 서버의 가장 바깥 방어선입니다. 운영에 필요한 최소한의 포트만 열고 나머지는 모두 닫아 외부 공격으로부터 서버를 보호하는 것이 핵심입니다.