Debian

Jumphost 突然重置第一次 SSH MUX 連接嘗試

  • June 10, 2020

一段時間以來,我一直在使用 Debian 9 SSH jumpbox 主機來執行我的腳本/ansible 劇本。jumbox 主要與 Debian 9 和一些 Debian 8 伺服器通信。大多數伺服器是在 VMWare Enterprise 5.5 下執行的 VM。

jumbox 中的 SSH 客戶端配置為進行 SSH MUX,並且通過 RSA 證書文件進行身份驗證。

SSH 多年來一直執行良好,但是突然 SSH 連接ssh_exchange_identification: read: Connection reset by peer在第一次嘗試時開始出現錯誤,一天幾次,這顯然對我的腳本和我們開發團隊的腳本造成了嚴重破壞。

但是,在第一次嘗試後,它們暫時還可以。伺服器的行為不端一開始似乎是隨機的,但有一些模式/超時。如果我確實向所有伺服器發送命令,例如,在預期腳本/劇本之前的命令中執行,一些會失敗,但下一個腳本將在所有伺服器中執行。

除了安全更新外,伺服器最近沒有發生重大變化。Debian 9 的過渡已經有一些(重要的)時間。

我已經找到了一個 MTU(錯誤)配置或其他配置,它曾經在故障中應用於多台伺服器並被遺忘,但事實並非如此。ControlPersist我還將客戶端和伺服器端的時間ClientAliveInterval都減少到了 1 小時,但這並沒有改善這種情況。

所以目前,我不知道為什麼會這樣。然而,我更傾向於第 7 層問題而不是網路問題。

客戶端的 SSH 配置/etc/ssh_config,Debian 9 是:

Host *
SendEnv LANG LC_*
HashKnownHosts yes
GSSAPIAuthentication yes
GSSAPIDelegateCredentials no
ControlMaster auto
ControlPath /tmp/ssh_mux_%h_%p_%r
ControlPersist 1h
Compression no
UseRoaming no

在幾個 Debian 伺服器的伺服器端的 SSH 上:

Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
UsePrivilegeSeparation yes

SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin forced-commands-only 
StrictModes yes
PubkeyAuthentication yes
IgnoreRhosts yes
HostbasedAuthentication no
PermitEmptyPasswords no
ChallengeResponseAuthentication no
PasswordAuthentication no

X11Forwarding no
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes

AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server -l INFO
UsePAM yes
ClientAliveInterval 3600
ClientAliveCountMax 0
AddressFamily inet

SSH 版本:

客戶 -

$ssh -V 
OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l  25 May 2017

伺服器

SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u1 (Debian 9)
SSH-2.0-OpenSSH_6.7p1 Debian-5+deb8u3  (Debian 8)

至少在兩台伺服器都使用 4.9.0-0.bpo.1-amd64 版本的情況下,我已經看到了這個錯誤。

以下tcpdump是伺服器行為不端的情況,兩台機器都在同一個網路中,中間沒有任何防火牆。我還監視 MAC 地址,並且在過去幾年中沒有記錄具有相同 MAC 地址的新機器/MAC。

#tcpdump port 22
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
19:42:25.462896 IP jumbox.40270 > server.ssh: Flags [S], seq 3882361678, win 23200, options [mss 1160,sackOK,TS val 354223428 ecr 0,nop,wscale 7], length 0
19:42:25.463289 IP server.ssh > jumbox.40270: Flags [S.], seq 405921081, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:25.463306 IP jumbox.40270 > server.ssh: Flags [.], ack 1, win 182, length 0
19:42:25.481470 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:25.481477 IP jumbox.40270 > server.ssh: Flags [.], ack 504902058, win 182, length 0
19:42:25.481490 IP server.ssh > jumbox.40270: Flags [R], seq 405921082, win 0, length 0
19:42:25.481494 IP server.ssh > jumbox.40270: Flags [P.], seq 504902058:504902097, ack 1, win 182, length 39
19:42:26.491536 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:26.491551 IP jumbox.40270 > server.ssh: Flags [R], seq 3882361679, win 0, length 0
19:42:28.507528 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:28.507552 IP jumbox.40270 > server.ssh: Flags [R], seq 3882361679, win 0, length 0
19:42:32.699540 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:32.699556 IP jumbox.40270 > server.ssh: Flags [R], seq 3882361679, win 0, length 0
19:42:40.891490 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:40.891514 IP jumbox.40270 > server.ssh: Flags [R], seq 3882361679, win 0, length 0
19:42:57.019511 IP server.ssh > jumbox.40270: Flags [S.], seq 4195986320, ack 3882361679, win 23200, options [mss 1160,nop,nop,sackOK,nop,wscale 7], length 0
19:42:57.019534 IP jumbox.40270 > server.ssh: Flags [R], seq 3882361679, win 0, length 0

