1. 程式人生 > >linux一切皆檔案之tty字元裝置(深入理解sshd建立pty的過程) (五)

linux一切皆檔案之tty字元裝置(深入理解sshd建立pty的過程) (五)

一、知識準備

1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列)
2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等
3、塊裝置支援隨機訪問,而字元裝置只能依據先後順序來讀取資料。最典型的字元裝置就是tty

二、環境準備

元件 版本
OS CentOS Linux release 7.5.1804

三、什麼是tty?

根據史料記載:

An ASR33 Teletype - origin of the abbreviation tty.

tty來源一種電傳印表機(teletype),就像這樣:

● 敲擊鍵盤輸入不同的字元,然後由印表機將字元列印在紙上
● 歷史不斷在往前發展,出現了計算機之後,計算機模擬了teletype的模式:通過外部終端輸入,將輸入的字元列印在螢幕上
● 在teletype與計算機之間用串列埠相連,並且在計算機上通過訊號轉換(模擬訊號轉換為數字訊號),讓計算機能夠識別,從而操作計算機
● 由於計算機廠商眾多,每個廠商都有自己風格的輸入裝置,所以計算機為了相容這些裝置,開發了核心tty模組

                            
                           +-----------------+
                           |                 |
+--------+                 | +-------------+ |
|teletype|-----------------> |serial       | |
+--------+                 | |communication| |
                           | +-----+-------+ |
                           |       |         |
                           |       v         |
                           |  +----------+   |        +----------+
                           |  |tty driver|   |------->| display  |
                           |  +----------+   |        +----------+
                           |                 |
                           |computer         |
                           +-----------------+


四、tty裝置檔案

登陸到作業系統(不使用SSH協議,而使用控制檯直接登陸),首先檢視當前程序號所使用的tty

[[email protected] ~]# tty
/dev/tty1
[[email protected] ~]# ls -l /dev/tty1
crw--w---- 1 root tty 4, 1 Nov 20 23:24 /dev/tty1

當前所使用的是/dev/tty1,並且tty1也分配了主裝置號與次裝置號(關於主裝置號與次裝置號,請看之前的文章:塊裝置檔案)

檢視程序開啟的描述符

[[email protected] ~]# echo $$
5598
[
[email protected]
~]# ls -l /proc/5598/fd total 0 lrwx------ 1 root root 64 Nov 19 22:23 0 -> /dev/tty1 lrwx------ 1 root root 64 Nov 19 22:23 1 -> /dev/tty1 lrwx------ 1 root root 64 Nov 19 22:23 2 -> /dev/tty1 lrwx------ 1 root root 64 Nov 19 22:23 255 -> /dev/tty1

程序打開了4個檔案描述符,這四個檔案描述符都是/dev/tty1,他們的作用分別是:
0:標準輸入
1:標準輸出
2:標準錯誤
255:這個比較特殊,主要用於當tty重置的時候對0,1,2的一份複製(個人觀點是對tty之前的歷史資訊作為一份複製)

五、ssh登陸之後的tty

剛才介紹的都是作業系統提供的控制檯登陸之後的情況,如果用ssh服務登陸之後會產生什麼情況呢?

首先介紹一個非常重要的概念,偽終端pty:
● pty是一對虛擬的字元裝置,提供雙向通訊。pty一般由master與slave組成
● pty的出現是為了滿足現在的登陸需求:網路登陸(ssh登陸、telnet登陸等)、Xwindow等
● 歷史上有兩套介面標準:分別是BSD與unix98,當前大多數pts都是基於unix98標準來實現的
● unix98的工作流程:
(1)程序對/dev/ptmx呼叫open(),返回pseudoterminal master(PTM)的檔案描述符,並且在/dev/pts下建立pseudoterminal slave(PTS): /dev/pts/0
(2)呼叫grantpt()修改PTS的檔案許可權;呼叫unlockpt()對PTS解鎖;最後呼叫slavename()得到PTS檔名字
(3)此時,PTM與PTS都已經正常開啟,並且建立一條通道,兩端分別連線PTM與PTS
(4)程序對PTM寫的資料可以從PTS讀出來,反之亦然

下面重點介紹一下基於unix98實現的sshd pty(主要分為登陸階段和執行命令階段):

登陸:

(1)當程序ssh client請求與sshd建立登陸連線的時候,經過TCP握手以及tls握手之後,確認是一個合法的請求,sshd會fork()一個子程序出來專門服務於這條連線

[[email protected] ~]# ps -ef | grep sshd
root       894     1  0 Nov25 ?        00:00:00 /usr/sbin/sshd -D
root      3126   894  0 Nov25 ?        00:00:00 sshd: [email protected]/0

(2)子程序3126/dev/ptmx呼叫open(),得到PTM的檔案描述符以及PTS的檔名

