Rocky Linux AlmaLinux SSH 포트 변경 방법
Rocky Linux 및 AlmaLinux에서 SSH 포트를 안전하게 변경하는 방법을 설명합니다. firewalld 설정과 semanage를 이용한 SELinux 레이블 추가, sshd_config 수정까지 세 단계를 거쳐 현재 세션 유지하며 포트를 변경하는 정확한 절차를 안내합니다.
SSH 포트 변경 시 세 단계가 필요한 이유
Rocky Linux, AlmaLinux, CentOS Stream 또는 Fedora에서 SSH 포트를 변경할 때는 설정 파일 수정만으로는 충분하지 않습니다. 새로운 포트에서 연결이 정상적으로 작동하려면 세 가지 시스템이 각각 승인해야 합니다. firewalld는 패킷이 서버에 도달할 수 있는지 결정합니다. SELinux는 sshd이 해당 포트 번호에 바인딩할 수 있는지 결정합니다. sshd_config은 데몬이 어떤 포트를 사용할지 결정합니다. SELinux 단계를 누락하면 데몬이 시작을 거부합니다. firewalld 단계를 누락하면 데몬은 시작되어 포트를 점유하지만, 외부에서 접근할 수 없습니다.
Ubuntu에서는 동일한 작업을 설정 파일 수정과 재시작 한 번으로 완료할 수 있습니다. Ubuntu는 SELinux 대신 AppArmor를 사용하며, sshd가 바인딩할 수 있는 포트를 제한하는 프로필을 기본적으로 제공하지 않기 때문입니다. ufw가 실행 중이라면 규칙 하나만 추가하면 됩니다. 이것이 두 운영체제 계열의 차이점입니다. RHEL 계열은 초기 설치 시 firewalld가 실행 중이고 SELinux가 enforcing 모드로 설정되어 있으며, 두 시스템 모두 포트 번호를 엄격하게 관리합니다.
다음 순서대로 작업을 진행하면 현재 세션을 유지하면서 안전하게 변경할 수 있습니다.
- firewalld에서 새 포트를 개방하고, 기존 22번 포트는 당분간 열어 둡니다.
semanage을 사용하여 새 포트에 SELinux 레이블을 추가합니다.- sshd 설정에서 포트를 변경합니다.
sshd를 재시작한 뒤, 첫 번째 터미널을 닫기 전에 다른 터미널에서 새 포트로 로그인을 시도합니다.
작업을 시작하기 전에 제공업체의 웹 콘솔(VNC 또는 시리얼)을 찾아 로그인할 수 있는지 확인하십시오. 변경 과정에서 문제가 발생했을 때 서버에 다시 접속할 수 있는 유일한 방법입니다. 포트 변경은 사용자가 새로 대여한 서버에서 스스로 접속을 차단하게 되는 가장 흔한 원인 중 하나입니다.
먼저 semanage를 설치합니다
semanage은 SELinux 정책 설정을 편집하는 도구이며, Rocky Linux나 AlmaLinux를 최소 설치하면 이 도구가 포함되지 않습니다. 이 도구는 policycoreutils-python-utils 패키지에 포함되어 있습니다.
sudo dnf install -y policycoreutils-python-utils해당 패키지를 설치하기 전에 명령어를 실행하면 sudo: semanage: command not found 오류가 발생합니다. 많은 사용자가 이 시점에서 SELinux가 설치되지 않았다고 판단하고 단계를 건너뜁니다. SELinux는 이미 설치되어 있습니다. 단지 관리 도구만 누락된 상태입니다. dnf 구문이 생소하다면, dnf 및 apt 명령어 대응표를 통해 이미 알고 있는 명령어와 비교해 보십시오.
포트를 선택하고 해당 포트가 사용 중인지 확인하기
1024에서 65535 사이의 사용 가능한 TCP 포트라면 무엇이든 좋습니다. 포트를 결정하기 전에 다음 두 가지를 확인하십시오.
sudo ss -tlnp | grep -w 2222
sudo semanage port -l | grep -w 2222첫 번째 명령은 해당 포트 번호에서 이미 수신 대기 중인 프로세스가 있는지 보여줍니다. 두 번째 명령은 SELinux 정책이 해당 포트를 다른 서비스 유형에 이미 할당했는지 확인합니다. 사용 가능한 포트라면 두 명령 모두 아무런 결과도 출력하지 않습니다. 정책이 이미 해당 포트를 점유하고 있다면 2단계의 semanage port -a 명령이 ValueError: Port tcp/2222 already defined 오류와 함께 실패하며, 이 경우 다른 포트 번호를 선택해야 합니다.
이 가이드에서는 예시로 2222 포트를 사용합니다. 하지만 2222는 스캐너가 22 포트 다음으로 가장 먼저 시도하는 포트이므로, 실제 서버에서는 더 눈에 띄지 않는 포트를 선택하십시오.
1단계: firewalld에서 포트 열기
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports--permanent은(는) 규칙을 디스크의 영역 파일에 기록하며 실행 중인 방화벽에는 영향을 주지 않습니다. --reload은(는) 디스크에 저장된 설정을 실행 중인 방화벽에 불러옵니다. reload를 건너뛰면 규칙은 존재하지만 다음 firewalld 재시작 전까지는 아무런 동작을 하지 않습니다. 이는 전체 과정이 이유 없이 실패한 것처럼 보이는 가장 흔한 원인 중 하나입니다.
ssh 서비스 항목은 일단 그대로 두십시오. 해당 항목은 포트 22를 열어두는 역할을 하며, 테스트 중 문제가 발생할 경우를 대비한 안전장치입니다.
제공업체의 제어판도 확인하십시오. 많은 호스트가 운영체제 외부인 VPS 앞단에서 네트워크 방화벽을 운영하므로, firewalld에서 포트를 열었더라도 상위 네트워크에서 차단될 수 있습니다. VPS를 위한 firewalld 기초 가이드에서 이 모델이 생소한 사용자를 위해 영역(zone)과 런타임/영구 설정의 차이를 다룹니다.
2단계: SELinux용 포트 레이블 지정
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -l | grep ssh_port_t-a는 새로운 포트 할당을 추가합니다. -t ssh_port_t은 SSH 포트가 사용하는 유형입니다. 두 번째 명령은 현재 ssh_port_t이 포함하는 모든 항목을 나열하므로, 데몬을 수정하기 전에 해당 번호가 정상적으로 등록되었는지 확인할 수 있습니다.
SELinux가 포트를 차단하는 이유
SELinux(Security-Enhanced Linux)는 시스템의 모든 객체에 레이블을 부여하며, TCP 포트 번호도 다른 객체와 마찬가지로 레이블이 지정됩니다. SSH 데몬은 sshd_t라는 도메인 내에서 제한된 상태로 실행됩니다. 정책상 sshd_t은 ssh_port_t로 레이블이 지정된 TCP 포트에만 바인딩할 수 있으며, 기본적으로 이 레이블이 지정된 포트는 22번뿐입니다. 데몬이 2222번 포트에 바인딩을 시도하면 커널은 레이블을 확인하고 해당 번호에 할당된 일반적인 유형 정책을 찾아 소켓에 대한 name_bind 권한을 거부합니다.
이러한 이유로 이 오류는 방화벽 문제처럼 보이지 않습니다. 리스닝 소켓이 생성되기도 전에 커널이 거부하기 때문에 sshd은 오류를 보고하고 종료됩니다. 방화벽 문제는 이와 반대입니다. 데몬은 정상적으로 실행 중이지만 들어오는 패킷이 도중에 폐기되는 경우입니다.
getenforce 명령을 사용하면 현재 시스템의 모드를 확인할 수 있습니다. Permissive 모드에서는 거부 기록만 남고 실제 차단은 수행되지 않으므로, 포트 변경이 성공한 것처럼 보이다가 누군가 setenforce 1를 실행하거나 시스템이 enforcing 모드로 재부팅되면 문제가 발생합니다. 어떤 경우든 포트에 올바른 레이블을 지정해야 합니다. 서버를 위한 SELinux 기초 가이드에서 모드, 컨텍스트, 불리언(boolean)에 대해 자세히 다룹니다. 포트 외에도 이 정책이 적용되는 객체는 많습니다. 예를 들어, 경로에 적절한 레이블을 다시 지정하기 전까지는 컨테이너가 마운트된 호스트 디렉터리를 읽을 수 없습니다. 이것이 바로 Rocky Linux 또는 AlmaLinux에 Docker 설치하기 가이드에 Ubuntu 가이드에는 없는 SELinux 관련 단계가 포함된 이유입니다.
3단계: sshd 설정에서 포트 지정하기
Rocky Linux 9 및 10, AlmaLinux 9 및 10, 그리고 최신 Fedora에서는 /etc/ssh/sshd_config이 include 라인으로 시작하므로, 변경 사항을 적용하기에 가장 깔끔한 위치는 드롭인 파일입니다. 이렇게 하면 패키지 업데이트 시 설정이 덮어씌워지지 않습니다.
grep -n '^Include' /etc/ssh/sshd_config
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -tRocky Linux 8 및 기타 구형 이미지와 같이 grep에 Include 라인이 없는 경우에는 Port 2222을 /etc/ssh/sshd_config에 직접 입력하십시오. sshd -t는 드롭인 파일을 포함한 전체 설정을 구문 분석하여 오류를 보고합니다. 구문 분석에 실패한 설정은 데몬이 다시 시작되지 않는 원인이 되므로, 재시작 전에 보고된 모든 오류를 수정해야 합니다.
Port은 여러 번 나타날 수 있으며, sshd는 나열된 모든 포트에서 대기합니다. 첫날에는 Port 22과 Port 2222을 함께 유지하는 것이 안전한 예방책이 될 수 있으나, 나중에 반드시 제거해야 한다는 점을 기억하십시오.
sshd가 소켓 유닛으로 시작됩니까?
일부 이미지는 SSH를 상시 실행되는 서비스가 아닌 systemd 소켓 활성화(socket activation)를 통해 시작합니다. 이 방식이 설정된 경우, systemd가 리스닝 소켓을 소유하고 연결을 sshd로 전달하므로 sshd_config의 Port 줄은 완전히 무시됩니다. 무엇인가를 재시작하기 전에 다음을 확인하십시오.
systemctl is-enabled sshd.socketenabled라는 응답은 포트가 sshd_config가 아닌 소켓 유닛에 설정되어 있음을 의미합니다.
sudo systemctl edit sshd.socket[Socket]
ListenStream=
ListenStream=2222빈 ListenStream= 설정이 필요합니다. 값은 드롭인(drop-in) 파일 전체에 누적되므로, 먼저 목록을 비우는 빈 할당을 하지 않으면 소켓은 22번 포트와 2222번 포트 모두에서 계속 대기하게 됩니다. sudo systemctl daemon-reload로 이를 적용한 뒤 sudo systemctl restart sshd.socket를 실행하십시오. 만약 해당 유닛이 비활성화되어 있거나 서버에 존재하지 않는다면, 이 섹션은 귀하에게 해당하지 않습니다.
단계 4: 재시작 후 두 번째 터미널에서 테스트
sudo systemctl restart sshd
systemctl status sshd
sudo ss -tlnp | grep sshd현재 터미널을 그대로 유지하십시오. 로그아웃하지 마십시오. 로컬 머신에서 두 번째 터미널을 열고 새로운 포트로 접속하십시오:
ssh -p 2222 youruser@203.0.113.10두 번째 터미널에서 로그인이 성공한 것을 확인한 후에만 첫 번째 세션을 종료하십시오. 만약 접속이 되지 않더라도, 설정을 되돌릴 수 있는 셸이 여전히 활성화되어 있습니다. 이 습관 하나가 5분이면 끝날 작업을 오후 내내 제공업체 콘솔과 씨름하게 만드는 상황을 방지합니다.
방화벽 차단인가 SELinux 거부인가? 구분 방법
노트북에서 확인하면 두 장애는 거의 동일해 보이지만, 서버 내부에서는 전혀 다르게 나타납니다.
systemctl status sshd명령으로 유닛이 실패했다고 나오면, 데몬이 소켓을 확보하지 못한 것입니다. 이는 설정 오류이거나 SELinux 거부 때문입니다.- 유닛이 활성 상태이고
ss -tlnp명령으로 sshd가 새 포트에 바인딩된 것이 확인된다면, 데몬은 정상이며 문제는 네트워크 경로에 있는 것입니다. 즉, firewalld, 제공업체의 별도 방화벽, 또는 접속하려는 주소와 포트 문제입니다.
SELinux 문제라면 추측하지 말고 감사(audit) 기록을 확인하십시오:
sudo ausearch -m AVC -ts recent
sudo journalctl -u sshd -n 50 --no-pagername_bind 거부 메시지의 tcp_socket 클래스에는 comm="sshd"의 프로세스 이름, src=의 포트 번호, 그리고 tcontext=의 실제 포트 레이블이 표시됩니다. 마지막 필드가 핵심입니다. ssh_port_t 이외의 값이 표시된다면 2단계 작업이 해당 포트에 적용되지 않은 것이며, 보통 포트 번호 오타나 잘못된 프로토콜 설정이 원인입니다. sealert를 사용하여 기록을 문장으로 읽고 싶다면 setroubleshoot-server를 설치하십시오.
커널이 바인딩을 거부할 때 sshd가 직접 기록하는 메시지는 다음과 같습니다:
error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.루트 권한이 필요 없는 1024번 이상의 포트에서 발생하는 Permission denied은 SELinux의 전형적인 징후입니다. 같은 줄에 나타나는 Address already in use은 다른 프로세스가 이미 해당 포트를 점유하고 있다는 뜻으로, 전혀 다른 오류입니다. 클라이언트 측에서는 연결 거부(connection refused)와 연결 시간 초과(connection timed out)의 차이를 통해 네트워크 문제를 구분할 수 있습니다. 연결 거부는 패킷이 호스트에 도달했으나 수신 대기 중인 서비스가 없음을 의미하고, 시간 초과는 아무런 응답이 없음을 의미하기 때문입니다.
포트 22를 닫고 클라이언트 업데이트하기
새로운 포트로 로그인이 여러 번 성공적으로 이루어졌다면, 포트 22를 닫습니다.
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-all포트 22에 설정된 SELinux 레이블은 그대로 둡니다. 이는 기본 정책에서 제공하는 것이며, 방화벽이 패킷 유입을 차단하면 해당 레이블은 아무런 권한도 부여하지 않습니다.
그다음 클라이언트를 수정합니다. 기본 포트를 사용한다고 가정했던 모든 도구에 변경 사항을 알려야 하기 때문입니다. 매번 -p를 입력하는 대신, 본인의 로컬 머신에서 ~/.ssh/config에 한 번만 설정해 둡니다.
Host myvps
HostName 203.0.113.10
Port 2222
User youruserscp, sftp, rsync 및 Ansible은 모두 해당 파일을 참조합니다. 백업 작업, 모니터링 체크, cron 스크립트에 포트 22가 하드코딩되어 있다면 이 파일의 영향을 받지 않으므로, 변경 사항이 기억에 생생할 때 모두 찾아 수정하십시오.
포트 변경의 이점과 한계
포트 변경은 로그 노이즈를 줄여줍니다. 자동화된 스캐너는 22번 포트를 끊임없이 공격하므로, 포트를 옮기면 저널에서 대부분의 관련 기록이 사라져 실제 이벤트를 확인하기가 훨씬 수월해집니다. 하지만 이는 보안 통제 수단이 아닙니다. 전체 포트 범위를 스캔하는 공격자는 결국 데몬을 찾아내어 버전 배너를 읽어낼 것입니다. 포트 변경은 단순한 관리 작업으로 여기고, 실제 보안은 비밀번호 로그인을 비활성화하고 키 기반 인증을 사용하는 방식으로 구현해야 합니다. 이에 관한 단계별 안내는 VPS를 위한 SSH 강화 가이드에서 확인할 수 있습니다.
위의 모든 내용은 동일한 소스에서 빌드되므로 두 주요 RHEL 리빌드 배포판에서 동일하게 작동합니다. 아직 배포판을 선택 중이라면 Rocky Linux와 AlmaLinux 비교를 참조하십시오. 2020년 CentOS가 더 이상 리빌드 배포판이 아니게 되면서 현재와 같이 두 개의 거의 동일한 리빌드 배포판이 존재하게 되었습니다. 이 과정에 대한 자세한 내용은 Red Hat에서 CentOS, 그리고 Rocky와 AlmaLinux까지의 이야기에 담겨 있습니다. 오래된 가이드를 따르기 전에 cat /etc/os-release 명령으로 현재 사용 중인 릴리스 버전을 먼저 확인하십시오. Rocky Linux 8용으로 작성된 가이드가 여전히 검색 상위에 노출되고 그 안의 semanage 및 firewall-cmd 단계는 여전히 정확할 수 있습니다. 하지만 Rocky 8에는 sshd_config.d include 라인이나 고려해야 할 소켓 유닛이 없으므로, 해당 가이드의 sshd 관련 내용은 현재 시스템과 일치하지 않습니다.
fail2ban에 새로운 포트를 알려야 합니다
fail2ban은 기본 저장소에 포함되어 있지 않습니다. EPEL(Extra Packages for Enterprise Linux) 저장소에서 설치해야 합니다:
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalldfail2ban-firewalld 하위 패키지를 사용하면 fail2ban이 firewalld를 통해 차단 규칙을 적용합니다. firewalld가 규칙 집합을 관리하는 서버에서는 이 방식이 권장됩니다.
기본 sshd jail 설정은 port = ssh로 지정되어 있으며, 이 이름은 /etc/services을 통해 22번 포트로 해석됩니다. 포트를 변경한 후에는 jail이 아무도 공격하지 않는 포트를 감시하게 되므로, 2222번 포트로 로그인 시도가 쌓여도 아무도 차단하지 못합니다. /etc/fail2ban/jail.local 파일에서 포트를 숫자로 직접 지정하십시오:
[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
bantime = 3600backend = systemd는 /var/log/secure 대신 저널(journal)에서 실패 기록을 읽어옵니다. 이는 rsyslog가 설치되지 않을 수 있는 최소 설치 환경에서 더 안전한 선택입니다. sudo systemctl enable --now fail2ban로 서비스를 시작하고 sudo fail2ban-client status sshd으로 jail 상태를 확인하십시오. jail 구문은 Ubuntu 24.04의 SSH용 fail2ban 설정에서 사용한 것과 동일합니다. 패키지 소스와 차단 동작(ban action)만 다릅니다.
포트 변경보다 중요한 보안 패치
SSH 포트를 변경하고 4개월 동안 보안 업데이트를 적용하지 않은 서버는, 22번 포트를 사용하더라도 매일 밤 자동으로 패치되는 서버보다 보안 상태가 취약합니다. root 권한으로 작업하는 김에 동일한 세션에서 자동 업데이트를 활성화하십시오. Rocky Linux 및 AlmaLinux에서 dnf 자동 업데이트 설정하기 문서에서 타이머 설정과 업데이트 다운로드 및 적용 방식 선택에 대해 다룹니다. 업데이트를 설치하더라도 기존 코드를 실행 중인 데몬은 재시작되지 않습니다. 따라서 openssh-server나 관련 라이브러리가 업데이트될 때마다 재시작이나 재부팅이 필요한 서비스 확인하기를 통해 필요한 조치를 취하는 것이 좋습니다.
FAQ
Rocky Linux에서 포트를 변경한 뒤 sshd가 시작되지 않는 이유는 무엇입니까?
거의 항상 SELinux 포트 레이블이 누락되었기 때문입니다. sshd은 sshd_t 도메인 내에서 제한된 상태로 실행되며, 정책상 ssh_port_t로 레이블이 지정된 포트에서만 바인딩할 수 있습니다. 기본적으로 이 레이블은 22번 포트에만 할당되어 있습니다. 커널이 바인딩을 거부하면 데몬은 리스닝 상태로 진입하지 못하고 종료됩니다. 이때 journalctl -u sshd에는 error: Bind to port 2222 on 0.0.0.0 failed: Permission denied. 형태의 메시지가 기록됩니다. 본인의 포트 번호를 사용하여 sudo semanage port -a -t ssh_port_t -p tcp 2222를 실행한 뒤 서비스를 재시작하십시오. semanage 명령어를 찾을 수 없다면 먼저 policycoreutils-python-utils를 설치해야 합니다.
SELinux가 permissive 모드일 때도 semanage가 필요합니까?
네, 필요합니다. permissive 모드에서는 거부 기록만 남을 뿐 바인딩 자체는 허용되므로 변경 사항이 정상적으로 작동하는 것처럼 보입니다. 하지만 레이블은 여전히 누락된 상태입니다. 누군가 setenforce 1를 실행하거나, /etc/selinux/config 파일의 SELINUX=enforcing 설정을 통해 시스템이 부팅되는 순간 sshd는 해당 포트에서 시작되지 않습니다. 레이블을 추가하는 것은 명령어 한 줄이면 충분하며, 나중에 원인을 알 수 없는 장애가 발생하는 상황을 방지할 수 있습니다.
포트 레이블도 지정했고 sshd도 실행 중인데 왜 연결 시간이 초과됩니까?
데몬이 실행 중이라는 것은 SELinux 정책을 통과했다는 의미이므로, 패킷이 도달하는 과정에서 차단되고 있는 것입니다. sudo firewall-cmd --list-ports 명령어로 포트 상태를 확인하고, --permanent 규칙을 추가한 뒤 firewall-cmd --reload를 실행했는지 확인하십시오. 영구 규칙만으로는 현재 실행 중인 방화벽에 즉시 적용되지 않기 때문입니다. 그다음 VPS 앞단에 별도의 네트워크 방화벽이 있는지 호스트 제어판을 확인하십시오. 운영체제 내부에서는 확인할 수 없는 두 번째 차단 지점입니다.
22번 대신 어떤 포트를 사용해야 합니까?
1024에서 65535 사이의 사용 가능한 TCP 포트라면 무엇이든 좋습니다. 실제 운영 서버에서는 2222나 22222 포트를 피하십시오. 스캐너들이 22번 다음으로 가장 먼저 시도하는 포트이기 때문입니다. sudo ss -tlnp 명령어로 해당 번호가 비어 있는지 확인하고, sudo semanage port -l 명령어로 SELinux 정책이 이미 해당 포트를 점유하고 있지 않은지 확인하십시오. 나중에 설치할 서비스에 할당된 포트도 피하는 것이 좋습니다. 기억하기 어려운 높은 번호의 포트를 사용하는 것이 좋습니다. 어차피 ~/.ssh/config에 한 번 적어두면 다시 입력할 일이 없기 때문입니다.