連接失敗的ssh -v server日誌,帶有重置錯誤:

OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l  25 May 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: /etc/ssh/ssh_config line 59: Deprecated option "useroaming"
debug1: auto-mux: Trying existing master
debug1: Control socket "/tmp/ssh_mux_fenix-storage_22_rui" does not exist
debug1: Connecting to fenix-storage [10.10.32.156] port 22.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_rsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_dsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
write: Connection reset by peer

一個ssh -v server成功的連接:

OpenSSH_7.4p1 Debian-10+deb9u1, OpenSSL 1.0.2l  25 May 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: /etc/ssh/ssh_config line 59: Deprecated option "useroaming"
debug1: auto-mux: Trying existing master
debug1: Control socket "/tmp/ssh_mux_sql01_22_rui" does not exist
debug1: Connecting to sql01 [10.20.10.88] port 22.
debug1: Connection established.
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_rsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_rsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_dsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_dsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ecdsa type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ecdsa-cert type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ed25519 type -1
debug1: key_load_public: No such file or directory
debug1: identity file /home/rui/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u1
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.4p1 Debian-10+deb9u1
debug1: match: OpenSSH_7.4p1 Debian-10+deb9u1 pat OpenSSH* compat 0x04000000
debug1: Authenticating to sql01:22 as 'rui'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: rsa-sha2-512
debug1: kex: server->client cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: kex: client->server cipher: chacha20-poly1305@openssh.com MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ssh-rsa SHA256:6aJ+ipXRZJfbei5YbYtvqKXB01t1YO34O2ChdT/vk/4
debug1: Host 'sql01' is known and matches the RSA host key.
debug1: Found key in /home/rui/.ssh/known_hosts:315
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 134217728 blocks
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,ssh-rsa,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /home/rui/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 277
debug1: Authentication succeeded (publickey).
Authenticated to sql01 ([10.20.10.88]:22).
debug1: setting up multiplex master socket
debug1: channel 0: new [/tmp/ssh_mux_sql01_22_rui]
debug1: control_persist_detach: backgrounding master process
debug1: forking to background
debug1: Entering interactive session.
debug1: pledge: id
debug1: multiplexing control connection
debug1: channel 1: new [mux-control]
debug1: channel 2: new [client-session]
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LC_ALL = en_US.utf8
debug1: Sending env LANG = en_US.UTF-8
debug1: mux_client_request_session: master session id: 2

有趣的是,可以使用 telnet 命令重現該行為:

$ telnet remote-server 22
Trying x.x.x.x...
Connected to remote-server
Escape character is '^]'.
Connection closed by foreign host.
$ telnet remote-server 22
Trying x.x.x.x...
Connected to remote-server
Escape character is '^]'.
SSH-2.0-OpenSSH_7.4p1 Debian-10+deb9u1

Protocol mismatch.
Connection closed by foreign host.

更新:

強制Protocol 2/etc/ssh_client客戶端配置中跳轉。不用找了。

更新2:

將使用 DES-EDE3-CBC 加密的舊密鑰更改為使用 AES-128-CBC 加密的新密鑰。再次沒有明顯的變化。

更新3:

有趣的是,當多路復用器處於活動狀態時,情況並沒有出現。

更新4:

我也在 serverfault 發現了一個類似的問題,但是沒有選擇答案:https ://serverfault.com/questions/445045/ssh-connection-error-ssh-exchange-identification-read-connection-reset-by-pe

嘗試重新生成 ssh 主機密鑰,sshd: ALL但沒有成功的建議。

更新 5

在目的地的虛擬機上打開一個控制台,看到一些“奇怪”的東西。tcpdump 而 1.1.1.1 是跳轉框。

# tcpdump -n -vvv "host 1.1.1.1"
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:47:45.808273 IP (tos 0x0, ttl 64, id 38171, offset 0, flags [DF], proto TCP (6), length 60)
   1.1.1.1.37924 > 1.1.1.2.22: Flags [S], cksum 0xfc1f (correct), seq 3260568985, win 29200, options [mss 1460,sackOK,TS val 407355522 ecr 0,nop,wscale 7], length 0
