kex_exchange_identification: read: Connection reset by peer는 SSH 키 교환 단계에서 연결이 리셋됐다는 메시지입니다. Connection closed by remote host도 함께 보일 수 있습니다. 이 문자열만으로 Fail2Ban 차단을 확정할 수는 없습니다. 클라이언트의 ssh -vvv와 같은 시각의 서버 로그를 연결해 원인을 좁혀야 합니다.
SSH 연결 오류를 먼저 구분하세요
| 오류 | 우선 확인할 범위 |
|---|---|
Connection refused | SSH 포트 리슨 여부, 주소·포트, 연결 거부 규칙 |
Connection timed out | 경로·방화벽·보안그룹, 응답하지 않는 서버 |
kex_exchange_identification ... reset by peer | 인증 전 연결 제한, 차단 장비, sshd 로그 |
Permission denied (publickey) | 서버에 도달한 뒤의 사용자·키 인증 |
클라이언트 메시지는 연결이 어떻게 끊겼는지만 알려 줍니다. Connection closed by remote host는 상대가 연결을 닫아 EOF를 받은 것이고, Connection reset by peer는 TCP RST를 받은 것입니다. RST는 원격 호스트뿐 아니라 경로상의 방화벽·LB·IPS가 보낼 수도 있습니다. 같은 Fail2Ban 차단도 banaction에 따라 다르게 보입니다. DROP이면 Connection timed out, 기본 REJECT(icmp-port-unreachable)면 Connection refused, --reject-with tcp-reset이면 Connection reset입니다. 반대로 sshd가 연결을 받은 뒤 정책으로 끊으면 closed로 보입니다.
먼저 나만 안 되는지, 모두 안 되는지를 가르면 범위가 크게 줄어듭니다.
SSH 접속 실패
├─ 다른 네트워크(휴대폰 핫스팟 등)에서도 안 됨 → sshd 상태·서버 방화벽·MaxStartups·전체 차단
└─ 특정 출발지 IP에서만 안 됨 → Fail2Ban·PerSourcePenalties·보안그룹 소스 IP 제한키 인증 실패와 연결 초기화 오류는 진단 순서가 다릅니다. 일반적인 접속 오류 분류는 SSH 접속 안 될 때 점검 가이드에서 이어서 확인할 수 있습니다.
1. ssh -vvv로 중단 지점과 시각 기록
# 클라이언트에서 실행: 사용자·주소·포트 교체
ssh -vvv -o ConnectTimeout=10 -p 22 user@host마지막 한 줄뿐 아니라 Connecting to, Connection established, 원격 버전 문자열, 인증 방식 안내가 어디까지 나오는지 기록합니다. verbose 로그는 가능한 원인을 좁히는 자료이며 차단 주체를 단독으로 증명하지는 않습니다.
서버 콘솔이나 기존 관리 세션이 있다면 같은 시각의 로그를 봅니다.
# 배포판에 따라 서비스 이름은 ssh 또는 sshd
sudo journalctl -u ssh -u sshd --since '15 minutes ago' --no-pager
sudo ss -ltnp버전·배포판에 따라 보이는 모습이 다릅니다.
- Ubuntu 22.10 이상(24.04 LTS 포함)은 기본적으로 systemd 소켓 활성화(
ssh.socket)를 씁니다.ss -ltnp에서 22번 포트를 잡은 프로세스가sshd가 아니라systemd로 보이는 것이 정상입니다. 포트·ListenAddress를 바꾼 뒤에는sudo systemctl daemon-reload && sudo systemctl restart ssh.socket으로 소켓을 다시 열어야 반영됩니다. Ubuntu: sshd socket-based activation - OpenSSH 9.8부터는 접속별 처리를
sshd-session바이너리가 맡아, 일부 로그가sshd가 아닌sshd-session태그로 찍힙니다.grep sshd만으로 찾으면 놓칠 수 있습니다. OpenSSH 9.8 릴리스 노트 - 서버의 OpenSSH 버전은
ssh -V(같은 패키지의 클라이언트 버전)나 패키지 관리자(dpkg -l openssh-server,rpm -q openssh-server)로 확인합니다.
서버에 기록이 전혀 없다면 잘못된 목적지·포트, 중간 방화벽, NAT 경로도 확인합니다. ping 성공은 ICMP 응답만 확인하므로 SSH 포트의 정상 동작을 보장하지 않습니다.
2. 특정 출발지 IP에서만 실패하면 차단 기록 확인
Fail2Ban을 실제로 운영하는 서버에서 다음을 확인합니다.
sudo fail2ban-client status
sudo fail2ban-client status sshdsshd는 jail 이름의 예시입니다. 활성 jail과 서버에서 관찰한 출발지 IP를 대조합니다. NAT·VPN 환경에서는 클라이언트의 사설 IP와 서버에 보이는 IP가 다를 수 있습니다.
확인된 정상 관리 IP가 해당 jail에 차단되어 있고 해제 권한이 있을 때만 다음을 실행합니다.
# 203.0.113.10은 예시 주소: 실제 차단 IP로 교체
sudo fail2ban-client set sshd unbanip 203.0.113.10인증 실패 원인도 고치지 않으면 다시 차단될 수 있습니다. Fail2Ban 클라이언트 명령 문서
관리망이 자주 차단된다면 /etc/fail2ban/jail.local의 ignoreip에 고정 관리 대역·VPN 대역을 등록합니다. 공용 NAT나 넓은 클라우드 대역은 넣지 않습니다.
[DEFAULT]
# 203.0.113.0/24는 예시 대역: 실제 관리망으로 교체
ignoreip = 127.0.0.1/8 ::1 203.0.113.0/24sudo fail2ban-client reload
sudo fail2ban-client get sshd ignoreip # 반영 확인3. 동시 접속 시에만 발생하면 MaxStartups 확인
sudo sshd -T | grep -iE 'maxstartups|persourcemaxstartups|logingracetime'MaxStartups는 인증을 완료하지 않은 동시 연결을 제한합니다. 예를 들어 유효 설정이 10:30:100이라면 미인증 연결 10개부터 30% 확률로 새 연결을 거부하기 시작하고, 100개에 도달하면 모두 거부합니다. 이는 로그인 완료 세션 수 제한인 MaxSessions와 다릅니다. 버전·배포판의 실제 유효 설정을 확인하세요. OpenSSH sshd_config
자동화 작업이 한 번에 다수 접속을 만드는지 먼저 봅니다. 배포 동시성을 줄이고 연결을 재사용하는 방법을 검토한 뒤, 서버 용량과 보안 정책에 맞춰 제한을 조정합니다. 공격 트래픽 때문에 발생한 상황에서 제한만 올리면 부하가 커질 수 있습니다.
3-1. OpenSSH 9.8 이상: 같은 출발지가 한동안 계속 거부될 때
OpenSSH 9.8부터 PerSourcePenalties가 기본으로 켜져 있습니다. 인증 실패를 반복하거나 인증을 끝내지 않고 연결만 반복하는 출발지 주소에 벌점 시간을 쌓고, 기준을 넘으면 그 주소(그리고 PerSourceNetBlockSize 범위)의 새 연결을 벌점이 끝날 때까지 거부합니다. 잘못된 키로 재시도하는 배포 도구, 같은 NAT 출구를 쓰는 사무실 전체가 함께 막히는 형태로 나타납니다. OpenSSH 9.8 릴리스 노트
ssh -V # 9.8 미만이면 이 절은 해당 없음
sudo sshd -T | grep -iE 'persourcepenalt|persourcenetblocksize'
sudo journalctl -u ssh -u sshd --since '1 hour ago' --no-pager | grep -i penalt판정 기준: 벌점 관련 로그가 해당 출발지 IP로 찍히고, 시간이 지나면 저절로 다시 접속된다면 이 기능이 원인일 가능성이 큽니다. 먼저 반복 실패를 만든 원인(잘못된 키, 만료된 계정, 과도한 재시도)을 고칩니다. 관리망처럼 확실히 신뢰하는 대역만 예외로 둘 수 있습니다.
# /etc/ssh/sshd_config (또는 sshd_config.d/*.conf) — 예시 대역은 실제 관리망으로 교체
PerSourcePenaltyExemptList 192.0.2.0/24예외를 넓게 잡으면 무차별 대입 방어가 약해지므로 공용 NAT·클라우드 전체 대역은 넣지 않습니다. 옵션 이름과 기본값은 sshd_config 매뉴얼에서 서버 버전 기준으로 확인하세요.
4. 계정별 정책과 sshd 상태 확인
sudo sshd -T | grep -iE 'allowusers|denyusers|allowgroups|denygroups'
sudo sshd -tMatch 조건이 있는 환경에서는 단순 sshd -T 결과만으로 특정 연결의 설정을 판단하지 않습니다. 관리자가 실제 사용자·원격 주소 등을 sshd -T -C에 지정해 유효 설정을 확인할 수 있습니다. 실행 전 로컬 man sshd에서 지원 옵션을 확인하세요.
설정을 바꿔야 한다면 아래 설정 변경 후 확인과 재발 방지의 순서(기존 세션 유지 → 문법 검사 → reload → 새 터미널에서 확인)대로 적용합니다. 리슨 중이던 프로세스가 내려갔다면 먼저 journal의 시작 실패 원인을 수정합니다.
5. hosts.deny는 구형 환경에서만 확인
OpenSSH는 6.7에서 TCP Wrappers/libwrap 지원을 제거했습니다. 따라서 현대 OpenSSH 서버에서 /etc/hosts.deny를 고치는 것을 기본 해결책으로 안내하면 맞지 않습니다. 구형 패키지나 별도 패치로 libwrap을 사용하는 환경인지 확인된 경우에만 조사합니다. OpenSSH 6.7 릴리스 노트
현재 서버의 방화벽은 배포 구성에 따라 nftables, iptables, UFW, 클라우드 보안그룹 등에서 확인합니다. 진단을 위해 전체 방화벽을 해제하기보다 필요한 출발지·목적지·포트 규칙을 확인하세요.
접속 경로가 모두 막혔을 때
호스팅 관리 콘솔, 사전에 구성한 시리얼 콘솔, 복구 환경 등 별도 관리 경로를 이용합니다. 클라우드 시리얼 콘솔은 인스턴스·계정·OS별 사전 조건이 있어 버튼만 누르면 항상 연결되는 기능은 아닙니다.
대표적인 별도 관리 경로와 사전 조건은 다음과 같습니다. 장애가 나기 전에 하나 이상을 미리 준비해 두세요.
| 경로 | 22번 포트 필요 | 사전 조건 |
|---|---|---|
| AWS SSM Session Manager | 불필요 | SSM Agent, 인스턴스 IAM 역할, SSM 엔드포인트로의 아웃바운드 통신 |
| AWS EC2 Instance Connect | 필요 | 보안그룹이 Instance Connect 서비스 대역(또는 Endpoint)에서 22번 허용 |
| AWS EC2 / GCP 시리얼 콘솔 | 불필요 | 계정·프로젝트 단위 활성화, OS 로그인용 비밀번호 사용자 |
| GCP IAP TCP 포워딩 | 필요(IAP 대역에서) | 방화벽에서 35.235.240.0/20 → 22번 허용, IAP 권한 |
| 온프레미스 IPMI·iDRAC·iLO | 불필요 | 관리망 연결, BMC 계정 |
복구 뒤에는 원인 로그 → 변경한 규칙 → 새 연결 성공 여부를 기록합니다. 특정 IP 차단인지, 동시 연결 제한인지, sshd 장애인지 확인된 원인에 따라 재발 방지 조치를 선택하세요.
차단 원인을 확인한 뒤 방어 설정을 정리하려면 SSH 하드닝과 Fail2Ban 구성을 참고하세요.
설정 변경 후 확인과 재발 방지
원인을 찾아 sshd 설정을 바꿨다면, 적용 과정에서 스스로 접속을 잃지 않도록 순서를 지키는 것이 중요합니다.
안전한 적용 순서
- 기존 SSH 세션 하나를 열어 둔 채로 작업합니다(적용 실패 시 되돌릴 통로).
- 문법 검사 후 적용합니다.
sudo sshd -t && echo "config OK"
# 실제 적용된 값 확인 (Include 파일 포함 최종 값)
sudo sshd -T | grep -Ei 'maxstartups|maxsessions|persourcepenalties|logingracetime'
# 재적용 (배포판에 따라 서비스 이름이 ssh 또는 sshd)
sudo systemctl reload ssh || sudo systemctl reload sshd- 새 터미널에서 접속을 시험한 뒤에만 기존 세션을 닫습니다.
로그로 원인 재확인
sudo journalctl -u ssh -u sshd --since "1 hour ago" | grep -Ei 'MaxStartups|penalt|refused|reset'"past MaxStartups" 문구가 보이면 동시 미인증 연결 한도, penalty 관련 문구가 보이면 위 3-1의 PerSourcePenalties를 확인합니다.
재발 방지
- 배포·모니터링 도구처럼 접속이 몰리는 출발지는 연결 재사용(
ControlMaster/ControlPersist)을 설정해 새 연결 수를 줄입니다. - 공개 인터넷의 무차별 대입 시도는 방화벽에서 출발지를 제한하거나 VPN·배스천 뒤로 옮겨 sshd까지 도달하지 않게 합니다.
ss -Htn state established '( sport = :22 )' | wc -l값을 주기적으로 수집해 평소 동시 접속 수를 알아 두면, 한도 조정의 근거가 됩니다.-H(헤더 생략)를 빼면 제목 줄까지 세어 1이 더 나옵니다. 이 값은 인증을 마친 세션도 포함하므로MaxStartups(미인증 연결) 판단에는 로그의 "past MaxStartups"를 함께 봅니다. ss 매뉴얼
글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보
이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.
댓글
첫 번째 댓글을 남겨보세요.