SSH 连接在一个接口上失败,但在另一个接口上有效 - kex_exchange_identification:读取:连接超时

SSH 连接在一个接口上失败,但在另一个接口上有效 - kex_exchange_identification:读取:连接超时

由于某种原因,我无法通过机器中的两个物理网卡之一通过 SSH 连接到我的 Ubuntu 22.04.2 LTS 服务器,并出现以下响应:

kex_exchange_identification: read: Connection timed out
banner exchange: Connection to 10.10.100.Y port 22: Connection timed out

我可以通过另一个接口毫无问题地连接到同一台服务器。

在职的接口(eno1)设置了以下 IP 地址详细信息,以便可以从我的主要内部网络暂时使用:

IP: 192.168.1.X
NM: 255.255.255.0
GW: 192.168.1.253
BC: 192.168.1.255

不允许我连接的接口(enp2s0)被设置为在单独的网络上进行通信:

IP: 10.10.100.Y
NM: 255.255.255.192
GW: 10.10.100.253
BC: 10.10.100.255

我可以使用PING接口10.10.100.Y,没有任何基本连接问题的迹象。我来自与接口相同的网络eno1192.168.1.X),并且正如我所说,我可以通过 SSH 连接到该接口,没有任何问题。

Pinging 10.10.100.Y with 32 bytes of data:
Reply from 10.10.100.Y: bytes=32 time<1ms TTL=64
Reply from 10.10.100.Y: bytes=32 time<1ms TTL=64
Reply from 10.10.100.Y: bytes=32 time<1ms TTL=64
Reply from 10.10.100.Y: bytes=32 time<1ms TTL=64

Ping statistics for 10.10.100.Y:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 0ms, Average = 0ms

再举个例子,我还有一个 Ubuntu VM(20.04.6 LTS),运行在 Antsle Nano(基本上是 Rasperry Pi 设备)上,它与enp2s0上面描述的接口位于同一网络上,我可以通过 SSH 连接,不会出错。它的 IP 地址详细信息为接口有:

IP: 10.10.100.Z
NM: 255.255.255.192
GW: 10.10.100.253
BC: 10.10.100.255

我查看了 SE 和其他网站上的几个问题和答案,并检查了大量可能的原因,但似乎仍然无法使 SSH 连接在界面上工作enp2s0。以下是我在“问题”服务器上查看的一些内容:

/etc/hosts.allow

sendmail: all
# /etc/hosts.allow: list of hosts that are allowed to access the system.
#                   See the manual pages hosts_access(5) and hosts_options(5).
#
# Example:    ALL: LOCAL @some_netgroup
#             ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#

sshd: ALL: aclexec /usr/local/bin/sshfilter.sh %a

这是使用 GeoIP 脚本(sshfilter.sh)来阻止来自“危险”国家/地区的传入 SSH 连接(两个服务器都使用相同的脚本)。

/etc/hosts.deny

# /etc/hosts.deny: list of hosts that are _not_ allowed to access the system.
#                  See the manual pages hosts_access(5) and hosts_options(5).
#
# Example:    ALL: some.host.name, .some.domain
#             ALL EXCEPT in.fingerd: other.host.name, .other.domain
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
# The PARANOID wildcard matches any host whose name does not match its
# address.
#
# You may wish to enable this to ensure any programs that don't
# validate looked up hostnames still leave understandable logs. In past
# versions of Debian this has been the default.
# ALL: PARANOID

sshd: ALL

使用(据称)sshfilter.sh中的脚本hosts.allow可以按照我期望的方式工作。

/etc/ssh/sshd_config

