Linux 伪终端的基本原理 及其在远程登录(SSH,

本文介绍了Linux中伪终端的创建,介绍了终端的回显、行缓存、控制字符等特性,并在此基础上解释和模拟了telnet、SSH开启远程会话的过程。

轻量级远程登录

之前制作的一块嵌入式板子,安装了嵌入式Linux操作系统,可以通过串口(Console)登录。为了方便使用,需要寻找通过网线远程登录的方法。最初的想法是SSH,不过板子的ROM太小,存不了体积庞大庞大的OpenSSH套装。后来换用了telnet,直接拿busybox的telnetd做服务器,效果很好。

后来有一天,发现了Linux中有一个直接建立TCP连接的工具:nc 。在服务端使用nc -l 端口号 来进行监听,在客户端使用nc IP地址 端口号来建立连接。建立连接后,nc会把从stdin读入的字节流发送给另一方,把接收到的字节流写入stdout中。配合方便的管道操作,不正可以将shell的输入/输出传送到远端机器上吗?于是在Ubuntu中实验操作如下(之后发现这种操作叫做“反弹shell”):

打开一个终端A,输入命令

mkfifo /tmp/p # 创建临时管道 sh -i </tmp/p |& nc -l 2333 >/tmp/p

该命令将bash的标准输入输出与nc的标准输出输入连接起来,并由nc将其与socket连接起来。同时,nc监听2333端口(如果使用小于1024的端口,需要root权限),等待远程连接。现在打开另一个终端B,准备连接:

nc localhost 2333

这时,在终端B中出现了sh的提示符。输入一般的shell命令后可以执行并得到结果。看来linux自带的工具已经灵活、强大到足够搭建一个小型的远程登录系统。这个过程可以使用下面的图来描述:

Linux 伪终端的基本原理 及其在远程登录(SSH,

通过tty命令,我们看到,此时的shell并没有一个tty终端。确实,它的标准输入输出都是管道。这会带来一个问题,需要操纵tty的一些命令,比如vi、less、sudo等都无法正常使用(可以动手试试效果怎么样)。更为要命的是,在终端B中按下Ctrl+C这样的控制键,内核把结束信号发送给了客户端nc,而不是远程的程序!

Linux 伪终端的基本原理 及其在远程登录(SSH,

Ctrl+C直接杀死nc,结束了会话。对比telnet,我们的登录系统还缺少什么东西。这就是伪终端(pseudoterminal)。

了解伪终端 终端和它的作用

终端(terminal)是用户访问计算机主机的设备,可以理解为一个显示器和一个键盘的组合。Linux里面比较接近原始类型的一类终端设备是(一系列)控制台。在Ubuntu等发行版本中按下Ctrl+Alt+F1(或F2, F3, ...)即可切换到相应控制台下。程序通过访问/dev/tty1等文件可以对这些控制台读写。

除此以外,还有一种广泛使用的虚拟设备——伪终端(pseudoterminal)。每次在图形界面使用“终端”应用,“终端”应用都会建立一个伪终端设备,名字类似/dev/pts/23。终端中运行的程序,默认以此为标准输入输出。

那终端有什么用呢?简单地说,无论是使用Ctrl+C、Ctrl+Z来终止、暂停前台任务,还是login、sudo的不显示密码,都是终端的功劳。(事实上,终端和linux的进程管理密切相关。Shell的作业调度、前后台进程组都是在终端的配合下完成的)

伪终端的介绍

通过man pts可以查阅linux对伪终端的介绍。伪终端是伪终端master和伪终端slave这一对字符设备。/dev/ptmx是用于创建一对master、slave的文件。当一个进程打开它时,获得了一个master的文件描述符(file descriptor),同时在/dev/pts下创建了一个slave设备文件。

master端是更接近用户显示器、键盘的一端,slave端是在虚拟终端上运行的CLI(Command Line Interface,命令行接口)程序。Linux的伪终端驱动程序,会把“master端(如键盘)写入的数据”转发给slave端供程序输入,把“程序写入slave端的数据”转发给master端供(显示器驱动等)读取。

Linux 伪终端的基本原理 及其在远程登录(SSH,

我们打开的“终端”桌面程序,其实是一种终端模拟器。当终端模拟器运行时,它通过/dev/ptmx打开master端,创建了一个伪终端对,并让shell运行在slave端。当用户在终端模拟器中按下键盘按键时,它产生字节流并写入master中,shell便可从slave中读取输入;shell和它的子程序,将输出内容写入slave中,由终端模拟器负责将字符打印到窗口中。

(终端模拟器的显示原理就不在这里展开了,这里认为键盘按键形成一列字节流、向显示器输出字节流后便打印到屏幕上)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13436.html