ssh原理探析

SSH是什么?

SSH是一种网络协议,用于计算机之间的加密登录。登录信息全部加密,即使被中途截获,密码也不会泄露。

SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。常用的OpenSSH是自由软件。例如win10默认已经安装了OpenSSH 在 C:\Windows\System32\OpenSSH\ssh.exe

OpenSSH有两个可执行文件, ssh 与 sshd

知识与概念

https://juejin.cn/post/7028374997269757960

基本用法

ssh -p 22 user@host

安全性

初次登录时,会提示:

The authenticity of host 'host (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is SHA256:AOnp3rCzs8rUQCddTHOkicEoW8gq0s3gNcyE7eKhEAk.
ECDSA key fingerprint is MD5:c2:ac:7a:20:60:01:a5:55:00:ad:a0:d3:2c:6a:7a:1b.

无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

用户无法知道远程主机的公钥指纹应该是多少,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对。

别的网站也贴出公钥指纹冒充怎么办呢?没关系,客户端用此公钥加密的内容,别的网站不像正宗网站一样有对应的私钥来解开

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

公钥登录

所谓"公钥登录",原理很简单, 就是用户A将自己的公钥PubKey储存在远程主机B上。登录的时候,B会向A发送一段随机字符串,A用自己的私钥加密后,再发回来给B。B用事先储存的公钥进行解密(比对解密结果与下发的字符串),如果成功,就证明A有PubKey对应的私钥,是可信的,直接免密登录shell。

ssh-keygen                  #生成密钥对
ssh-copy-id user@host       #传公钥给服务器,从此可免密

如果还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,确定以下配置。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

远程主机将用户的公钥,保存在登录后的用户主目录的$HOME/.ssh/authorized_keys文件中。公钥就是一段字符串,只要把它追加在authorized_keys文件的末尾就行了。(ssh-copy-id user@host其实就是这么做的。)

如果还是需要密码,可以查看一下日志, 日志路径因系统而异(见本文),我遇到过的一个问题是 ~/.ssh/authorized_keys读写权限不对, SSH不希望home与home/.ssh对组有写权限, 因此chmod 755就解决了。

sshd工作原理与涉及的系统调用

  1. 读取sshd_config, listen
  2. ConnFD = accept ; fork + waitpid 每个连接处理
  3. ssh协议,握手,交换密钥
  4. 账号密码验证: (这个是sshd要求的,不是操作系统要求,你自己写sshd的可以设计不要)
    • PAM(可插拔):
      • pam_unix.so 读/etc/shadow,对比
      • 或者 PublicKey 对比 ~/.ssh/authorized_key
    • 非PAM: getpwnam 与 crypt 来验证
  5. 设置sid, 分配pty
    • fork, 设父进程为"M", 子进程为"S"
    • S执行: setuid + setgid 创建会话, 切换用户
    • S执行: forkpty + openpty(master, slave) + tcsetattr + ioctl
    • S执行: dup2(slave, STD*);
  6. 启动shell
    • S执行: exec("/bin/bash") 实际执行的是pw->shell
    • 自此 S 由shell接管, 此后对pty slave的读写都是shell及子进程导致的。
  7. "M"执行
    • read(pty), 编码加密send(ConnFD)
    • recv(ConnFD), 解密后 write(pty)

可以做一个小实验,有ssh时ps 一下获取一下自己的bash的tty

$ ps
    PID TTY          TIME CMD
3855325 pts/12   00:00:00 bash
3861176 pts/12   00:00:00 ps

在另一个ssh里,执行echo, 并观察之前ssh的输出

$ sudo echo "OK" > /dev/pts/12

ssh工作原理

  1. connect()
  2. ssh协议,握手
  3. 读console,加密send
  4. recv, 解密写console

只管文件形式读写console, console可能是serial,也可能是xterm,也可能是windows黑窗口,具体console怎么渲染怎么输入,不归ssh管。

