Linux 서버를 운영하는 시스템 엔지니어에게 원격 접속 기술은 가장 기본적이면서도 중요한 기술입니다. 실제 서버는 데이터센터나 클라우드 환경에 위치하는 경우가 많기 때문에 관리자가 직접 서버 앞에 앉아서 작업하는 것보다 SSH를 이용해 원격으로 접속하는 경우가 대부분입니다.
하지만 SSH는 단순히 서버에 접속하기 위한 기능만을 의미하지 않습니다. 외부 네트워크에 연결된 Linux 서버에서는 SSH 자체가 공격 대상이 될 수 있기 때문에 계정 관리, 인증 방식, Root 로그인 제한, 방화벽, 접근 제어, 로그 분석까지 함께 이해해야 합니다.
이번 글에서는 Rocky Linux와 같은 Linux 서버를 기준으로 SSH 원격 접속의 기본 원리부터 실무적인 보안 설정과 장애 분석 방법까지 단계적으로 알아보겠습니다.
SSH는 Secure Shell의 약자로 네트워크를 통해 원격 서버에 안전하게 접속하기 위한 프로토콜입니다.
과거에는 Telnet과 같은 원격 접속 방식도 많이 사용했지만 Telnet은 통신 내용이 암호화되지 않는다는 문제가 있었습니다.
반면 SSH는 통신 내용을 암호화하기 때문에 서버 관리자가 원격으로 명령어를 실행하거나 파일을 전송할 때 안전하게 사용할 수 있습니다.
일반적인 SSH 접속 구조는 다음과 같습니다.
관리자 PC
|
| SSH
| TCP 22
↓
Linux Server
|
└── sshd
Linux 서버에서는 SSH 서버 프로그램인 sshd가 클라이언트의 접속 요청을 받아 인증을 처리합니다.
SSH의 기본 TCP 포트는 22번입니다.
Linux 서버에서 SSH 서비스가 실행되고 있는지 확인하려면 다음과 같이 사용할 수 있습니다.
systemctl status sshd
포트가 실제로 열려 있는지 확인하려면 다음 명령어도 사용할 수 있습니다.
ss -lntp | grep :22
예를 들어 다음과 같은 결과가 나온다면 SSH 서버가 TCP 22번 포트에서 연결을 기다리고 있다는 의미입니다.
LISTEN 0 128 0.0.0.0:22
다만 서버가 포트 22에서 LISTEN 중이라고 해서 외부에서 반드시 접속할 수 있는 것은 아닙니다.
방화벽이나 클라우드 보안 그룹, 네트워크 ACL 등의 접근 제어 정책도 함께 확인해야 합니다.
SSH 서버의 주요 설정 파일은 다음과 같습니다.
/etc/ssh/sshd_config
설정 파일을 수정하기 전에 반드시 백업하는 습관을 들이는 것이 좋습니다.
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
SSH 설정을 변경한 후에는 문법 오류가 없는지 먼저 확인해야 합니다.
sshd -t
오류가 없다면 SSH 서비스를 다시 로드하거나 재시작할 수 있습니다.
systemctl reload sshd
운영 서버에서는 SSH 연결을 유지한 상태에서 설정을 변경하고, 새로운 터미널에서 실제 접속이 정상적으로 되는지 확인한 후 기존 세션을 종료하는 것이 안전합니다.
잘못된 SSH 설정으로 기존 접속까지 종료되면 원격 서버에 다시 접근하기 어려워질 수 있기 때문입니다.
가장 기본적인 SSH 인증 방식은 아이디와 비밀번호를 입력하는 방법입니다.
예를 들어 다음과 같이 접속합니다.
ssh user@192.168.1.100
이 방식은 편리하지만 인터넷에 직접 노출된 서버에서는 보안상 주의가 필요합니다.
공격자는 자동화된 프로그램을 이용해 다음과 같은 공격을 반복할 수 있습니다.
admin
root
test
user
oracle
postgres
등의 계정을 대상으로 수많은 비밀번호를 시도하는 방식입니다.
이를 Brute Force Attack, 즉 무차별 대입 공격이라고 합니다.
따라서 운영 서버에서는 단순한 비밀번호 인증에만 의존하지 않는 것이 좋습니다.
SSH 보안을 강화하는 대표적인 방법이 공개키 인증 방식입니다.
SSH 키는 일반적으로 다음 두 개로 구성됩니다.
Private Key
Public Key
개인키는 관리자의 PC에 보관하고 공개키는 서버에 등록합니다.
구조는 다음과 같습니다.
관리자 PC
├── Private Key
└── Public Key
|
↓
Linux Server
└── authorized_keys
중요한 점은 개인키를 서버에 복사하지 않는 것입니다.
개인키는 원칙적으로 사용자 자신의 안전한 장치에 보관해야 합니다.
Linux 또는 macOS에서는 일반적으로 ssh-keygen을 사용할 수 있습니다.
ssh-keygen -t ed25519
생성된 키는 일반적으로 사용자의 SSH 디렉터리에 저장됩니다.
~/.ssh/
├── id_ed25519
└── id_ed25519.pub
여기서
id_ed25519
는 개인키이고,
id_ed25519.pub
는 공개키입니다.
개인키는 절대로 다른 사람에게 전달해서는 안 됩니다.
공개키를 서버에 등록하면 비밀번호 대신 SSH 키를 이용해 로그인할 수 있습니다.
일반적으로 다음 명령어를 사용할 수 있습니다.
ssh-copy-id user@server-ip
또는 서버의 다음 파일에 공개키를 직접 등록할 수도 있습니다.
~/.ssh/authorized_keys
권한도 중요합니다.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
소유권 역시 해당 사용자로 설정되어 있어야 합니다.
chown -R user:user ~/.ssh
잘못된 권한이나 소유권 때문에 정상적인 SSH 키가 있는데도 로그인이 실패하는 경우가 실제 운영 환경에서 상당히 많습니다.
SSH 키 인증이 정상적으로 동작하는 것을 확인했다면 비밀번호 인증을 제한하는 방법을 고려할 수 있습니다.
/etc/ssh/sshd_config에서 다음 설정을 사용할 수 있습니다.
PasswordAuthentication no
그리고 설정을 검사합니다.
sshd -t
문제가 없다면 SSH 서비스를 reload합니다.
systemctl reload sshd
단, 키 인증이 실제로 정상 작동하는 것을 확인하기 전에 비밀번호 인증을 먼저 차단하면 안 됩니다.
원격 서버에서 잘못 설정하면 관리자가 서버에 접근하지 못하는 상황이 발생할 수 있습니다.
Linux 서버 보안에서 매우 중요한 설정 중 하나가 Root의 직접적인 SSH 로그인을 제한하는 것입니다.
SSH 설정에서 다음과 같은 설정을 사용할 수 있습니다.
PermitRootLogin no
이렇게 하면 Root 계정으로 직접 SSH 로그인하는 것을 차단할 수 있습니다.
대신 일반 사용자로 로그인한 후 필요한 경우 sudo를 사용합니다.
ssh admin@server-ip
로그인한 뒤
sudo systemctl restart nginx
와 같은 방식으로 관리자 권한을 획득합니다.
이 방식은 어떤 사용자가 관리자 작업을 수행했는지 추적하는 데도 도움이 됩니다.
운영 서버에서는 모든 작업을 Root 계정으로 수행하는 것보다 필요한 작업에만 관리자 권한을 사용하는 것이 좋습니다.
예를 들어 일반 사용자에게 sudo 권한을 부여하고 다음과 같이 사용합니다.
sudo systemctl status sshd
현재 sudo 권한을 확인하려면
sudo -l
을 사용할 수 있습니다.
시스템 엔지니어에게 중요한 것은 단순히 Root 권한을 얻는 방법이 아니라 **최소 권한 원칙(Least Privilege)**을 적용하는 것입니다.
필요한 사람에게 필요한 권한만 제공하는 것이 서버 보안의 기본입니다.
SSH 기본 포트인 22번을 다른 포트로 변경하는 방법도 있습니다.
예를 들어
Port 2222
와 같이 설정할 수 있습니다.
그러나 포트 변경만으로 SSH가 안전해지는 것은 아닙니다.
공격자가 포트 스캔을 수행하면 변경된 포트도 발견할 수 있기 때문입니다.
따라서 포트 변경은 보안 강화의 보조적인 수단으로 이해해야 합니다.
더 중요한 것은 다음과 같은 접근 제어입니다.
SSH Key 인증
Root 로그인 제한
방화벽
접속 가능 IP 제한
Fail2ban
로그 모니터링
Linux 서버에서는 방화벽을 통해 SSH 접근을 제한할 수 있습니다.
Rocky Linux에서는 firewalld가 대표적인 방화벽 관리 도구입니다.
현재 상태 확인:
systemctl status firewalld
SSH 서비스가 허용되어 있는지 확인:
firewall-cmd --list-services
SSH 서비스를 허용하려면 일반적으로 다음과 같이 사용할 수 있습니다.
firewall-cmd --permanent --add-service=ssh
firewall-cmd --reload
현재 방화벽 설정을 확인합니다.
firewall-cmd --list-all
운영 서버가 특정 사무실이나 VPN 네트워크에서만 관리되는 환경이라면 SSH 접근 자체를 특정 네트워크로 제한하는 것이 더욱 효과적입니다.
예를 들어
인터넷 전체
X
|
방화벽
|
관리 네트워크
|
SSH Server
와 같은 구조를 만들 수 있습니다.
이렇게 하면 인터넷의 모든 사용자가 SSH 포트에 접근할 수 있는 구조보다 공격 표면을 크게 줄일 수 있습니다.
클라우드 환경에서는 서버 내부 방화벽뿐 아니라 Security Group, Network ACL 등의 네트워크 정책도 함께 확인해야 합니다.
인터넷에 노출된 SSH 서버에서는 반복적인 로그인 실패가 발생할 수 있습니다.
이때 사용할 수 있는 대표적인 도구가 Fail2ban입니다.
Fail2ban은 로그를 분석하여 반복적으로 인증에 실패하는 IP 주소를 탐지하고 일정 시간 동안 차단하는 방식으로 동작합니다.
구조를 단순화하면 다음과 같습니다.
공격자
↓
SSH 로그인 반복 시도
↓
sshd
↓
로그 기록
↓
Fail2ban 분석
↓
IP 차단
Fail2ban은 침입 자체를 완전히 막는 도구라기보다 반복적인 자동 공격을 줄이는 보조적인 방어 수단으로 이해하는 것이 좋습니다.
시스템 엔지니어에게 매우 중요한 부분입니다.
SSH 접속에 문제가 발생하면 가장 먼저 로그를 확인해야 합니다.
systemd 기반 Linux에서는 다음과 같이 확인할 수 있습니다.
journalctl -u sshd
실시간 로그를 확인하려면
journalctl -u sshd -f
를 사용할 수 있습니다.
배포판과 설정에 따라 인증 관련 로그가 별도의 파일에 기록될 수도 있습니다.
예를 들어
/var/log/secure
파일을 확인할 수 있습니다.
tail -f /var/log/secure
예를 들어 사용자가 SSH 접속을 시도했는데 다음과 같은 오류가 발생했다고 가정해 보겠습니다.
Permission denied
이때 무조건 비밀번호부터 바꾸는 것이 아니라 다음 순서로 확인하는 것이 좋습니다.
1. 서버 네트워크 연결 확인
↓
2. SSH 포트 접근 가능 여부 확인
↓
3. sshd 서비스 상태 확인
↓
4. sshd_config 확인
↓
5. 사용자 계정 상태 확인
↓
6. SSH Key 및 권한 확인
↓
7. SELinux 정책 확인
↓
8. 방화벽 확인
↓
9. SSH 로그 확인
이러한 순서로 원인을 좁혀가는 것이 시스템 엔지니어의 기본적인 장애 분석 방법입니다.
로그에서는 다음과 같은 내용을 확인할 수 있습니다.
Accepted
Failed password
Invalid user
authentication failure
Connection closed
Disconnected
예를 들어 반복적으로 다음과 같은 로그가 나타난다면
Failed password for invalid user admin
존재하지 않는 사용자 계정에 대해 로그인 공격이 반복되고 있을 가능성이 있습니다.
반대로
Accepted publickey for user
와 같은 로그는 공개키 인증을 통해 정상적으로 로그인했다는 의미입니다.
로그를 단순히 읽는 것보다 정상적인 로그와 비정상적인 로그를 구분하는 능력이 중요합니다.
Rocky Linux에서는 SELinux가 활성화되어 있는 경우가 많습니다.
현재 상태는 다음과 같이 확인할 수 있습니다.
getenforce
결과가
Enforcing
이라면 SELinux가 정책을 적용하고 있는 상태입니다.
SSH 포트를 변경하는 경우 SELinux 정책에도 새로운 포트를 등록해야 할 수 있습니다.
예를 들어 SSH를 2222번 포트에서 운영하려면 SELinux에서 해당 포트를 SSH 포트로 허용하는 작업이 필요할 수 있습니다.
따라서 SSH 포트를 변경했는데 접속이 되지 않는다면 다음 세 가지를 함께 확인해야 합니다.
sshd 설정
방화벽
SELinux
운영 서버에서 SSH를 구성한다면 다음과 같은 구조를 고려할 수 있습니다.
인터넷
|
↓
방화벽 / Security Group
|
↓
SSH 접근 가능한 IP 제한
|
↓
sshd
|
├── 공개키 인증
├── Root 로그인 제한
├── 비밀번호 인증 제한
└── 접속 로그 기록
|
↓
Fail2ban
이렇게 여러 방어 계층을 구성하면 하나의 보안 설정에만 의존하는 것을 피할 수 있습니다.
실제 운영 서버를 구축한 후 다음 항목을 점검하는 습관을 들이는 것이 좋습니다.
불필요한 계정 제거
강력한 인증 정책
최소 권한 적용
sudo 권한 관리
SSH Key 인증 사용
Root 로그인 제한
비밀번호 인증 정책 검토
불필요한 SSH 접근 제한
firewalld 설정
SSH 접근 IP 제한
클라우드 Security Group 확인
불필요한 포트 차단
journalctl
/var/log/secure
Failed login
Invalid user
Accepted login
Fail2ban
SELinux
정기적인 패치
보안 취약점 점검
시스템 엔지니어 교육에서는 단순히 SSH 설정 파일을 읽는 것보다 직접 장애를 만들어 보는 것이 훨씬 효과적입니다.
예를 들어 테스트 서버에서 다음과 같은 상황을 만들어 볼 수 있습니다.
systemctl stop sshd
이후 원격 접속이 실패하는 것을 확인합니다.
그리고 콘솔에서
systemctl start sshd
로 복구합니다.
sshd_config의 설정을 일부러 변경한 뒤
sshd -t
를 실행하여 오류를 확인합니다.
chmod 777 ~/.ssh
처럼 잘못된 권한을 설정한 뒤 SSH 키 인증이 실패하는 상황을 확인해 볼 수 있습니다.
이후 정상적인 권한으로 복구합니다.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
이러한 실습을 통해 SSH 인증 구조와 장애 원인을 훨씬 빠르게 이해할 수 있습니다.
SSH는 Linux 서버 관리에서 가장 많이 사용하는 원격 접속 기술이지만 동시에 인터넷에 노출된 서버에서 가장 먼저 공격받을 수 있는 서비스 중 하나입니다.
따라서 시스템 엔지니어는 단순히 다음과 같은 명령어만 알고 있어서는 부족합니다.
ssh user@server
실제 운영 환경에서는 다음의 전체 구조를 이해해야 합니다.
SSH Client
↓
네트워크
↓
방화벽
↓
sshd
↓
인증
↓
SSH Key / Password
↓
계정 권한
↓
sudo
↓
로그 기록
↓
로그 분석
↓
Fail2ban / 보안 정책
특히 다음 7가지는 Linux 서버 운영자가 반드시 익혀야 합니다.
1. SSH 기본 구조
2. SSH Key 인증
3. Root 로그인 제한
4. 비밀번호 인증 정책
5. firewalld를 이용한 접근 제어
6. Fail2ban을 이용한 반복 공격 대응
7. journalctl과 /var/log/secure를 이용한 로그 분석
그리고 SSH 보안에서 가장 중요한 원칙은 **“포트를 바꾸는 것보다 접근 자체를 통제하는 것”**입니다.
SSH 포트를 22번에서 다른 번호로 변경하는 것만으로 서버가 안전해지는 것은 아닙니다. 공개키 인증, 최소 권한, Root 로그인 제한, 방화벽, IP 접근 제어, SELinux, 로그 모니터링 등을 여러 계층으로 구성해야 실제 운영 환경에서 보다 안전한 Linux 서버를 만들 수 있습니다.