AWS VPC 서브넷에 연결할 때 오해의 소지가 있는 심각한 오류가 발생합니다. B->A 연결에서는 오류가 발생하지만 A->B 연결에서는 발생하지 않아서 처음에는 라이브러리 버그인 줄 알았습니다.
이는 AWS 시스템의 "이중 계층 라우팅"과 서브넷의 NAT 인스턴스로 인해 발생했으며 실제로 패킷을 잘못된 네트워크 채널로 리디렉션하여 SSH 연결이 끊어졌습니다.
다음은 원래 스레드에서 삭제된 "사례 연구"가 포함된 내 게시물의 사본입니다.
제가 아는 한, 이는 질문에 대한 답변을 위한 시도조차 아니므로 삭제하겠습니다. 별도의 질문이 있으시면 @michael-mrozek로 편하게 글 남겨주세요 |
나는:
@patrick이 제안했듯이 (ssh_exchange_identification: 읽기: 피어에 의한 연결 재설정):
클라이언트(서브넷 B 172.16.3.76)ssh 172.16.0.141 -vvv -p23
OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug2: ssh_connect: needpriv 0
debug1: Connecting to 172.16.0.141 [172.16.0.141] port 23.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type -1
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: identity file /root/.ssh/id_ed25519 type -1
debug1: identity file /root/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2
ssh_exchange_identification: read: Connection reset by peer
서버(서브넷 A 172.16.0.141)
$(which sshd) -d -p 23
debug1: sshd version OpenSSH_6.6.1, OpenSSL 1.0.1f 6 Jan 2014
debug1: key_parse_private2: missing begin marker
debug1: read PEM private key done: type RSA
debug1: private host key: #0 type 1 RSA
debug1: key_parse_private2: missing begin marker
debug1: read PEM private key done: type DSA
debug1: private host key: #1 type 2 DSA
debug1: key_parse_private2: missing begin marker
debug1: read PEM private key done: type ECDSA
debug1: private host key: #2 type 3 ECDSA
debug1: could not open key file '/etc/ssh/ssh_host_ed25519_key': No such file or directory
Could not load host key: /etc/ssh/ssh_host_ed25519_key
debug1: rexec_argv[0]='/usr/sbin/sshd'
debug1: rexec_argv[1]='-d'
debug1: rexec_argv[2]='-p'
debug1: rexec_argv[3]='23'
Set /proc/self/oom_score_adj from 0 to -1000
debug1: Bind to port 23 on 0.0.0.0.
Server listening on 0.0.0.0 port 23.
debug1: Bind to port 23 on ::.
Server listening on :: port 23.
debug1: Server will not fork when running in debugging mode.
debug1: rexec start in 5 out 5 newsock 5 pipe -1 sock 8
debug1: inetd sockets after dupping: 3, 3
debug1: getpeername failed: Transport endpoint is not connected
debug1: get_remote_port failed
VPC 설정 및 사례 설명:
VPC에서 실행 중인 AWS EC2 Amazon 인스턴스(172.16.0.0/16)가 있습니다.
- 탄력적 IP가 연결된 퍼블릭 서브넷 A(172.16.0.0/24), NAT 인스턴스 A(172.16.0.200)가 있습니다.
- subnetA의 다른 인스턴스는 instanceA를 통해 인터넷과 통신합니다(기본값은 172.16.0.200 dev eth0을 통해).
- 서브넷B(172.16.3.0/24)에 인스턴스가 있습니다.
- 라우팅 테이블은 다음과 유사합니다.https://stackoverflow.com/questions/10243833/how-to-connect-to-outside-world-from-amazon-vpc
질문:
- 서브넷 A와 서브넷 B의 두 호스트 모두 성공적으로 ping할 수 있습니다.
- 서브넷 A의 호스트는 서브넷 B의 호스트로 SSH를 통해 연결할 수 있습니다.
- 서브넷 B의 호스트는 서브넷 A의 인스턴스 A로 SSH를 통해 연결할 수 있습니다.
- 서브넷 B의 어떤 호스트도 서브넷 A(인스턴스 A 제외)의 다른 인스턴스로 SSH를 통해 연결할 수 없습니다. 오류: ssh_exchange_identification: read: 피어에 의한 연결 재설정 IF_AND_ONLY_IF 서브넷 A의 인스턴스에는 기본 게이트웨이가 NAT-InstanceA로 설정되어 있습니다(예: 172.16을 통한 기본값) .0.200 dev eth0') not_changed 기본 게이트웨이가 있는 instance_in_subnetA가 있는 경우(예: '172.16.0.1 dev eth0을 통한 기본값') SubnetBhosts에서 해당 인스턴스로 SSH를 통해 연결할 수 있습니다.
- 참고: subnetA에 NAT가 없으면 subnetA의 인스턴스에는 나가는 인터넷 연결이 없습니다.
그래서...
이 문제는 Amazon AWS 라우터 및/또는 NAT 구성으로 인해 발생할 수 있습니다.
지금으로서는 그런 사실에도 불구하고 제 생각에는VPC 라우팅 테이블다음과 같이 설정됩니다.
Destination Target
172.16.0.0/16 local
0.0.0.0/0 igw-nnnnn
서브넷 A인스턴스는 다음 위치에 있습니다.
172.16.0.0/24
(편집 : 문제의 원인: 라우팅 테이블은 AWS 측 라우팅: 172.16.0.0/16을 포함하여 NAT 인스턴스를 통해 172.16.0.0/24 이외의 트래픽을 리디렉션합니다.
default via 172.16.0.200 dev eth0
172.16.0.0/24 dev eth0 proto kernel scope link src 172.16.0.60
서브넷 B인스턴스는 다음 위치에 있습니다.
172.16.3.0/24
서브넷 B의 호스트가 서브넷 A(NAT 인스턴스 A 제외)의 인스턴스에 연결되면 트래픽은 다음과 같습니다.
172.16.3.X/24 --> 172.16.3.1 --> 172.16.0.Y
V
??? <-- 172.16.3.200 (NAT)
여기에 문제가 있습니다. 이를 확인 해야 tcpdump
하며 NAT 규칙을 통해 해결할 수 있지만 예상보다 더 복잡합니다.
실제로 AWS 라우터의 규칙은
Destination Target
172.16.0.0/16 local
이론적으로는 VPC/16 서브넷을 포함해야 하지만 인스턴스/24 서브넷 + NAT 게이트웨이는 "system_level"의 기능을 숨깁니다.
답변1
subnetA의 인스턴스(NAT 인스턴스 172.16.0.200)에서 라우팅 테이블은 다음과 같습니다.
default via 172.16.0.200 dev eth0
172.16.0.0/24 dev eth0 proto kernel scope link src 172.16.0.141
실제로 다음과 같은 추가 사항이 있습니다.
$ ip r a 172.16.3.0/24 via 172.16.0.1
(or ip r a 172.16.3.0/16 via 172.16.0.1)
수리 시스템 라우팅 테이블:
default via 172.16.0.200 dev eth0
172.16.0.0/24 dev eth0 proto kernel scope link src 172.16.0.141
172.16.3.0/24 via 172.16.0.1 dev eth0
그리고 VPC 서브넷 경로를 AWS 라우터로 전송합니다.
Destination Target
172.16.0.0/16 local
0.0.0.0/0 igw-nnnnn