sshd配置

作为服务器,sshd的配置也很重要。

sshd的配置在 /etc/ssh/sshd_config 其主要的配置项是:
ssh的配置也在此目录,叫/etc/ssh/sshd_config

HostKey /etc/ssh/ssh_host_rsa_key
#HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

AuthorizedKeysFile .ssh/authorized_keys
X11Forwarding yes

Ciphers aes128-ctr,aes192-ctr,aes256-ctr
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256

key文件应该是安装时生成的。这些key对应的公钥是 ssh_host_ecdsa_key.pub等,用Base64编码过了。之后Base64解码后的二进制公钥会随sshv2发送给客户端,在抓到的包里是的Server:Elliptic Curve Diffie-Hellman Key Exchang包的ECDSA public key字段。

X11-forwarding 原理与排错

sshd读取/etc/ssh/sshd_config X11Forwarding yes 之后

  1. 本地监听一个 6010 端口
    • sshd-sess 726791 pxf_god 10u IPv4 1956367 0t0 TCP *:6010 (LISTEN)
  2. XClient程序比如xclock会读取$DISPLAY环境变量 (不管是ssh还是本地都读这个)
  3. XClient并不知道会不会被 forwarding, 他只认为$DISPLAY指定的就是XServer
  4. XClient向6010发指令
  5. sshd-sess 向 sshd 转发
  6. sshd 通过加密连接向 MobaXterm ssh转发
  7. MobaXterm ssh向X Server转发
  8. X Server绘制

$DISPLAY 变量是由谁设置的?

$DISPLAY 是由 SSH 服务器端(sshd)设置的,但它的值是由 SSH 客户端(ssh) 提供的。

  1. SSH 客户端 在连接时(使用 -X 或 -Y)会告诉服务器:
    • "我要启用 X11 Forwarding,请分配一个 DISPLAY 给我"。
  2. SSH 服务器 收到请求后:
    • 检查 sshd_config 是否允许 X11 Forwarding(X11Forwarding yes)。
    • 分配一个可用的 DISPLAY 编号(通常是 :10.0,对应端口 6010)。
    • 在用户的 shell 环境中设置 DISPLAY=localhost:10.0。

没有监听6010, 也没有DISPLAY变量

通常是xauth没安装

sudo pacman -S xorg-xauth  # Arch
sudo apt install xauth     # Debian

转发的本质:X11 协议通信

ssh完全不知道里面的内容,只是转发,只有xclient与xserver需要理解其中内容。
转发的内容是 X11 协议的数据包,主要包括:

  • 绘制指令(如画线、填充矩形、渲染文本等)。
  • 事件通知(如键盘输入、鼠标点击、窗口焦点变化)。
  • 资源管理(如图片、字体、颜色等对象的引用和操作)。
  • 不是直接转发像素: 像素数据体积庞大, 服务器可以硬件加速渲染

同一条tcp连接上的逻辑通道

SSH 协议在一条 TCP 连接上创建了多个 逻辑通道(channels),每个通道用于传输不同类型的数据。这些通道是独立的,SSH 协议通过 通道 ID 来区分它们。

  • 当你在 SSH 会话中运行命令时,命令的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)都会通过默认的通道传输。例如:
  • X11 程序的所有图形数据都会通过 X11 通道传输到 SSH 客户端。
  • 通道 ID 位于 SSH 协议数据包的 有效载荷 部分。
    • 当 SSH 协议需要传输某种类型的数据时,它会将数据封装为一个 通道数据包。
    • 通道数据包的有效载荷中会包含 通道 ID,用于标识该数据包属于哪个逻辑通道。
  • 端口转发(forwarding ports) 也是channel的另一用途

SSH 协议中连接(connection) 通过 逻辑通道(channels) 区分不同类型数据的机制,本质上就是一种 多路复用(Multiplexing) 技术

本地端口转发(Local forwarding)

