로그인 프롬프트 전에 SSH가 중단됩니다.

로그인 프롬프트 전에 SSH가 중단됩니다.

나는 debian jessie를 실행하는 원격 라즈베리 파이에서 여러 개의 역방향 SSH 터널을 설정했습니다. RPI는 3G 동글을 사용하여 인트라넷 연결을 얻습니다. 이것이 바로 역방향 SSH를 사용하여 원격으로 로그인하는 이유입니다. 각 RPI는 각 시스템에 로그인하는 데 사용하는 클라우드 서버에 대한 역방향 SSH 터널을 설정합니다.

SSH 터널 설정은 다음과 같습니다.

ssh -N -o ExitOnForwardFailure=yes -R 23xx:localhost:22 [email protected]

여기서 23xx는 포트 22에서 연결을 전달하는 데 사용되는 포트이고 178.xxxxx는 서버의 IP 주소입니다.

내 문제는 때때로 시스템에 SSH를 연결하려고 할 때 다음과 같은 오류 없이 영원히 중단된다는 것입니다.

ssh pi_username@localhost -p 23xx

그 후 터미널은 아무 것도 출력하지 않고 영원히 정지됩니다. -vvv를 사용하여 디버깅을 시도하면 다음과 같은 결과가 나타납니다.

ssh pi_username@localhost -p 23xx -vvv

OpenSSH_6.7p1 Debian-5+deb8u4, OpenSSL 1.0.1t  3 May 2016
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 localhost [::1] port 23xx.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_rsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_dsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/master/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u4

연결이 설정된 것 같지만 로그인 프롬프트가 표시되지 않습니다. 어떤 아이디어가 있나요? 이를 추가로 디버깅하는 방법에 대한 제안이 있으십니까?

답변1

이것은 단지 이론일 뿐이지만 SSH 세션에 대한 TCP 연결이 사라지고 있지만 "클라우드 서버"가 이를 감지하지 못하는 것이 무슨 일인지 의심됩니다. 따라서 connect 로 이동하면 localhost -p 23xxssh 프로세스는 여전히 살아 있고 수신 대기 중이지만 Pi로 데이터를 다시 보내려고 하면 최대 TCP 재전송 횟수에 도달할 때까지 멈추고 마침내 연결이 끊어졌다고 판단하여 종료됩니다( 영원히 멈춘다고 하셨지만 충분히 오래 기다리면 연결이 재설정될 것입니다.)
이제 SSH 터널이 다운된 경우 다시 연결하도록 Pi를 구성했다고 가정하면 이것이 문제를 해결해야 한다고 생각할 수 있습니다. 이 아이디어에는 몇 가지 잠재적인 문제가 있습니다. 첫째, Pi도 끊어진 연결을 감지하지 못했을 수 있습니다. 따라서 데이터 전송을 시도하고 TCP 재전송 제한에 도달할 때까지 끊어진 연결을 확인하지 않고 다시 연결합니다. 두 번째 잠재적인 문제는 연결이 끊긴 것을 감지하고 다시 연결을 시도하더라도 이전 SSH가 여전히 거기에 있고 포트를 점유하고 있기 때문에 클라우드 서버에서 리스너를 설정할 수 없다는 것입니다.

여기서 해결 방법은 끊어진 연결을 감지할 수 있도록 ssh를 구성하는 것입니다. 이 문제를 해결하는 방법에는 TCP KeepAlive와 SSH KeepAlive 등 여러 가지가 있습니다. (인용하다:https://unix.stackexchange.com/a/34201/4358)

TCP KeepAlive( TCPKeepAlivessh 구성에 설정)는 TCP의 기본 연결 유지 기능을 사용합니다. 기본적으로 커널은 X초마다 빈 TCP ACK를 보내고, 상대방으로부터 ACK를 받지 못하거나 재설정되면 연결을 닫아 애플리케이션(SSH)에 알립니다.

SSH KeepAlive( ServerAlive*& ClientAlive*설정)는 유사하지만 더 높은 수준에서 작동합니다. 여기서 SSH 프로세스는 연결을 통해 실제 데이터를 보내고 응답을 찾습니다. 이는 일반 TCP KeepAlive처럼 끊어진 연결을 감지해야 하지만 중간 홉이 TCP KeepAlive 패킷을 인식하고 무시할 수 있을 뿐만 아니라 유휴 연결 시간을 초과할 수 있으므로 연결을 활성 상태로 유지할 가능성이 더 높습니다. 그러나 SSH KeepAlive는 중간 홉에 도착하는 실제 트래픽처럼 보이기 때문에 인식되지 않습니다.

간단히 말해서:

Raspberry Pi에서 SSH 클라이언트 구성( ~/.ssh/config또는 /etc/ssh/ssh_config)에 다음 설정을 추가합니다.

ServerAliveInterval 15
ServerAliveCountMax 1

(문서)

서버에서 SSH 데몬 구성( /etc/ssh/sshd_config)에 다음 설정을 추가합니다.

ClientAliveInterval 20
ClientAliveCountMax 1

(문서)

간격 값을 약간 더 높게 설정했습니다. 그 이유는 양 당사자가 정확히 동시에 KeepAlive 메시지를 보내고 회선에서 서로 교차하는 것을 방지하기 위한 것입니다. 실제로 해가 되는 것은 없으며 단지 약간 비효율적일 뿐입니다. 서로 다르기만 하면 어느 쪽이 더 높은지는 중요하지 않습니다.

답변2

나는 같은 문제에 직면했다.

$ ifconfig wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.9  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::d949:d257:c622:3388  prefixlen 64  scopeid 0x20<link>
        ether 18:1d:ea:00:4e:cf  txqueuelen 1000  (Ethernet)
        RX packets 333970  bytes 471184965 (449.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 76462  bytes 9787485 (9.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

mtu 값을 1200으로 변경합니다. (최대 전송 단위)

$ ifconfig wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1200
        inet 192.168.1.9  netmask 255.255.255.0  broadcast 192.168.1.255
        ether 18:1d:ea:00:4e:cf  txqueuelen 1000  (Ethernet)
        RX packets 334117  bytes 471271158 (449.4 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 76604  bytes 9808842 (9.3 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

이 SSH가 예상대로 연결되면. 이 답변이 솔루션 검색 시간을 단축할 수 있기를 바랍니다. :)

관련 정보