#這裡使用strace跟蹤sshd主程序和它建立的子程序,然後開啟另外一個shell登陸伺服器
[[email protected] ~]# strace -p 894 -ff -o sshd
strace: Process 894 attached
strace: Process 3126 attached
strace: Process 3127 attached
strace: Process 3128 attached
strace: Process 3129 attached
strace: Process 3130 attached
strace: Process 3131 attached
strace: Process 3132 attached
strace: Process 3133 attached
strace: Process 3134 attached
strace: Process 3135 attached
strace: Process 3136 attached
strace: Process 3137 attached
strace: Process 3138 attached
strace: Process 3139 attached
strace: Process 3140 attached
[[email protected] ~]# grep ptmx ./sshd.*
./sshd.3126:open("/dev/ptmx", O_RDWR)               = 8

sshd894建立了一個子程序3126用來處理這條TCP連線。程序對/dev/ptmx呼叫open(),得到PTM的檔案描述符8

(2)子程序3126/dev/pts下建立了一個字元裝置檔案/dev/pts/08/dev/pts/0成為一對master/slave
(3)子程序3126會再fork()一個子程序3128,子程序3128開啟/dev/pts/0 3個描述符(標準輸入,標準輸出,標準錯誤),並且執行作業系統預設的shell(本文中bash)

[[email protected] ~]# ps -ef | grep 3126
root      3126   894  0 03:16 ?        00:00:00 sshd: [email protected]/0
root      3128  3126  0 03:16 pts/3    00:00:00 -bash
[[email protected] ~]# ls -l /proc/3128/fd
total 0
lrwx------ 1 root root 64 Nov 26 03:16 0 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:16 1 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:16 2 -> /dev/pts/0
lrwx------ 1 root root 64 Nov 26 03:22 255 -> /dev/pts/0

至此,通訊流程大概是這樣:

                         +----------------+
+------------+           |                |
| ssh client +---------->|      sshd      |
+----+-------+           |                |
     |                   +--------+-------+
     |                            |
     |                            |
     |                         fork()
     |                            |
     |                            |
     |                            v
     |                       +----+-----+     fork()    +----------+      +-----+
     +---------------------->|pid: 3126 |-------------->|pid: 3128 |----->|bash |
                             +-+--------+               +----------+      +-----+
                               |                              ^
                               |                              |
                       +-------+                              |
                +------|--------------------------------+     |
                |      |                 +-----------+  |     |
                |      v                 |           |  |     |
                |  +---------+    fd=8   +-----------+  |     |
                |  |/dev/ptmx|---------->|/dev/pts/0 |--------+
                |  +---------+           +-----------+  |
                |                        |           |  |
                |                        +-----------+  |
                +---------------------------------------+

執行命令:

(4)當ssh client發出一個ls命令,通過TCP連線來到31263126ls寫入PTM檔案描述符8
(5)/dev/ptmx查詢到關聯記錄 PTM:8對應PTS:/dev/pts/0,把ls轉發到/dev/pts/0當中
(6)31280 -> /dev/pts/0中讀取之後執行ls
(7)ls返回結果之後寫入1 -> /dev/pts/0,然後根據關聯記錄回寫到/dev/ptmx
(8)3126/dev/ptmx讀取之後返回到ssh client

六、參考資料

至此,本文結束
在下才疏學淺,有撒湯漏水的,請各位不吝賜教...

相關推薦

linux一切檔案tty字元裝置(深入理解sshd建立pty過程)

一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 3、塊裝置支援隨機訪問,而字元裝置只能依據先後順序來讀取資料。最典型的字元裝置就是tty 二、環境準備 元

linux一切檔案Unix domain socket描述符

