linux一切皆文件之tty字元設備(深入理解sshd創建pty的過程) (五)

来源:https://www.cnblogs.com/MrVolleyball/archive/2018/11/27/10024540.html
-Advertisement-
Play Games

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


一、知識準備

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

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

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

查看進程打開的描述符

[root@localhost ~]# echo $$
5598
[root@localhost ~]# 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之前的歷史信息作為一份複製)

更多的信息,請拜讀大神的書《Shell Scripting: Expert Recipes for Linux, Bash, and more》,這裡是鏈接(大概在267頁):
https://doc.lagout.org/operating%20system%20/linux/Commands%20and%20Shell%20Programming/Shell%20Scripting.pdf


五、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()一個子進程出來專門服務於這條連接

[root@localhost ~]# 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: root@pts/0

(2)子進程3126/dev/ptmx調用open(),得到PTM的文件描述符以及PTS的文件名

#這裡使用strace跟蹤sshd主進程和它創建的子進程,然後打開另外一個shell登陸伺服器
[root@localhost ~]# 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
[root@localhost ~]# 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)

[root@localhost ~]# ps -ef | grep 3126
root      3126   894  0 03:16 ?        00:00:00 sshd: root@pts/0
root      3128  3126  0 03:16 pts/3    00:00:00 -bash
[root@localhost ~]# 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


六、參考資料

http://man7.org/linux/man-pages/man7/pty.7.html
http://man7.org/linux/man-pages/man4/pts.4.html
http://osr600doc.sco.com/en/SDK_sysprog/_Pseudo-tty_Drivers_em_ptm_and_p.html
https://unix.stackexchange.com/questions/79334/how-does-a-linux-terminal-work



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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 不同應用領域的主流操作系統 l 桌面操作系統 l 伺服器操作系統 l 嵌入式操作系統 l 移動設備操作系統 桌面操作系統 Windows系列 用戶群體很大 MacOS 適合於開發人員 Linux 應用軟體比較少 伺服器操作系統 所謂的伺服器就是一臺電腦。 Linux 安全、穩定、免費 占有率高 wi ...
  • 用戶修改密碼命令--passwd 當修改用戶的密碼時,也要分普通用戶和超級用戶兩種情況 普通用戶:修改密碼前需要先輸入當前密碼,確認是否正確 密碼設置不可以過於簡單 超級用戶:權利非常的大,可以設置任何東西為密碼 常見參數 註意點:其實鎖定用戶和解鎖用戶也可以直接使用編輯方式 當使用vim /etc ...
  • 用戶管理命令--useradd 作用:用於添加一個新的用戶 選項的常用介紹 使用-c添加用戶的註釋時,如果需要添加的內容較多,並且中間使用逗號隔開。這時需要使用“ ”將註釋內容包含 註意點:使用useradd新創建的用戶是不可以登錄的,因為沒有設置密碼。當我們使用cat /etc/shadow命令時 ...
  • 歡迎大家前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~ 本文由9527發表 根功能變數名稱伺服器是功能變數名稱解析系統(DNS)中最為頂級的功能變數名稱伺服器,它們負責管理頂級域的權威功能變數名稱伺服器地址。作為互聯網基礎設施的重要部分,所有功能變數名稱的解析操作均離不開它們。下麵我們將從 DNS 協議實現的角度分析為什麼全球只有13 ...
  • 說明:(easypanel集成了kangle web 伺服器和mysql,僅支持centos 5和centos 6) 。執行下麵的命令即可,安裝程式將自動安裝或者升級: yum -y install wget;wget http://kangle.odata.cc/start;sh start 運行 ...
  • passwd 文件 位置:/etc/passwd 作用:用於保存用戶的賬戶信息 註意點:由於passwd也可以作為一個命令直接使用,也可以作為配置文件,所以如果使用man命令進行查看幫助信息時,應該有2種寫法 使用 cat /etc/passwd 命令以後,會看到這樣的畫面 我們會看到7個欄位,分別 ...
  • 鑒於Firefox安裝配置文件: 因此對於Firefox下的安裝如下: sudo cp libflashplayer.so /usr/lib64/browser-plugins/(64位Firefox) sudo cp libflashplayer.so /usr/lib/browser-plugi ...
  • 系統版本:CentOS 7.4 top uptime vmstat mpstat sar pidstat ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...