ssh -D 8080 user@host 客户端ssh.exe启动时,监视本地的端口bind(:8080)+listen,收到的包将转发给host。

假定host1是本地主机,host2是远程主机。由于种种原因,这两台主机之间无法直接连通。但是,另外还有一台host3,可以同时连通前面两台主机。因此,通过host3跳板,将host1连上host2。

# host1
ssh -L 2121:host2:21 host3

L参数一共接受三个值,分别是"本地端口:目标主机:目标端口"。指定SSH绑定本地端口2121,然后指定host3将所有的数据,转发到目标主机host2的21端口(假定host2运行FTP,默认端口为21)。

# host1, 开ftp连本地的2121,被转发给host3
ftp localhost:2121

# host3 转给host2
ssh -L 5900:localhost:5900 host3

远程端口转发(Remote forwarding)

"远程端口转发"的前提条件是,host1和host3两台主机都有sshd和ssh
ssh -R 2121:host2:21 host1

R参数也是接受三个值,分别是"远程主机端口:目标主机:目标主机端口"。让host1监听它自己的2121端口,然后将所有数据经由host3,转发到host2的21端口。由于对于host3来说,host1是远程主机,所以这种情况就被称为"远程端口绑定"。

vscode的基本功能ssh到远程,打开远程文件操作,就像windows本地操作一样,应该就是远程的node进程借助ssh转发功能与本地的vscode通信来办到的

其他参数

  • -N -T N参数,表示只连接远程主机,不打开远程shell;T参数,表示不为这个连接分配TTY。一起用,代表这个SSH连接只用来传数据,不执行远程操作。
  • -f f参数,表示SSH连接成功后,转入后台运行。这样一来,你就可以在不中断SSH连接的情况下,在本地shell中执行其他操作。

HTTPS

HTTPS这个协议与SSH有异曲同工之处! HTTPS概念:HTTPS是身披SSL外壳的HTTP(超文本传输协议)。

ssh协议

用wireshark抓包,过滤条件是BPF tcp port 22,即仅关心ssh通信。

avatar

  1. 先是TCP握手
  2. 由服务器告诉客户端 ssh版本。这个是文本可读的,SSH-2.0-OpenSSH_7.4再以\r\n结尾
  3. 客户端告诉服务器自己的版本
  4. 客户端提交客户端的公钥算法。 图中的Key Exchange Init
  5. 服务器下发服务器的公钥算法。两端啰嗦一番,交代底细,支持哪些算法, 都是文本信息,人工可读的明文。

avatar

  1. 客户端上传公钥
  2. 服务器下发公钥
  3. 之后的信息就都是用对方的公钥加密过的了,因为只有对面才有钥匙才能解开,所以是安全的。

avatar

  1. 可以看到后面抓到的包都显示“Encrypted Packet”

每个“Encrypted Packet”都包括一个4字节的长度信息L与一个L字节长度的载荷,载荷的内容是对面公钥加密过的,本例的算法是 “curve25519-sha256”

那么,我把抓到的包保存下来发布到网络上有什么问题吗?不会,都是公钥和里面的加密内容,无妨。

ssh与sshd之间通信协议是什么

[pxfgod@VM-12-10-centos ~]$ ps
  PID TTY          TIME CMD
16180 pts/7    00:00:01 bash
19951 pts/7    00:00:00 ps

pts/7是 ssh会话建立之后, sshd虚拟的一个tty。sshd会分配一个tty并运行bash。

如果有两个连接,一个分配了 pts/7 一个分配了 pts/8, 在pts/7上执行sudo echo vvv > /dev/pts/8 可以看到另一个session里打印了vvv

通过ps -ef可以看到父进程, 推测ssh与sshd握手之后, sshd fork了,然后子进程启动了bash。sshd是一个 accept+fork的服务模型

