리눅스 서버를 구축하고 인터넷망에 연결한 뒤 방화벽을 켜두었다면 기본적인 방어선은 구축된 셈입니다. 하지만 공격자들의 탐색은 여기서 멈추지 않습니다. 리눅스 서버의 원격 관리를 담당하는 SSH(Secure Shell)의 기본 포트인 22번은 해커들이 가장 먼저, 그리고 가장 집요하게 문을 두드리는 곳입니다.
실제로 서버 로그를 살펴보면 전 세계에서 수많은 봇(Bot)들이 초당 수십 회씩 무작위로 비밀번호를 대입하는 '무차별 대입 공격(Brute Force Attack)'이나 딕셔너리 공격을 감행하고 있음을 알 수 있습니다. 아무리 복잡한 비밀번호를 설정했더라도 비밀번호 기반의 인증 체계를 유지하는 한 유출이나 파쇄의 위험에서 완전히 자유로울 수 없습니다.
연재 두 번째 시간인 이번 글에서는 비밀번호 자체를 아예 없애버리는 'SSH 키(Key) 기반 인증'과, 공격자의 스캔 대상에서 벗어나기 위한 'SSH 포트 변경 및 숨기기' 전략을 실무 예시와 함께 아주 자세히 알아보겠습니다.
SSH 키 기반 인증은 쉽게 말해 '비밀번호'라는 텍스트 방식의 자물쇠를 버리고, 수학적으로 결합된 복잡한 '전자 열쇠' 쌍을 사용하는 방식입니다. 이 방식은 비대칭 암호화(Asymmetric Cryptography) 알고리즘을 기반으로 하며, 다음과 같이 두 개의 키가 하나의 쌍(Pair)을 이룹니다.
공개키 (Public Key): 서버에 저장되는 키입니다. 자물쇠의 역할을 하며, 외부에 공개되어도 아무런 상관이 없습니다.
비밀키 (Private Key): 사용자의 개인 PC(클라이언트)에 안전하게 보관해야 하는 키입니다. 절대 타인에게 노출되어서는 안 되는 실제 '열쇠'입니다.
인증 과정에서 서버는 공개키를 이용해 난수를 암호화하여 클라이언트에 던집니다. 사용자의 PC는 오직 하나뿐인 비밀키로 이를 복사 및 해독하여 자신이 올바른 열쇠의 소유자임을 서버에 증명합니다. 네트워크상으로 비밀번호가 오가지 않기 때문에 중간에 패킷을 가로채더라도 인증 정보를 탈취할 수 없습니다.
그럼 내 PC에서 키를 만들고, 이를 리눅스 서버에 등록하여 비밀번호 없이 로그인하는 과정을 단계별로 진행해 보겠습니다. 여기서는 가장 널리 쓰이는 강력한 알고리즘인 ED25519 방식을 기준으로 설명합니다. (RSA보다 키 길이가 짧으면서도 보안성은 훨씬 뛰어납니다.)
Windows(PowerShell/CMD) 또는 macOS/Linux 터미널을 열고 다음 명령어를 입력합니다.
Bash
ssh-keygen -t ed25519 -C "your_email@example.com"
명령어를 실행하면 키를 저장할 경로를 묻습니다. 기본값(엔터)을 선택하면 사용자의 홈 디렉토리 내 .ssh 폴더에 생성됩니다.
이후 Enter passphrase라는 문구가 나오는데, 이는 비밀키 자체를 한 번 더 암호화할 비밀번호를 설정하는 단계입니다. 비밀키 파일이 유출되더라도 이 패스프레이즈를 알지 못하면 사용할 수 없으므로, 보안을 위해 설정을 권장합니다.
생성이 완료되면 두 개의 파일이 생깁니다.
id_ed25519 : 절대 유출되면 안 되는 비밀키
id_ed25519.pub : 서버에 업로드할 공개키
생성된 공개키(id_ed25519.pub)의 내용을 서버의 접속할 계정 홈 디렉토리 내 .ssh/authorized_keys 파일에 기록해야 합니다. 가장 간단한 방법은 전용 명령어를 사용하는 것입니다.
Bash
# 로컬 PC에서 실행 (sysadmin 계정으로 서버 IP 192.168.1.100에 공개키 전송)
ssh-copy-id -i ~/.ssh/id_ed25519.pub sysadmin@192.168.1.100
만약 ssh-copy-id 명령어를 사용할 수 없는 환경(예: Windows 순정 환경)이라면, 공개키 파일의 텍스트 내용을 직접 복사하여 서버 내부 파일에 수동으로 붙여넣어야 합니다.
Bash
# 서버 내부에서 실행할 내용 (sysadmin 계정 기준)
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "로컬에서 복사한 id_ed25519.pub의 텍스트 내용 전체" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
보안 중요 메모: 리눅스는 권한 관리에 매우 엄격합니다.
.ssh디렉토리는 소유자만 접근 가능하도록700,authorized_keys파일은 소유자만 읽고 쓸 수 있도록600권한이 부여되지 않으면 SSH 데몬이 보안상 위험하다고 판단하여 키 인증을 거부합니다.
키 등록이 완료되었다면 이제 로컬 PC에서 비밀번호 입력 없이 키 인증(또는 패스프레이즈 입력)만으로 로그인이 가능해집니다. 키 기반 로그인이 정상 작동하는 것을 확인했다면, 이제 기존의 취약한 비밀번호 기반 로그인 창 자체를 폐쇄해야 합니다. 아무리 키를 잘 만들어두었어도 비밀번호 문이 열려 있다면 해커들은 여전히 비밀번호 대입 공격을 시도하기 때문입니다.
서버 터미널에서 설정 파일을 엽니다.
Bash
sudo nano /etc/ssh/sshd_config
파일 내부에서 다음 항목들을 찾아 값을 no로 변경합니다. (앞에 주석 기호 #가 있다면 반드시 지워야 합니다.)
Plaintext
# 비밀번호 기반의 인증을 허용하지 않습니다.
PasswordAuthentication no
# 챌린지 응답 인증(일종의 비밀번호 기반 방식)을 차단합니다.
ChallengeResponseAuthentication no
KbdInteractiveAuthentication no
설정을 저장하고 나온 뒤 SSH 데몬을 재시작합니다.
Bash
sudo systemctl restart sshd # 또는 ssh
이전 회차 주의사항 리마인드: 현재 접속 중인 세션을 닫지 마십시오. 새 터미널을 열어 키 파일 없이 일반적인 방법으로 접속을 시도해 봅니다. 서버가 비밀번호 입력을 요구하지 않고
Permission denied (publickey)에러를 뱉으며 접속을 칼같이 거부한다면 성공입니다. 오직 열쇠를 가진 자만이 들어올 수 있는 방이 되었습니다.
키 인증을 적용해 두면 해커가 무차별 대입 공격을 하더라도 뚫릴 확률은 제로에 가깝습니다. 하지만 공격자들이 22번 포트로 끊임없이 접속을 시도하는 것 자체만으로도 서버의 CPU 자원이 낭비되고, 인증 실패 로그가 수 기가바이트(GB)씩 쌓여 디스크 공간을 낭비하는 2차 피해가 발생합니다.
따라서 집 주소를 아예 숨겨버리듯, SSH의 기본 포트인 22번을 1024번 이후의 사설 포트(예: 22022)로 변경하는 것이 효과적입니다.
포트를 변경하기 전에, 바꿀 포트를 방화벽에서 미리 열어두어야 합니다. 방화벽을 열지 않고 SSH 포트를 변경한 뒤 재시작하면 서버에 다시는 영영 접속하지 못하는 대참사가 발생합니다.
Ubuntu (UFW): sudo ufw allow 22022/tcp
Rocky Linux (Firewalld): ```bash
sudo firewall-cmd --permanent --add-port=22022/tcp
sudo firewall-cmd --reload
다시 /etc/ssh/sshd_config 파일을 열어 포트 설정을 변경합니다.
Plaintext
# 기존 #Port 22의 주석을 풀고 변경하거나 아래와 같이 한 줄을 추가합니다.
Port 22022
만약 시스템에 SELinux가 활성화되어 있다면(기본값), SELinux 정책상 SSH는 22번 포트만 사용하도록 고정되어 있어 포트를 바꿔도 SSH가 켜지지 않습니다. SELinux에게 새로운 포트를 알려주어야 합니다. (Ubuntu의 AppArmor 환경에서는 이 단계를 건너뛰어도 됩니다.)
Bash
# semanage 도구가 없다면 설치 (policycoreutils-python-utils)
sudo semanage port -a -t ssh_port_t -p tcp 22022
모든 준비가 끝났다면 SSH 서비스를 재시작합니다.
Bash
sudo systemctl restart sshd
이제 새로운 터미널에서 포트 번호 옵션(-p)을 주어 접속을 테스트합니다.
Bash
# 로컬 PC에서 변경된 포트로 접속 시도
ssh -p 22022 -i ~/.ssh/id_ed25519 sysadmin@192.168.1.100
접속이 완벽하게 이루어진다면, 마지막으로 방화벽에서 기존에 열어두었던 22번 포트 규칙을 삭제하여 외부 통로를 완전히 폐쇄합니다.
이번 시간에 적용한 두 가지 핵심 전략은 서버 보안의 패러다임을 바꿉니다. SSH 키 기반 인증은 해커가 아무리 찍어도 열리지 않는 마스터 자물쇠를 채운 것이며, 포트 변경은 '여기가 SSH 접속로입니다'라고 광고하던 간판을 내려 해커의 자동화 스캔 대상에서 서버를 지워버리는 효과를 줍니다.
실제로 포트만 변경해 두어도 시스템 로그에 찍히던 무차별 접속 시도의 99% 이상이 즉각적으로 사라지는 기적을 경험할 수 있습니다. 시스템 자원을 아끼고, 혹시 모를 패스워드 유출 위협을 근본적으로 거부하는 것, 이것이 리눅스 서버를 안전하게 지키는 두 번째 기본 공식입니다.
다음 3회차에서는 설령 변경된 포트를 알아내어 꾸역꾸역 접속을 시도하는 집요한 공격자가 있을 경우, 비정상적인 로그인 실패를 실시간으로 감시하여 해당 공격자의 IP를 실시간으로 방화벽에 가두어버리는 자동 침입 차단 도구, 'Fail2ban 구축하기'에 대해 상세히 다루어 보겠습니다.