"서버끼리는 SSH 가 되는데 내 PC 에서만 안 된다" 는 형태의 장애는 원인이 네트워크 경로, 서버 OS 설정, 네트워크 장비 정책 중 어디에 있는지부터 갈라야 한다. 순서를 지키지 않고 sshd_config 부터 뒤지면 대부분 시간을 버린다.
가장 빠른 단서는 클라이언트가 내는 한 줄이다.
| 문구 | 의미 | 볼 곳 |
|---|---|---|
Connection timed out |
패킷이 서버까지 못 가거나 응답이 돌아오지 못함 | 경로상의 방화벽·ACL·라우팅, 서버 NIC |
No route to host |
라우팅 경로 자체가 없음 | 클라이언트 라우팅 테이블, 게이트웨이 |
Connection refused |
서버까지 도달했으나 22번에 리스닝이 없거나 reject 됨 | sshd 기동 여부, 포트 변경, 로컬 방화벽의 reject 규칙 |
Permission denied (publickey,password) |
네트워크는 정상. 인증 단계 실패 | 계정, 키, AllowUsers, Match |
kex_exchange_identification · no matching host key type |
암호 알고리즘 협상 실패 | 구형 클라이언트, 보안 정책(crypto-policies) |
refused 와 timed out 은 성격이 정반대다. refused 는 서버가 응답한 것이고 timed out 은 아무 응답이 없는 것이다. 이 둘을 구분하지 않으면 진단 방향이 뒤집힌다.
ssh -vvv user@192.168.0.10
Test-NetConnection 192.168.0.10 -Port 22
TcpTestSucceeded : False 면 네트워크 구간 문제로 좁혀진다.
sudo ss -ntlp | grep ':22'
sudo systemctl status sshd
sudo firewall-cmd --list-all
sudo iptables -L -n
cat /etc/hosts.allow /etc/hosts.deny
sudo getenforce
sshd_config 에 대역 제한이 걸려 있는지도 본다.
grep -Ei 'port|listenaddress|allowusers|allowgroups|denyusers' /etc/ssh/sshd_config
grep -A5 '^Match' /etc/ssh/sshd_config
시도한 흔적이 서버 로그에 아예 없으면 패킷이 서버까지 오지 못한 것이다.
sudo tail -100 /var/log/secure
sudo journalctl -u sshd --since "1 hour ago"
여기서 결론이 갈린다. 서버에서 잡고 클라이언트에서 접속을 시도한다.
sudo tcpdump -nn -i eno1 'tcp port 22 and host 172.20.32.174'
| 보이는 것 | 해석 |
|---|---|
| 아무것도 안 보임 | 패킷이 서버에 도달하지 않음. 경로상의 방화벽·ACL |
| SYN 만 보이고 SYN-ACK 가 없음 | 서버가 받고도 응답하지 않거나, 응답이 스위치에서 버려짐 |
| SYN 과 SYN-ACK 가 모두 보이는데 클라이언트는 타임아웃 | 돌아가는 경로에서 차단. 네트워크 장비 |
인터페이스를 지정하지 않으면 tcpdump 가 엉뚱한 NIC 를 고른다. 서버에 NIC 가 여러 장이면 -i 를 반드시 준다. 실제로 인터페이스를 빼고 돌려 0 packets captured 를 보고 "패킷이 안 온다" 고 오판하기 쉽다.
OS 가 응답을 막는 대표적인 원인은 다음과 같다.
역경로 검사가 켜져 있고 라우팅이 비대칭이면 커널이 조용히 버린다. all 과 default 만 꺼도 소용없고 해당 인터페이스 값을 봐야 한다.
cat /proc/sys/net/ipv4/conf/all/rp_filter
cat /proc/sys/net/ipv4/conf/eno1/rp_filter
sudo sysctl -w net.ipv4.conf.eno1.rp_filter=0
ip addr show dev eno1
inet 172.18.23.15/24 scope global noprefixroute eno1
inet 172.18.23.100/32 scope global eno1:0
nmcli·ifcfg 어디에도 없는 .100 이 살아 있다면 keepalived 나 수동 ip addr add 로 올라간 VIP 다. 응답 패킷의 출발지 IP 가 접속 대상과 달라지면 클라이언트가 그 응답을 버린다. keepalived 를 멈추고 남는지 확인한다.
sudo systemctl stop keepalived
ip addr show dev eno1
sudo ip addr del 172.18.23.100/32 dev eno1
grep -R "172.18.23.100" /etc/keepalived /etc/sysconfig/network-scripts /etc/NetworkManager 2>/dev/null
OS 쪽에서 아무것도 막고 있지 않은데 신규로 들여온 서버만 안 된다면 스위치의 IP-MAC binding, port security, ARP inspection 을 의심한다. 클라이언트에서 ARP 항목이 제대로 잡히는지 확인한다.
arp -a | findstr 172.18.23.15
ICMP 는 되는데 22번만 안 되면 장비 ACL 쪽이다.
위 절차를 끝까지 돌린 사례 하나는 결론에 이르지 못했다. 같은 대역의 기존 서버는 PC 에서 접속이 되는데 새로 설치한 두 대만 타임아웃이 났고, 확인한 것은 다음과 같다.
| 항목 | 상태 |
|---|---|
sshd 기동·리스닝 |
정상 |
firewalld |
미동작 |
iptables |
22번 차단 규칙 없음 |
hosts.allow · hosts.deny |
비어 있음 |
| SELinux | disabled |
인터페이스별 rp_filter |
0 |
| 라우팅 | 정상 |
tcpdump |
SYN 도달, SYN-ACK 미확인 |
설정 파일에 없는 VIP(172.18.23.100/32)가 eno1:0 으로 올라와 있었고 지워도 다시 생겼으나, keepalived 설정은 그 VIP 를 dummy0 에 올리도록 되어 있었고 서비스는 정지 상태였다. 어느 주체가 eno1 에 alias 를 올리는지 특정하지 못했다. 남은 확인 항목은 스위치 쪽 IP-MAC binding 과 ARP inspection 이며, 네트워크 담당자 확인이 필요하다.