加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么后台ssh可以接管来自Bash的tty?

发布时间:2020-12-16 01:56:46 所属栏目:安全 来源:网络整理
导读:(我在Debian 8上使用 Bash 4.4.12.问题也在 bash mailing list中提出.) 请参阅以下步骤以重现该问题. 从tty#1(pts / 2): [STEP 101] # tty/dev/pts/2[STEP 102] # ssh -o ControlMaster=yes -o ControlPath=/tmp/socket.ssh -N -f 127.0.0.1[STEP 103] # ps
(我在Debian 8上使用 Bash 4.4.12.问题也在 bash mailing list中提出.)

请参阅以下步骤以重现该问题.

从tty#1(pts / 2):

[STEP 101] # tty
/dev/pts/2
[STEP 102] # ssh -o ControlMaster=yes -o ControlPath=/tmp/socket.ssh -N -f 127.0.0.1
[STEP 103] # ps -C ssh u
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root       1390  0.0  0.0  36440   656 ?        Ss   11:33   0:00 ssh -o ControlMaster=yes -o ControlPath=/tmp/so
[STEP 104] #
[STEP 105] # ssh -o ControlMaster=no -o ControlPath=/tmp/socket.ssh 
             127.0.0.1 sleep 3600 &
[1] 1396
[STEP 106] #    <-- Here I cannot input anything except <CTRL-C>

步骤102启动作为守护程序运行的多路SSH连接.步骤105尝试使用多路复用连接来运行睡眠命令.但后来我无法在当前shell中输入任何内容.如果我杀了ssh …… sleep&过程然后Bash将能够再次接受我的输入.似乎所有输入都被ssh进程使用.

转到tty#2(pts / 3):

[STEP 201] # tty
/dev/pts/3
[STEP 202] # ps t pts/2 j
  PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
   723   1353   1353   1353 pts/2      1353 Ss+      0   0:00 bash
  1353   1396   1396   1353 pts/2      1353 S        0   0:00 ssh -o ControlMaster=no -o ControlPath=/tmp/socket.ssh 127.0.0.1 sleep 3600
[STEP 203] # ps s 1396
  UID    PID  PENDING  BLOCKED  IGNORED    CAUGHT STAT TTY    TIME COMMAND
    0   1396 00000000 00000000 00001000 188004003 S    pts/2  0:00 ssh -o ControlMaster=no -o ControlPath=/tmp/socket.ssh 127.0.0.1 sleep 3600
[STEP 204] #

我解码了sig mask:

PENDING (00000000):
BLOCKED (00000000):
IGNORED (00001000):
  13 PIPE
CAUGHT (188004003):
   1 HUP
   2 INT
  15 TERM
  28 WINCH
  32
  33

在这里我们可以看到ssh进程没有捕获SIGTTIN信号.这让我感到困惑,因为后台作业(进程组)应该接收SIGTTIN并在尝试从tty读取时停止.

解决方法

我想我已经弄清楚发生了什么.让我解释一下.

从tty#1(pts / 2):

[STEP 300] # tty
/dev/pts/2
[STEP 301] # ssh -o ControlMaster=yes -o ControlPath=/tmp/socket.ssh -N -f 127.0.0.1 < /dev/null >& /dev/null
[STEP 302] # ps -C ssh j
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    1  4052  4052  4052 ?           -1 Ss       0   0:00 ssh -o ControlMaster=yes -o ControlPath=/tmp/socket.ssh -N -f 127.0.0.1
[STEP 303] # ls -l /proc/4052/fd/
total 0
lr-x------ 1 root root 64 2017-06-12 22:59 0 -> /dev/null
l-wx------ 1 root root 64 2017-06-12 22:59 1 -> /dev/null
l-wx------ 1 root root 64 2017-06-12 22:59 2 -> /dev/null
lrwx------ 1 root root 64 2017-06-12 22:59 3 -> socket:[370151]
lrwx------ 1 root root 64 2017-06-12 22:59 4 -> socket:[370201]
[STEP 304] # ssh -o ControlMaster=no -o ControlPath=/tmp/socket.ssh 127.0.0.1 sleep 3600 &
[1] 4062
[STEP 305] #    <-- Cannot input anything

去吧#2(pts / 3):

[STEP 401] # tty
/dev/pts/3
[STEP 402] # ps t pts/2 j
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
  579  3552  3552  3552 pts/2     3552 Ss+      0   0:00 bash
 3552  4062  4062  3552 pts/2     3552 S        0   0:00 ssh -o ControlMaster=no -o ControlPath=/tmp/socket.ssh 127.0.0.1 sleep 3600
[STEP 403] # ls -l /proc/4062/fd/    # The `ssh ... sleep' process
total 0
lrwx------ 1 root root 64 2017-06-12 23:00 0 -> /dev/pts/2
lrwx------ 1 root root 64 2017-06-12 23:00 1 -> /dev/pts/2
lrwx------ 1 root root 64 2017-06-12 23:00 2 -> /dev/pts/2
lrwx------ 1 root root 64 2017-06-12 23:00 3 -> socket:[370349]
[STEP 404] # ls -l /proc/4052/fd/    # The `ssh -o ControlMaster=yes' process
total 0
lr-x------ 1 root root 64 2017-06-12 22:59 0 -> /dev/null
l-wx------ 1 root root 64 2017-06-12 22:59 1 -> /dev/null
l-wx------ 1 root root 64 2017-06-12 22:59 2 -> /dev/null
lrwx------ 1 root root 64 2017-06-12 22:59 3 -> socket:[370151]
lrwx------ 1 root root 64 2017-06-12 22:59 4 -> socket:[370201]
lrwx------ 1 root root 64 2017-06-12 23:02 5 -> socket:[370350]
lrwx------ 1 root root 64 2017-06-12 23:02 6 -> /dev/pts/2
lrwx------ 1 root root 64 2017-06-12 23:02 7 -> /dev/pts/2
lrwx------ 1 root root 64 2017-06-12 23:02 8 -> /dev/pts/2
[STEP 405] #

步骤403的输出显示ssh … sleep进程’stdin / stdout / stderr在pts / 2上打开.这个是正常的.

但是STEP 404的输出(与步骤303相比)显示ssh -o ControlMaster = yes进程也打开pts / 2.我相信这是多路复用SSH的工作方式 – 新的ssh … sleep进程通过UNIX域套接字将其打开的文件描述符传递给ssh -o ControlMaster = yes进程(-o ControlPath = / tmp / socket.ssh).所以它实际上是ssh -o ControlMaster = yes进程正在消耗来自pts / 2的所有输入.并且由于ssh -o ControlMaster = yes进程与bash进程(和ssh … sleep)不在同一个进程会话中,因此即使它在后台运行(作为守护进程),作业控制机制也不适用于它从pts / 2读取.

换句话说:SIGTTIN仅发送到作为后台作业运行的进程,并尝试从其控制终端读取.这里ssh -o ControlMaster = yes进程在后台运行,但它不是bash进程会话的工作,它根本没有控制终端.

更多关于通过UNIX域套接字(从Wikipedia)在进程之间传递FD:

In addition to sending data,processes may send file descriptors across a Unix domain socket connection using the sendmsg() and recvmsg() system calls. This allows the sending processes to grant the receiving process access to a file descriptor for which the receiving process otherwise does not have access.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读