[pxfgod@VM-12-10-centos ~]$ ps -ef | grep 16180
pxfgod   16180 16134  0 14:50 pts/7    00:00:01 -bash
pxfgod   21285 16180  0 15:11 pts/7    00:00:00 ps -ef
pxfgod   21286 16180  0 15:11 pts/7    00:00:00 grep --color=auto 16180
[pxfgod@VM-12-10-centos ~]$ ps -ef | grep 16134
pxfgod   16134 16122  0 14:50 ?        00:00:00 sshd: pxfgod@pts/7
pxfgod   16180 16134  0 14:50 pts/7    00:00:01 -bash
pxfgod   21415 16180  0 15:11 pts/7    00:00:00 grep --color=auto 16134
[pxfgod@VM-12-10-centos ~]$ ps -ef | grep 16122
root     16122  1091  0 14:50 ?        00:00:00 sshd: pxfgod [priv]
pxfgod   16134 16122  0 14:50 ?        00:00:00 sshd: pxfgod@pts/7
pxfgod   21535 16180  0 15:12 pts/7    00:00:00 grep --color=auto 16122

或者可以用pstree直接找到父子关系

[pxfgod@VM-12-10-centos ~]$ sudo readlink /proc/16180/exe
/usr/bin/bash
[pxfgod@VM-12-10-centos ~]$ sudo readlink /proc/16134/exe
/usr/sbin/sshd
[pxfgod@VM-12-10-centos ~]$ sudo readlink /proc/16122/exe
/usr/sbin/sshd
[pxfgod@VM-12-10-centos ~]$ sudo ls -l /proc/16180/fd
total 0
lrwx------ 1 pxfgod root 64 Jul 18 14:50 0 -> /dev/pts/7
lrwx------ 1 pxfgod root 64 Jul 18 14:50 1 -> /dev/pts/7
lrwx------ 1 pxfgod root 64 Jul 18 14:50 2 -> /dev/pts/7
lrwx------ 1 pxfgod root 64 Jul 18 15:01 255 -> /dev/pts/7

[pxfgod@VM-12-10-centos ~]$ sudo ls -l /proc/16134/fd
total 0
lrwx------ 1 root root 64 Jul 18 15:15 0 -> /dev/null
lrwx------ 1 root root 64 Jul 18 15:15 1 -> /dev/null
lrwx------ 1 root root 64 Jul 18 15:15 13 -> /dev/ptmx
lrwx------ 1 root root 64 Jul 18 15:15 14 -> /dev/ptmx
lrwx------ 1 root root 64 Jul 18 15:15 2 -> /dev/null
lrwx------ 1 root root 64 Jul 18 15:15 3 -> socket:[531037334]
lrwx------ 1 root root 64 Jul 18 15:15 4 -> socket:[531036878]
lrwx------ 1 root root 64 Jul 18 15:15 5 -> socket:[531037404]
l-wx------ 1 root root 64 Jul 18 15:15 6 -> /run/systemd/sessions/611572.ref
lr-x------ 1 root root 64 Jul 18 15:15 7 -> pipe:[531036917]
l-wx------ 1 root root 64 Jul 18 15:15 8 -> pipe:[531036917]
lrwx------ 1 root root 64 Jul 18 15:15 9 -> /dev/ptmx

[pxfgod@VM-12-10-centos ~]$ sudo ls -l /proc/16122/fd
total 0
lr-x------ 1 root root 64 Jul 18 14:50 0 -> /dev/null
lrwx------ 1 root root 64 Jul 18 14:50 1 -> /dev/null
lrwx------ 1 root root 64 Jul 18 14:50 2 -> /dev/null
lrwx------ 1 root root 64 Jul 18 14:50 3 -> socket:[531037334]
lrwx------ 1 root root 64 Jul 18 14:50 4 -> socket:[531036878]
lrwx------ 1 root root 64 Jul 18 14:50 5 -> /dev/ptmx
l-wx------ 1 root root 64 Jul 18 15:16 6 -> /run/systemd/sessions/611572.ref
lrwx------ 1 root root 64 Jul 18 15:16 7 -> socket:[531037405]