一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 3、主要用於:執行在同一臺機器上的2個程序相互之間的資料通訊 4、它們和網路檔案描述符非常相似(比如:TCP

linux一切檔案tcp socket描述符

一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 二、環境準備 元件 版本

linux一切檔案Unix domain socket描述符

一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案(比如:塊裝置,socket套接字,pipe佇列) 2、操作這些不同的型別就像操作檔案一樣,比如增刪改查等 二、環境準備 元件 版本 OS CentOS Linux release 7.5.1804

linux一切檔案檔案描述符

一、知識準備 1、在linux中,一切皆為檔案,所有不同種類的型別都被抽象成檔案。如:普通檔案、目錄、字元裝置、塊裝置、套接字等 2、當一個檔案被程序開啟,就會建立一個檔案描述符。這時候,檔案的路徑就成為了定址系統,檔案描述符成為了位元組流的介面 3、相對於普通檔案這類真實存在於檔案系統中的檔案,tcp

Linux學習02--Linux一切檔案

Linux學習第二部 Linux一切皆物件 啊啊啊啊啊,今天被學妹說太直了,嚶嚶嚶。   學習linux兩三天了,前期感覺並不難,只是命令多,多記記多敲一敲就能都記住了。希望自己能夠堅持下去吧! 下面是根據第二次學的做的一些筆記。 一、 系統狀態檢測命令   1-

Linux 一切檔案思想

“一切皆檔案” 在linux開發過程中,相信大家都聽過一句話叫作“limux下,一切皆檔案”。這句話是linux/unix的哲學核心思想,下面我們就針對這句話給大家進行展開解釋下。 這句話中的“檔案”不僅僅是我們通常所指的檔案,在linux和unix中它

【JAVA秒會技術秒殺面試官】JavaEE常見面試題

內存溢出 不可重復讀 cad struts2的 pro 單線程 映射 指定 log 51.事務的特性? 答:①原子性(Atomicity) 指事務是一個不可分割的工作單位,事務中的操作要麽全都發生,要麽全不發生; ②一致性(Consistency) 事務前後數據的完成性必須

安卓專案實戰強大的網路請求框架okGo使用詳解:擴充套件專案okRx,完美結合RxJava

前言 在第一篇講解okGo框架新增依賴支援時,還記得我們額外新增的兩個依賴嗎,一個okRx和一個okServer,這兩個均是基於okGo框架的擴充套件專案,其中okRx可以使請求結合RxJava一起使用,而okServer則提供了強大的下載上傳功能,如斷點支援,多工管理等,本篇我們主要講

深入理解JVM虛擬機器:檔案結構

前言 在上一篇深入理解JVM虛擬機器:(二)垃圾收集器概述 文章中,我們瞭解了Java虛擬機器中垃圾收集器的種類以及垃圾回收的方式等,這一篇,我們將去了解一下Java中類檔案的內部構造,由於這一章比較抽象,因此將會分為兩篇文章進行講解。 概述 程式碼編譯的

OpenStackNova分析——建立虛擬機器

上篇兩篇文章分析了Nova Scheduler服務,這篇文章我們繼續來分析建立虛擬機器的過程。先來回顧一下。 class FilterScheduler(driver.Scheduler): def scheduler_run_instance(self, cont

深入理解Java虛擬機器》-實戰練習修改class檔案

這是一篇修改class檔案的文章。註釋並不完全,要抓住這次練習的目的: boolean在虛擬機器中是以何種方式解讀的 好的,開始我的表演 1.安裝asmtools.jar(本文尾部有步驟) 2.編寫一個java檔案,並編譯,執行  2.1 Foo.java 1 public

Linux系統下一切檔案,socket程式設計淺析

“一切皆Socket!” 話雖些許誇張,但是事實也是,現在的網路程式設計幾乎都是用的socket。 ——有感於實際程式設計和開源專案研究。 我們深諳資訊交流的價值,那網路中程序之間如何通訊,如我們每天開啟瀏覽器瀏覽網頁時,瀏

Linux中“一切檔案

“一切皆檔案” 在linux開發過程中,相信大家都聽過一句話叫作“limux下,一切皆檔案”。這句話是linux/unix的哲學核心思想,下面我們就針對這句話給大家進行展開解釋下。 這句話中的“檔案”

Linux裝置驅動字元裝置驅動》

    Linux裝置中最大的特點就是裝置操作猶如檔案操作一般,在應用層看來,硬體裝置只是一個裝置檔案。應用程式可以像操作檔案一樣對硬體裝置進行操作,如open(),close(),read(),write()等。     下面是一個字元裝置驅動程式的簡單實現test.c  

linux一切文件

系統運維;雲計算;Linux;一切皆文件 FHS 標準目錄結構樹形結構/bin 二進制文件 存放普通用戶可以使用的命令/sbin 只有root用戶可以使用的命令/root root用戶的家目錄 /home 普通用戶的家目錄的父目錄/dev device 存放設備文件的目錄

linux統計一個檔案中特定字元的個數

統計一個檔案中某個字串的個數,其實就是在在一塊沙地裡面找石頭,有的人看到石頭以後,在上面做個標記(grep),然後記住自己做了多少個標記;有的人看到石頭以後,把它挖了(tr),最後統計自己挖了多少石頭;有的人看到石頭以後,把它跳過去(awk),然後統計自己跳了多少次。這是我用的的檔案 [[

Linux學習02--Linux一切文件

ces pass top 編輯 ear sbin ali gil 轉換 Linux學習第二部 Linux一切皆對象 啊啊啊啊啊,今天被學妹說太直了,嚶嚶嚶。 學習linux兩三天了,前期感覺並不難,只是命令多,多記記多敲一敲就能都記住了。希望自己能夠堅持下去吧! 下

lsof 命令——一切檔案

lsof(list open files)是一個檢視當前系統檔案的工具。在linux環境下,任何事物都以檔案的形式存在,通過檔案不僅僅可以訪問常規資料,還可以訪問網路連線和硬體。如傳輸控制協議 (TCP) 和使用者資料報協議 (UDP) 套接字等,系統在後臺都為該應用程式分配

Linux Kernel 學習筆記5:字元裝置

(本章基於:linux-4.4.0-37) 本章介紹如何註冊一個字元裝置,並通過裝置節點對這個字元裝置進行open、close、read、write等操作。 一、字元設備註冊 相關標頭檔案:linux/cdev.h 1、初始化 void cdev_init(struct