Include /etc/ssh/sshd_config.d/*.conf
Protocol 2
ListenAddress 192.168.1.X
ListenAddress 10.10.100.Y
LogLevel VERBOSE
LoginGraceTime 30
PermitRootLogin yes
PubkeyAuthentication yes
AuthenticationMethods publickey
HostbasedAuthentication no
IgnoreRhosts yes
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
TCPKeepAlive yes
#AllowTcpForwarding no
X11Forwarding yes
PrintMotd no
PrintLastLog no
ClientAliveInterval 150
ClientAliveCountMax 0
AcceptEnv LANG LC_*
Subsystem sftp  /usr/lib/openssh/sftp-server
AllowUsers myuser anotheruser

我添加了这些ListenAddress行(并重新启动了sshd服务)但没有帮助。

ufw status

Status: inactive

/etc/netplan/netcfg.yaml

# This is the network config written by 'subiquity'
network:
  ethernets:
    enp2s0:
      dhcp4: false
      addresses:
        - 10.10.100.Y/26
      nameservers:
        addresses:
          - 68.105.29.16
          - 68.105.28.16
          - 1.1.1.1
          - 9.9.9.9
          - 8.8.8.8
          - 10.10.100.253
      routes:
      - to: default
        via: 10.10.100.253
        metric: 100
    eno1:
      dhcp4: false
      addresses:
        - 192.168.1.X/24
      nameservers:
        addresses:
          - 68.105.29.16
          - 68.105.28.16
          - 1.1.1.1
          - 9.9.9.9
          - 8.8.8.8
          - 192.168.1.253
      routes:
      - to: default
        via: 192.168.1.253
        metric: 200
  renderer: NetworkManager
  version: 2

/etc/nftables.conf

flush ruleset

# `inet` applies to both IPv4 and IPv6.
table inet filter {
    chain input {
        type filter hook input priority 0;

        # accept any localhost traffic
        iif lo accept

        # no ping floods:
        ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets drop
        ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate over 10/second burst 4 packets drop

        # accept traffic originated from us
        ct state established,related accept

        # accept ICMP & IGMP
        ip6 nexthdr icmpv6 icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-sol>        ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } accept
        ip protocol igmp accept

        # ssh
        tcp dport 22 accept

        # http, https
        tcp dport 80 accept
        tcp dport 443 accept

        # smtp, submission, smtps
        tcp dport 25 accept
        tcp dport 587 accept
        tcp dport 465 accept

        # pop3, pop3s
        tcp dport 110 accept
        tcp dport 995 accept

        # imap, imaps
        tcp dport 143 accept
        tcp dport 993 accept

        # count and drop any other traffic
        counter drop
    }

    chain output {
        type filter hook output priority 0;
        policy accept;
    }

    chain forward {
        type filter hook forward priority 0;
        policy drop;
    }
}

iptables -L

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER-USER  all  --  anywhere             anywhere
DOCKER-ISOLATION-STAGE-1  all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             172.D.0.2           tcp dpt:5000

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target     prot opt source               destination
DOCKER-ISOLATION-STAGE-2  all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-ISOLATION-STAGE-2 (1 references)
target     prot opt source               destination
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Chain DOCKER-USER (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

route -n

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.10.100.253   0.0.0.0         UG    100    0        0 enp2s0
0.0.0.0         192.168.1.253   0.0.0.0         UG    200    0        0 eno1
172.D.0.0       0.0.0.0         255.255.0.0     U     0      0        0 docker0
10.10.100.192   0.0.0.0         255.255.255.192 U     101    0        0 enp2s0
192.168.1.0     0.0.0.0         255.255.255.0   U     100    0        0 eno1

netstat -tulpn | grep :22

(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 192.168.1.X:22        0.0.0.0:*               LISTEN      -
tcp        0      0 10.10.100.Y:22        0.0.0.0:*               LISTEN      -

ip r

default via 10.10.100.253 dev enp2s0 proto static metric 100
default via 192.168.1.253 dev eno1 proto static metric 200
10.10.100.192/26 dev enp2s0 proto kernel scope link src 10.10.100.Y metric 101
172.D.0.0/16 dev docker0 proto kernel scope link src 172.D.0.1
192.168.1.0/24 dev eno1 proto kernel scope link src 192.168.1.X metric 100

ifconfig

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.D.0.1  netmask 255.255.0.0  broadcast 172.D.255.255
        inet6 fe80::42:d3ff:fe5e:1111  prefixlen 64  scopeid 0x20<link>
        ether 02:42:d3:5e:46:11  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 2  overruns 0  frame 0
        TX packets 78  bytes 11868 (11.8 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.X  netmask 255.255.255.0  broadcast 192.168.1.255
        inet6 fe80::1a03:73ff:feb8:1111  prefixlen 64  scopeid 0x20<link>
        ether 18:03:73:b8:82:11  txqueuelen 1000  (Ethernet)
        RX packets 203434  bytes 14342810 (14.3 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 6615  bytes 1573720 (1.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 20  memory 0xe1b00000-e1b20000

enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.10.100.Y  netmask 255.255.255.192  broadcast 10.10.100.255
        inet6 fe80::6a05:caff:fec2:1111  prefixlen 64  scopeid 0x20<link>
        ether 68:05:ca:c2:b0:11  txqueuelen 1000  (Ethernet)
        RX packets 29985  bytes 11846128 (11.8 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 18305  bytes 2268768 (2.2 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 18  memory 0xe10c0000-e10e0000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 891535  bytes 248668330 (248.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 891535  bytes 248668330 (248.6 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

vethb9d0ba4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c76:3cff:fe82:1111  prefixlen 64  scopeid 0x20<link>
        ether 0e:76:3c:82:f4:11  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0

ssh-keyscan 10.10.100.Y

read (10.10.100.Y): Connection timed out
read (10.10.100.Y): Connection timed out
read (10.10.100.Y): Connection timed out
read (10.10.100.Y): Connection timed out
read (10.10.100.Y): Connection timed out

ssh-keyscan 192.168.1.X

# 192.168.1.X:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
192.168.1.X ssh-rsa <key here>
# 192.168.1.X:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
192.168.1.X ecdsa-sha2-nistp256 <key here>
# 192.168.1.X:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
192.168.1.X ssh-ed25519 <key here>
# 192.168.1.X:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1
# 192.168.1.X:22 SSH-2.0-OpenSSH_8.9p1 Ubuntu-3ubuntu0.1

我将所有这些信息与 Antsle VM 中的相同信息进行了比较,尝试尽可能多地进行“同类”比较,并尝试找出任何明显错误的地方,但没有发现任何异常。我还应该/可以在哪里找到问题?


故障排除(来自评论)

  • 我能够毫无问题地enp2s0从位于同一网络上的 RasPi 设备通过 SSH 连接到接口。10.10
  • 我已从我的中删除了该脚本hosts.allow并将其设置为sshd : ALL,但这没有帮助。
  • 我有不是但尝试禁用公钥认证并尝试使用密码登录,但我稍后会测试一下。
  • 根据sysctl net.ipv4.ip_forward,看起来 IP 转发已启用,尽管它似乎没有作为服务运行(Unit sysctl.service could not be found.
  • 我尝试将/etc/nftables.confFORWARD 策略从更新dropallow,但没有帮助。
  • 我一直在通过网络防火墙设备查找与该 IP 地址 ( 10.10.100.Y) 的连接是否存在任何“不同”,但始终一无所获。与同一网络上的 RasPi 设备的连接工作正常,因此防火墙知道如何在两个子网之间路由。如果防火墙问题是,它似乎必须是为该 IP 地址或某物明确定义的规则。

根据请求 以下是此处所使用的网络拓扑的“简化”图: 网络拓扑结构

  • Fortigate 防火墙是我们网络的“边缘”设备。
  • 接口 1 是主 LAN ( 192.168),接口 3 是“辅助” LAN ( 10.10)。
  • 接口 1 连接到 24 端口 PoE 交换机,该交换机为我们网络的其余部分供电。接口 3 连接到“专用于”网络的小型交换机10.10

我之前提到过,我可以从公共 IP 地址访问“问题”接口,但前提是我从另一个网络进行访问(例如家里)。尝试从此处的192.168网络通过 SSH 访问该站点时超时(没有关于的消息kex_exchange_identification)。

现在是不是每个人都有这种感觉,还是只有我一个人这样?


更新(仍然不起作用):

经过一番搜索,我记起 22.04 服务器 ( 10.10.100.Y) 已nftables作为防火墙运行(而不是ufw)。我已nftables.conf在上面发布了详细信息以及其他防火墙信息。

这个谜题的另一个有趣之处是:我的防火墙设置了一个“虚拟 IP”,用于将流量路由到我在该服务器上分配的公共 IP 地址 ( 24.249.N.N) 到接口上的内部私有 IP enp2s0( 10.10.100.Y)。我尝试从远程网络通过 SSH 进入服务器的公共 IP 地址,它运行正常,因此这似乎排除了许多服务器配置解决方案,并让我相信问题可能出在防火墙级别,即使我可以 PING 该接口,甚至可以毫无问题地连接到同一网络上的另一台设备。

为了尝试覆盖所有基础,我检查了fail2banSSH 监狱中客户端设备的 IP 地址,但它没有出现在那里。

此外,尽管我不知道如何真正阅读它们,但我还是从头到尾运行了一些数据包捕获,以查看是否有任何异常。在服务器上,我tcpdump -i enp2s0 port 22 and src 192.168.1.C在尝试连接时运行了这些数据包,结果如下:

tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on enp2s0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
11:28:04.935646 IP 192.168.1.C.50719 > 10.10.100.Y.ssh: Flags [S], seq 3110886807, win 64240, options [mss 1460,nop,wscale 8,nop,nop,sackOK], length 0

1 packet captured
1 packet received by filter
0 packets dropped by kernel

似乎只有一个数据包到达了该接口,无论出于什么原因。其他数据包捕获(来自我的客户端和防火墙本身)提供了更多信息,但正如我所说,我不确定如何阅读所有内容,甚至不知道如何提供屏幕截图和/或上传文件以外的详细信息.pcap,因此这里有一些图片: SSH 协商失败期间的 Wireshark 捕获 SSH 协商失败,导致出现以下Connection timed out消息

Wireshark 捕获到“工作”服务器 此连接失败只是因为我没有使用公钥进行身份验证

显然,我的工作站和“工作”服务器之间存在着更多的主动通信。

我不知道我现在是否更加困惑,但我仍然不知道下一步该看哪里。


更新 #2:

我仍然无法通过 SSH 连接到该enp2s0接口,但由于我能够连接到该eno1接口,所以我一直在花时间处理这个问题并尝试设置另一个包 -远程。我提出这个问题的唯一原因是我无法连接到该服务除了有那么一瞬间,我能够让登录/管理页面出现(eno1界面上,但仍然)。我不知道一件事是否与另一件事有关,但它随机开始工作然后再次停止的事实让我认为发生了一些非常奇怪的事情。

虽然我仍然认为我们的网络防火墙设备存在问题,但有两件事让我认为这是不是问题:

  1. 我可以连接到该10.10网络上的另一个设备(RasPi)
  2. 我可以通过我分配并路由到接口的公共 IP 地址从外部连接连接到服务器enp2s0

当然,#2 也让我认为问题不太可能是服务器的配置问题,所以我完全感到困惑。

为了提供尽可能多的信息,我还添加了我的 netplan 配置信息。我曾怀疑问题是否在于连接“默认”到接口,eno1从而导致路由出现一些“混乱”,但我认为配置不支持该理论。


更新 #3 (有点“固定” (?)):

嗯,有趣的发展……谢天谢地,我可以访问该机器的控制台,所以我完全禁用了网卡eno1,并尝试通过 SSH 连接到它10.10.100.Y,它成功连接了。我甚至尝试使用公共 IP 24.249.N.B,这次也成功了。我重新启用了eno1接口并再次尝试,但仍然出现错误kex_exchange_identification

我觉得这个问题可能与两个不同的子网“搞乱”了机器上的网络有关,于是我继续重新配置接口eno1以使用来自同一子网范围的另一个 IP(10.10.100.E),然后我能够10.10.100.Y再次成功通过 SSH 连接到。在编辑sshd_config将 更改ListenAddress为包含新 IP 后,我甚至能够通过 SSH 连接到10.10.100.E

因此,在使用两个不同的子网时,似乎有什么东西导致了两个接口(eno1enp2s0)之间发生某种冲突。也许防火墙在尝试路由两个网络之间的流量时“失灵了”。我仍然对此感到困惑,真的很想了解为什么这是一个很大的问题,但目前看起来与该服务器的所有连接都按预期工作。

相关内容