OpenSSH 研究

编译&安装 OpenSSH

sudo apt update
sudo apt install build-essential zlib1g-dev libssl-dev
sudo apt install autoconf

git clone ...

autoreconf
./configure CFLAGS="-ggdb -O0" CXXFLAGS="-ggdb -O0" LDFLAGS="-ggdb3"
make -j4
pacman -S zlib openssl  #安装依赖库

如果是archlinux,安装,然后其他一样。

./configure --prefix=/usr/             \
             --sysconfdir=/etc/ssh/        \
             --with-ssl-dir=/usr/local/ssl \
             --with-md5-passwords          \
             --mandir=/usr/share/man/

安装还需要设置sshd用户编辑服务配置文件

[/etc/group]
sshd:x:74:
     
[/etc/passwd]
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
vim /usr/lib/systemd/system/sshd.service

[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
#After=network.target sshd-keygen.service
#Wants=sshd-keygen.service
After=network.target

[Service]
#Type=notify
#EnvironmentFile=/etc/sysconfig/sshd
#ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecStart=/usr/sbin/sshd
#ExecReload=/bin/kill -HUP $MAINPID
#KillMode=process
#Restart=on-failure
#RestartSec=42s

[Install]
WantedBy=multi-user.target

systemctl enable sshd
systemctl restart sshd

https://juejin.cn/post/7062370067903676453

协议

读网络协议

#0  __GI___libc_read (fd=3, buf=0x7f03fed2f010, nbytes=262144) at ../sysdeps/unix/sysv/linux/read.c:25
#1  0x000055de85e2baf2 in sshbuf_read (fd=3, buf=0x55de8780ec80, maxlen=262144, rlen=0x7fffdd37bfa8) at sshbuf-misc.c:286
#2  0x000055de85e54b95 in ssh_packet_process_read (ssh=0x55de8780d280, fd=3) at packet.c:1795
#3  0x000055de85df3dc3 in client_process_net_input (ssh=0x55de8780d280) at clientloop.c:642
#4  0x000055de85df6810 in client_loop (ssh=0x55de8780d280, have_pty=1, escape_char_arg=126, ssh2_chan_id=0)

b read if $rdi=4 读stdin

#0  0x000055de85e383f8 in channel_handle_rfd (ssh=0x55de8780d280, c=0x55de878236b0) at channels.c:1974
#1  0x000055de85e397f0 in channel_post_open (ssh=0x55de8780d280, c=0x55de878236b0) at channels.c:2202
#2  0x000055de85e3aa4a in channel_handler (ssh=0x55de8780d280, table=1, unpause_secs=0x0) at channels.c:2442
#3  0x000055de85e3bc7c in channel_after_poll (ssh=0x55de8780d280, pfd=0x55de8781ff70, npfd=3) at channels.c:2751
#4  0x000055de85df67fd in client_loop (ssh=0x55de8780d280, have_pty=1, escape_char_arg=126, ssh2_chan_id=0)

b write if $rdi==5 回显到ssh

#0  __GI___libc_write (fd=5, buf=0x55de87823820, nbytes=92) at ../sysdeps/unix/sysv/linux/write.c:25
#1  0x000055de85e38b03 in channel_handle_wfd (ssh=0x55de8780d280, c=0x55de878236b0) at channels.c:2060
#2  0x000055de85e39803 in channel_post_open (ssh=0x55de8780d280, c=0x55de878236b0) at channels.c:2203
#3  0x000055de85e3aa4a in channel_handler (ssh=0x55de8780d280, table=1, unpause_secs=0x0) at channels.c:2442
#4  0x000055de85e3bc7c in channel_after_poll (ssh=0x55de8780d280, pfd=0x55de8781ff70, npfd=4) at channels.c:2751
#5  0x000055de85df67fd in client_loop (ssh=0x55de8780d280, have_pty=1, escape_char_arg=126, ssh2_chan_id=0)
#0  ssh_packet_read_poll2 (ssh=0x557e70edf280, typep=0x7ffc65d825cf "", seqnr_p=0x7ffc65d825d0) at packet.c:1498
#1  0x0000557e6f0e46cf in ssh_packet_read_poll_seqnr (ssh=0x557e70edf280, typep=0x7ffc65d825cf "", seqnr_p=0x7ffc65d825d0)
    at packet.c:1716
#2  0x0000557e6f0f02ea in ssh_dispatch_run (ssh=0x557e70edf280, mode=1, done=0x557e6f18a760 <quit_pending>) at dispatch.c:100
#3  0x0000557e6f0f0505 in ssh_dispatch_run_fatal (ssh=0x557e70edf280, mode=1, done=0x557e6f18a760 <quit_pending>)
    at dispatch.c:133
#4  0x0000557e6f085ca4 in client_process_buffered_input_packets (ssh=0x557e70edf280) at clientloop.c:1166
#5  0x0000557e6f08663a in client_loop (ssh=0x557e70edf280, have_pty=1, escape_char_arg=126, ssh2_chan_id=0)
    at clientloop.c:1310

核心工作原理

  • ssh,作为客户端:
    • 逻辑主要循环读取 终端T, 加密传给sshd, 读取网络包,解密写入T。
    • 写入T之后,在屏幕上显示什么是T的write的效果,与ssh无关。
    • T就是你启动ssh的终端,它可能是tty也可能xterm模拟的pts,甚至有可能是串口。
    • 如果是putty/xmobaterm之类在Windows的客户端就不读终端,而是读窗口消息
  • sshd,作为服务端:
    • accept(得到连接L)+fork(得到S)之后
    • 认证身份
    • S创建伪终端/dev/pts/n 并用dup2重定向其stdin, stdout
    • S再fork一个bash继承文件表
    • S循环直到网络断开
      • 读取L, 解密,并写入stdout(/dev/pts/n)
      • 读取stdin(/dev/pts/n),加密,并写入L(转发回ssh)
  • bash:
    • S启动bash时,已经将stdin,stdout偷换了。当然bash不关心这个也感知不到这个。
    • bash本身的逻辑就是循环读写stdin, stdout并执行读到的命令。

sshd的本质是通过加密的网络连接将客户的终端T映射成服务器的终端pts/n

sshd的主要工作:

  1. 处理网络连接:建立安全的通信通道
  2. 用户认证:
    • 支持多种认证方式,包括密码、公共密钥、双因素认证。
    • 没错,用户认证是sshd做的,不是系统功能。
    • 认证之后就能创建session了。以相应的用户来运行bash。
  3. 授权与访问控制:
    • /etc/ssh/sshd_config
  4. 分配伪终端:
    • 为每个新连接分配一个伪终端设备(/dev/pts/n)。
    • 管理与伪终端的读写过程,将网络上的数据传递给终端(与bash交互),同时将终端输出传回客户端。
  5. 命令执行:bash,其他命令是bash间接执行的

SSH 协议

SH 协议有两个主要版本:SSH-1 和 SSH-2。现代系统大多使用 SSH-2。

ssh的行为

sshd的行为

sshd 接收到来自 SSH 客户端的加密数据包之后

  1. 数据解析
    • 解码数据包:sshd 首先解密接收到的数据包,提取出实际的内容(如输入的字符)。
    • 确定数据类型:解析数据包后,sshd 会确定数据的类型,通常是一个 "data" 消息或 "channel request"。
  2. 输入处理
    • 将字符传递给 shell:如果输入是字符,sshd 会将这些字符传递给与该会话关联的 shell。
    • 这通过标准输入(stdin)实现,sshd 将字符重定向到 shell 的输入流。
  3. 执行命令
    • bash 或其他 shell 接收到字符后,会根据输入解析命令。如果输入是完整的命令,shell 会执行该命令。
    • 执行命令后,shell 会生成输出(如命令的结果或错误信息)。
  4. 输出返回
    • bash 将输出写入标准输出(stdout),sshd 会捕获这些输出,并通过加密通道将其发送回 SSH 客户端。
    • 输出格式化:如果有必要,sshd 还会进行格式化,以确保输出在客户端正确显示。
  5. 处理信号
    • sshd 会处理来自客户端的信号(如 Ctrl+C),并将这些信号转发给相应的 shell,以便用户能够中断或终止正在运行的命令。
  6. 会话管理
    • sshd 还会监控会话的状态,管理用户的会话生命周期,包括处理连接的断开、超时等情况。
pxf_god@pxf-ubuntu:~$ pstree
systemd─┬─ModemManager───2*[{ModemManager}]
        ├─agetty
        ....
        ├─snapd───13*[{snapd}]
        ├─sshd─┬─sshd───sshd───bash───pstree
        │      ├─sshd───sshd───sftp-server
        │      └─sshd───sshd───bash─┬─sh───node─┬─node─┬─bash
        │                           │           │      └─11*[{node}]
        │                           │           ├─node─┬─cpptools───13*[{cpptools}]
        │                           │           │      └─11*[{node}]
        │                           │           ├─node───12*[{node}]
        │                           │           └─10*[{node}]
        │                           └─sleep
        
        
pxf_god    15874   15829  0 14:18 ?        00:00:00 sh /home/pxf_god/.vscode-server/bin/74f6148eb9ea00507ec113ec51c489d6ffb4b771/bin/code-server --start-server --host=127.0.0.1 --accept-server-license-terms --enable-remote-auto-shutdown --port=0 --telemetry-level all --connection-token-file /home/pxf_god/.vscode-server/.74f6148eb9ea00507ec113ec51c489d6ffb4b771.token
pxf_god    15884   15874  3 14:18 ?        00:00:03 /home/pxf_god/.vscode-server/bin/74f6148eb9ea00507ec113ec51c489d6ffb4b771/node /home/pxf_god/.vscode-server/bin/74f6148eb9ea00507ec113ec51c489d6ffb4b771/out/server-main.js --start-server --host=127.0.0.1 --accept-server-license-terms --enable-remote-auto-shutdown --port=0 --telemetry-level all --connection-token-file /home/pxf_god/.vscode-server/.74f6148eb9ea00507ec113ec51c489d6ffb4b771.token

pxf_god@pxf-ubuntu:~/labs/openssh-portable$ file /home/pxf_god/.vscode-server/bin/74f6148eb9ea00507ec113ec51c489d6ffb4b771/bin/code-server
/home/pxf_god/.vscode-server/bin/74f6148eb9ea00507ec113ec51c489d6ffb4b771/bin/code-server: a /usr/bin/env sh script, ASCII text executable

ssh问题排查

  1. sshd的配置文件在 /etc/ssh/sshd_config

  2. 重启sshd服务

  • ubuntu sudo service ssh restart
  • centos sudo systemctl restart sshd
  • archlinux sudo systemctl restart sshd
  • macOS
sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist
  1. sshd的日志在
  • ubuntu sudo tail -f /var/log/auth.log
  • centos sudo tail -f /var/log/secure
  • archlinux sudo journalctl -u sshd / sudo journalctl -u sshd -f
  • macOS sudo tail -f /var/log/system.log

无法private-key免密码登录

  1. 检查客户端是否勾了 private-key
  2. 查看日志
  3. Accepted publickey for xxx from 192.168.10.3 port 59787 ssh2: RSA SHA256:xoMbWzQcoHGF0vBpRel2b1QsSGqZUNXiM5QzXBZ99N0

error: AuthorizedKeysCommand path is not absolute

posted @ 2025-07-08 11:25  切糕茶叶蛋  阅读(72)  评论(0)    收藏  举报