끄적이는 보송

[Linux] ssh_exchange_identification: read: Connection reset: read: Connection reset 오류 해결 본문

STUDY/Linux

[Linux] ssh_exchange_identification: read: Connection reset: read: Connection reset 오류 해결

끄적이는 보송 2022. 11. 7. 17:57
반응형

EC2 Instance에 SSH 원격 접속을 하려고 하는데 아래와 같은 오류 메시지가 출력되었다. 빠르게 결론부터 말하자면 'etc' 경로 밑에 있는 hosts.allow와 hosts.deny 파일을 수정해주면 된다.

ssh_exchange_identification: read: Connection reset (*사용자 접속 ID/PW 사용)
kex_exchange_identification: read: Connection reset (*서버 키값 사용)

 

hosts.allow 설정

# hosts.allow   This file contains access rules which are used to
#               allow or deny connections to network services that
#               either use the tcp_wrappers library or that have been
#               started through a tcp_wrappers-enabled xinetd.
#
#               See 'man 5 hosts_options' and 'man 5 hosts_access'
#               for information on rule syntax.
#               See 'man tcpd' for information on tcp_wrappers
#

#172.31.10.0/24 대역의 모든 접근을 허용하겠다.
#뒷단에 서브넷마스크 명시 없이 점(.)만 찍고 대역이 될 부분을 빈 공간으로 둔다
ALL: 172.31.10.

hosts.deny 설정

# hosts.deny    This file contains access rules which are used to
#               deny connections to network services that either use
#               the tcp_wrappers library or that have been
#               started through a tcp_wrappers-enabled xinetd.
#
#               The rules in this file can also be set up in
#               /etc/hosts.allow with a 'deny' option instead.
#
#               See 'man 5 hosts_options' and 'man 5 hosts_access'
#               for information on rule syntax.
#               See 'man tcpd' for information on tcp_wrappers
#

#172.31. 설정은 172.31.0.0 IP대역을 의미한다.
#또한 명시적으로 192.168.10.5 IP를 입력하여 172.168.10.5/32 IP주소를 명시할 수 있다.
ALL : 172.31.
ALL : 192.168.10.5

예제로 위와 같이 설정했다. 설정 내용을 정리하자면 "서버는 172.31.0.0/16 대역과 172.168.10.5 IP주소의 접근을 막겠다. 하지만 172.31.10.0/24 대역은 허용하겠다."라는 의미이다. 재밌는 점은 Deny 설정보다 Allow 설정이 더 우선시된다는 점이다. 172.31.0.0/16 대역을 Deny 했음에도 불구하고 172.31.10.0/24 대역은 접근이 가능하다는 점이다. 그리고 굳이 sshd 서비스를 재시작(sudo service sshd restart) 하지 않아도 바로 설정이 적용된다. 

 

원리를 이해해보자

먼저 TCP Wrapper에 대해서 알아야 한다. TCP Wrapper란 접근하는 네트워크 트래픽에 필터링을 걸어 Client가 서비스에 연결할 수 있는지 없는지 판단하는 ACL 라이브러리와 같은 것이다.

TCP Wrapper는 호스트 액세스 파일이라고도 불리는 두 파일을 참조하여 동작하는데, 그것이 hosts.allow와 hosts.deny이다. hosts.allow와 hosts.deny에 각각 서버 데몬과 클라이언트의 액세스를 선택적으로 허용 혹은 거부할 수 있다. 여기서 TCP Wrapper의 동작 순서를 보면 왜 ALLOW 규칙이 DENY보다 우선시되는지 알 수 있다.

1. 서비스에 접근하는 액세스를 TCP Wrapper는 hosts.allow와 hosts.deny를 참고하여 필터링된다.
2. 먼저 hosts.allow를 읽는다.
3. hosts.allow의 설정 값을 위에서부터 한 줄씩 규칙과 액세스를 비교한다.
4. hosts.allow의 '데몬 - 클라이언트' 줄과 일치하는 것이 있다면 허용한다.
5. 만약 일치하는 것이 없다면 hosts.deny 파일을 읽는다.
6. hosts.deny의 설정 값을 위에서부터 한 줄씩 규칙과 액세스를 비교한다.
7. hosts.deny의 '데몬 - 클라이언트' 줄과 일치하는 것이 있다면 거부한다.
8. 만약 일치하는 것이 없다면 액세스를 허용한다.

즉, 어느 파일에도 일치하는 규칙이 없다면 암묵적으로 허용되며, 설령 hosts.allow와 hosts.deny에 같은 '데몬 - 클라이언트' 규칙이 등록되어 있어도 TCP Wrapper는 hosts.allow를 먼저 읽기 때문에 해당 액세스를 허용되게 된다. 

분석/정리하면서 Firewall과 TCP Wrapper가 어떻게 동작할지 궁금했다. 개인적으로 테스트를 해보았을 때, 둘 중 어느 하나라도 막아버리면 통신이 안 되는 것을 확인했지만 분명 먼저 동작하는 녀석이 있을 것이다. 이것에 대한 정답은 "Firewall이 먼저 동작한다."이다. 이유는 Firewall는 OSI 3 계층(Network Layer)이며 TCP Wrapper는 OSI 7 계층(Application Layer)이기 때문이라고 한다. 참고 정도만 해두자. 

반응형
Comments