11:47:45.808318 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
   1.1.1.2.22 > 1.1.1.1.37924: Flags [S.], cksum 0x5508 (incorrect -> 0x68a8), seq 2881609759, ack 3260568986, win 28960, options [mss 1460,sackOK,TS val 561702650 ecr 407355522,nop,wscale 7], length 0
11:47:45.808525 IP (tos 0x0, ttl 64, id 38172, offset 0, flags [DF], proto TCP (6), length 52)
   1.1.1.1.37924 > 1.1.1.2.22: Flags [.], cksum 0x07b0 (correct), seq 1, ack 1, win 229, options [nop,nop,TS val 407355522 ecr 561702650], length 0
11:47:45.808917 IP (tos 0x0, ttl 64, id 38173, offset 0, flags [DF], proto TCP (6), length 92)
   1.1.1.1.37924 > 1.1.1.2.22: Flags [P.], cksum 0x6de0 (correct), seq 1:41, ack 1, win 229, options [nop,nop,TS val 407355522 ecr 561702650], length 40
11:47:45.808930 IP (tos 0x0, ttl 64, id 1754, offset 0, flags [DF], proto TCP (6), length 52)
   1.1.1.2.22 > 1.1.1.1.37924: Flags [.], cksum 0x5500 (incorrect -> 0x0789), seq 1, ack 41, win 227, options [nop,nop,TS val 561702651 ecr 407355522], length 0
11:47:45.822178 IP (tos 0x0, ttl 64, id 1755, offset 0, flags [DF], proto TCP (6), length 91)
   1.1.1.2.22 > 1.1.1.1.37924: Flags [P.], cksum 0x5527 (incorrect -> 0x70c1), seq 1:40, ack 41, win 227, options [nop,nop,TS val 561702654 ecr 407355522], length 39
11:47:45.822645 IP (tos 0x0, ttl 64, id 21666, offset 0, flags [DF], proto TCP (6), length 40)
   1.1.1.1.37924 > 1.1.1.2.22: Flags [R], cksum 0xaeb1 (correct), seq 3260569026, win 0, length 0
11:47:50.919752 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 1.1.1.2 tell 1.1.1.1, length 46
11:47:50.919773 ARP, Ethernet (len 6), IPv4 (len 4), Reply 1.1.1.2 is-at 00:50:56:b9:3d:2b, length 28
11:47:50.948732 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has 1.1.1.1 tell 1.1.1.2, length 28
11:47:50.948916 ARP, Ethernet (len 6), IPv4 (len 4), Reply 1.1.1.1 is-at 00:50:56:80:57:1a, length 46
^C
11 packets captured
11 packets received by filter
0 packets dropped by kernel

更新 6

由於校驗和錯誤,我禁用了將 TCP/UDP 校驗和解除安裝到 VM 中的 NIC,但它並沒有改善這種情況。

$sudo ethtool -K eth0 rx off
$sudo ethtool -K eth0 tx off

iface eth0 inet static
  address 1.1.1.2
  netmask 255.255.255.0
  network 1.1.1.0
  broadcast 1.11.1.255
  gateway 1.1.1.254
  post-up /sbin/ethtool -K $IFACE rx off
  post-up /sbin/ethtool -K $IFACE tx off

了解 VMware 環境中的 TCP 校驗和解除安裝 (TCO) (2052904)

更新 7

GSSAPIAuthentication在跳轉框的 ssh 客戶端中禁用。測試Enable Compression yes無變化。

更新 8

測試用 填充校驗和iptables

/sbin/iptables -A POSTROUTING -t mangle -p tcp -j CHECKSUM --checksum-fill

它並沒有改善這種情況。

更新 9:

發現了一個關於限制密碼的有趣測試,將嘗試一下。MTU 問題似乎不是罪魁禍首,因為在某些情況下,同一網路中的伺服器和客戶端會出現問題。

目前在客戶端“ssh -c aes256-ctr”測試,症狀沒有改善。

SSH 客戶端損壞的神秘案例(“對等連接重置”)

更新 10

將此添加到/etc/ssh/ssh_config. 沒有變化。

Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc

SSH 問題:從套接字讀取失敗:對等方重置連接

更新 11

在 22 埠和 2222 埠定義了 ssh 服務,沒有用。

更新 12

我懷疑這是 OpenSSH 7.4 中存在的回歸錯誤,已通過 OpenSSH 7.5 進行了糾正

OpenSSH 7.5 的發行說明

  • sshd(8):修復 OpenSSH 7.4 中對 server-sig-algs 擴展支持的回歸,其中 SHA2 RSA 簽名方法沒有被正確宣傳。bz#2680

為了在 Debian 9/Stretch 中使用 openSSH 7.5,我openssh-clientopenssh-serverDebian testing/Buster 安裝。

情況沒有改善。

更新 13

定義

密碼 aes256-ctr MACs hmac-sha1

在客戶端和伺服器端。沒有改進。

更新 14

設置

UseDNS no
GSSAPIAuthentication no
GSSAPIKeyExchange no

不用找了。

更新 15

/etc/ssh/sshd_config

將其更改為 /etc/ssh/sshd_config:

TCPKeepAlive no

來自tcp-keepalive 如何在 ssh 中工作?

TCPKeepAlive 執行在 TCP 層。它發送一個空的 TCP ACK 數據包

$$ from the SSH server to the client - Rui $$. 防火牆可以配置為忽略這些數據包,因此如果您通過丟棄空閒連接的防火牆,這些可能無法保持連接處於活動狀態。

我的猜測是 TCPKeepAlive 正在配置伺服器發送一個在下面的堆棧中的某個層被優化/忽略的數據包,並且遠端 SSH 伺服器在某種程度上認為它仍然連接到 TCP mux 客戶端,而實際上會話已經拆毀;因此 TCP 在第一次嘗試時重置。

因此,雖然有人說如果您使用 ClientAliveInterval,您可以禁用 TCPKeepAlive,但似乎更多的是您使用 ClientAliveInterval,您應該禁用 TCPKeepAlive。

  • 顯然是這個選項;至於解釋,它們主要是猜想,如果我有時間,將不得不仔細檢查它們/來源。

TCPKeepAlive 顯然也有欺騙問題,所以建議關閉它。

儘管如此,問題仍然存在。

最後,發現這是由於 Cisco 6059 FWSM 核心路由器和正在使用的 ASA 防火牆中的錯誤。

Linux 核心 v3 和 v4 不能很好地使用 TCP 序列隨機化,並且在傳輸大文件時會出現“隨機”問題,或者在許多連接中出現其他類型的模糊問題,其中 SSH 更為明顯。不幸的是,Windows、Mac 和 FreeBSD 執行良好,所以它可以被引用為 Linux 錯誤。

這是一個非常糟糕的情況,因為我們抱怨人們無法從我們的網站下載隨機文件。

每個 TCP 連接有兩個 ISN:一個由客戶端生成,一個由伺服器生成。ASA 隨機化在入站和出站方向上傳遞的 TCP SYN 的 ISN。

隨機化受保護主機的 ISN 可防止攻擊者預測新連接的下一個 ISN 並可能劫持新會話。

如有必要,您可以禁用 TCP 初始序列號隨機化,例如,因為數據被打亂。例如:

如果另一個內聯防火牆也在隨機化初始序列號,則不需要兩個防火牆都執行此操作,即使此操作不會影響流量。

我最初在內部核心路由器中禁用了 Cisco Randomization,這還不夠。在邊界防火牆和核心 Cisco 路由器/交換機中禁用 Cisco Randomization 後,問題停止發生。

為了禁用它,它類似於:

policy-map global_policy
   class preserve-sq-no
       set connection random-sequence-number disable

請參閱 Cisco note禁用 TCP 序列隨機化

我還在 FWSM 上發現了一個不相關的 XLATE 錯誤,用於 NAT 優化,預設情況下啟用,這會導致虛假通信問題,並且由於核心路由器不負責 NAT,因此禁用它:

xlate-bypass

啟用 xlate-bypass 在上面的兩個範例中,xlate 都是使用 Ii 標誌創建的。這些標誌表明 xlate 是源自高安全性 (i) 介面的身份轉換 (I)。預設情況下,FWSM 將為任何不匹配顯式 NAT/PAT 規則的流量建構這些 xlate。為了禁用此行為,可以在 FWSM 3.2(1) 及更高版本中啟用 xlate-bypass 命令:

FWSM(config)# xlate-bypass

當心那些是預設配置,我們花了幾個月的時間在內部調查中追踪這一點,並且我不會在這裡命名的幾家相關供應商無法確定這些配置是罪魁禍首。

您是否正在通過任何嘗試 TCP 優化的韌體或設備?我在網路上也有同樣的經歷,結果證明它是一個進行 TCP 優化的設備。

引用自:https://unix.stackexchange.com/questions/391125