日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

X-Window结构分析与应用

發布時間:2023/12/15 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 X-Window结构分析与应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

X-Window結構分析與應用

  • X-Window結構分析與應用
    • 簡介
    • 結構
    • 組件
      • X-Client
      • X-Server
        • Linux下的X-Server
        • MacOS Windows
      • X-Window-Manager
      • X-Security
        • 基于IP驗證
        • 基于預共享密鑰驗證
    • 協議
        • NAT-sensitiveNAT敏感
        • 結合SSH隧道運行遠端GUI應用
    • 應用案例
      • 本地MAC端運行遠端GUI應用
      • 本地Ubuntu端運行遠端GUI應用
      • 本地Windows端運行遠端GUI應用

簡介

*nix系統的圖形交互使用的是x-window系統. 基于C/S架構,即可完全運行在本地,也可以讓本端運行的GUI應用在遠端上進行交互(在遠端上顯示GUI 和 接收遠端上的鍵盤鼠標輸入).

結構

組件

X-Client

  • X-Client就是GUI應用程序(如:xclock,xterm,firefox,…)
  • Linux下GUI應用程序大多是通過庫Xlib(libX11)與X-Server通信
  • X-Client自身不直接輸出圖形到屏幕或直接讀取鍵盤輸入,這些與外設的通信都由X-Server來處理

GUI應用程序通過加載Xlib,連接到X-Server建立通信通道,最終通過這通道將顯示需求發送到X-Server上 或 從這通道上接收用戶的鍵盤鼠標輸入, 從而實現GUI交互

每個終端可以配置使用指定的X-Server, 由終端當前的環境變量’DISPLAY’指定.DISPLAY字符串的格式如下:

[host]:[displayer-id].[screen-id]

意思為: 哪個主機上的哪個顯示器上的哪個屏幕

其中[host]和[screen-id]可省略.host省略意為本機,screen-id省略為默認的屏幕.如:

# 本終端環境使用本地ID為0的顯示器的默認屏幕作為X-Server export DISPLAY=:0 # 使用主機(10.0.66.238)上ID為1的顯示器的ID為0的屏幕 export DISPLAY=10.0.66.238:1.0

X-Server

  • 顧名思義是X-Client們的服務端
  • 負責與輸入輸出設備通信
  • Linux上通常使用的實現為 Xorg
  • MacOS上可使用 XQuartz
  • Windows上可使用 Xmanager 或 Xming

負責將X-Client請求顯示的圖形顯示到屏幕上 和 將鍵盤鼠標的輸入事件發送到相應的X-Client上.

Linux下的X-Server

  • 已安裝桌面環境
  • 以ubuntu17為例,若安裝了桌面環境,即GNOME,則已經完全具備X-Server的服務能力(基于Xorg-server). 這完整的桌面環境不止X-Server,還包括一系列的X-Client應用程序(任務欄,文件夾管理器…)和X-Window-Manager等等.

    但默認的情況下,該X-Server只提供給本地的X-Client使用,沒開啟TCP的對外服務渠道,只開啟了基于unix-socket的進程間通信的服務渠道.

    開啟TCP方式則需要修改配置文件:/etc/gdm3/custom.conf

    [security] DisallowTCP=false

    開放給遠端使用時可能會遇到X-Auth驗證失敗 或 NAT環境下不可用的情況,在后面的小節進行說明

    下圖為GNOME桌面環境下, 終端默認使用了當前GNOME桌面所在的X-Server(Displayer1), 當執行X-Client(GUI應用xclock)時就把他顯示在當前GNOME桌面里了

    當然也可以手動再開啟一個純凈的X-Server,如接下來這小節所示

  • 未安裝桌面環境,使用最純凈的X-Server(Xorg)
  • 先確認已安裝X-Server:

    rock@ubuntu17:~$ sudo apt-get xorg

    手動開啟一個新的X-Server(Xorg為例):

    ## ':1'表示該X-Server標識為ID為2的Displayer ## Displayer1顯示在tty5 ## '-listen tcp'顯式表示要使用tcp方式 ## '-retro'表示背景為斜紋,不然默認為純黑,不好判斷啟動成功與否 rock@ubuntu17:~$ sudo X :2 vt5 -listen tcp -retro

    此時tty5終端已經成功啟動了X-Server了,顯示如下斜紋背景:

    ctrl+alt+F3 切換到其他未使用的終端:

    rock@ubuntu17:~$ sudo lsof -nPi tcp|grep X Xorg 3505 root 5u IPv6 37157 0t0 TCP *:6002 (LISTEN) Xorg 3505 root 6u IPv4 37158 0t0 TCP *:6002 (LISTEN)

    啟動后可以發現tcp6002端口已啟動監聽. 其實X-Server的端口號是從6000開始一一對應Displayer-ID,如:tcp6002對應Displayer2,tcp6010對應Displayer10.

    在剛啟動的Displayer2上運行xclock:

    rock@ubuntu17:~$ export DISPLAY=:2 rock@ubuntu17:~$ xclock& [1] 4103 rock@ubuntu17:~$

    ctrl+alt+F5 :

    MacOS & Windows

    其他操作系統,MacOS上運行XQuartz,Windows上運行Xmanager 即可看到相應的TCP端口開啟了監聽,即已經開啟了X-Server服務

    • XQuartz

    • Xmanager

    X-Window-Manager

    單一的X-Server是沒有窗口管理功能的,即多個X-Client窗口會重疊在一塊,無法移動任何一個窗口. X-Window-Manager就是為多窗口管理而生的

    • X-Server(xorg) without X-Window-Manager
    ## 接著使用上一節'純凈X-Server'的環境 rock@ubuntu17:~$ sudo X :2 vt5 -listen tcp -retro ## tty2: rock@ubuntu17:~$ export DISPLAY=:2 ## 運行GUI應用程序 rock@ubuntu17:~$ xterm& rock@ubuntu17:~$ xeyes&

    此時tty5的桌面顯示為下圖所示的倆重疊應用程序窗口, 鼠標無法拖動:

    tty5:

    • Xorg-server(xorg) with X-Window_Manager(twm)
    ## 接著使用上面的環境 rock@ubuntu17:~$ sudo X :2 vt5 -listen tcp -retro ## tty2: rock@ubuntu17:~$ export DISPLAY=:2 ## 運行GUI應用程序 rock@ubuntu17:~$ xterm& rock@ubuntu17:~$ xeyes& ## 啟動twm窗口管理器 rock@ubuntu17:~$ twm&

    此時tty5桌面上的倆應用程序窗口已經可以用鼠標自由拖放了:

    • 所以現在應該理解了ubuntu上GNOME桌面提供的其中一個服務就是X-Window-Manager了:

    • MacOS下XQuartz自身集成了X-Window-Manager
    • Windows下XManager自身也集成了X-Window-Manager

    X-Security

    X-Window系統的’訪問控制(access control)’功能由X-Security來定義,X-Server端可配置基于IP級別的驗證和基于共享key的驗證.

    確認當前X-Server的’訪問控制’功能已開啟

    xhost配置的是當前終端環境變量DISPLAY所指向的X-Server.所以配置前先確認當前環境變量中的DISPLAY值

    rock@rock-ubuntu17:~$ echo $DISPLAY :1 ## 顯示當前訪問控制的狀態,和xhost允許的X-Client的主機來源或用戶 rock@rock-ubuntu17:~$ xhost access control enabled, only authorized clients can connect SI:localuser:rock

    該輸出表示訪問控制功能已開啟,只允許通過IP驗證 或 通過共享密鑰驗證的才能訪問X-Server服務

    ## 關閉訪問控制. 不驗證xhost和xauth rock@rock-ubuntu17:~$ xhost + access control disabled, clients can connect from any host ## 開啟訪問控制. 驗證xhost和xauth rock@rock-ubuntu17:~$ xhost - access control enabled, only authorized clients can connect

    基于IP驗證

    • 一個Displayer(X-Server)對應一個xhost列表
    • 只需在X-Server端配置
    • X-Client請求接入時, X-Server驗證X-Client的IP是否在放行列表中,不在則拒絕接入
    • 使用xhost維護
    ## 指定配置Displayer1 rock@rock-ubuntu17:~$ export DISPLAY=:1 ## 允許10.211.55.2上的X-Client接入Displayer1 rock@rock-ubuntu17:~$ xhost + 10.211.55.2 10.211.55.2 being added to access control list ## 顯示Displayer1上的IP放行列表 rock@rock-ubuntu17:~$ xhost access control enabled, only authorized clients can connect INET:10.211.55.2 SI:localuser:rock

    以上設置重啟失效,永久設置需要寫入到對應的配置文件:/etc/X[n].hosts. n為X-Server顯示器ID.即:

    /etc/X0.hosts: 配置Displayer0的放行列表

    /etc/X1.hosts: 配置Displayer1的放行列表

    基于預共享密鑰驗證

    • 一個X-Server關聯一個Xauthority文件, 一個Xauthority文件可包含多個Displayer的預共享密鑰. X-Server只使用他所關聯的Xauthority文件里自身Displayer的密鑰記錄
    • 需要在X-Server端和X-Client端配置一致的密鑰
    • X-Client接入時帶上目標Displayer的密鑰,X-Server驗證該密鑰是否與本地Xauthority文件里配置的一致,不一致則拒絕
    • 使用xauth維護

    xauth默認配置的是環境變量XAUTHORITY所指向的Xauthority文件或用戶家目錄的.Xauthority(當環境變量’XAUTHORITY’不存在時); 可以用-f參數顯式指定

    在X-Server端為Displayer2生成密鑰

    rock@rock-ubuntu17:~$ xauth Using authority file /run/user/1000/gdm/Xauthority ## 生成DISPLAY=:2顯示器的共享key, '.'表示使用機制'MIT-MAGIC-COOKIE-1'明文共享密鑰 xauth> generate :2 . authorization id is 572 ## 查看當前顯示器共享key列表 xauth> list rock-ubuntu17/unix:1 MIT-MAGIC-COOKIE-1 5d8f557af058440ef69d6aaa665c91fb rock-ubuntu17/unix:2 MIT-MAGIC-COOKIE-1 578f3bb50f08cd4831277cc4397a2611 xauth> exit Writing authority file /run/user/1000/gdm/Xauthority

    在X-Client端配置對端Displayer2的密鑰

    ## 添加目標Displayer的訪問密鑰 root@dld:~# xauth add 10.211.55.5:2 . 578f3bb50f08cd4831277cc4397a2611 ## 配置當前終端使用上步驟的遠端Displayer2 root@dld:~# export DISPLAY=10.211.55.5:2 root@dld:~# xclock

    如果要編輯指定的Xauthority文件,則:

    rock@rock-ubuntu17:~$ xauth -f /root/.Xauthority

    X-Server執行時可使用’-auth [auth-file]’選項指定使用的Xauthority文件

    rock@rock-ubuntu17:~$ sudo X :1 vt5 -auth /run/user/121/gdm/Xauthority

    協議

    NAT-sensitive(NAT敏感)

    NAT敏感 通常是因為協議的應用報文中帶有對端的IP信息, 對端在處理應用邏輯里需要依賴這IP信息. 然而對端在NAT環境后面(即做了DNAT, 外網IP映射為內網IP), 本端是不知道你是做了DNAT的, 所以帶的對端的IP是對端的外網IP, 這時對端解釋到的IP信息是外網IP, 但他應用邏輯是用內網IP的, 因此導致應用邏輯上的混亂

    X-Server與X-Client之間的遠程通信使用TCP方式, 在實際測試中發現X-Server和X-Client在同一個局域網內才能連接成功, X-Client連接NAT后的X-Server的話是不能成功的. 看來這協議是’NAT敏感’的. 解決方法通常是使用SSH隧道

    還有一個內容本文章沒提及, 那就是XDM(X-Display-Manager), 他使用的是XDMCP協議, 走UDP177端口. 以后有機會再補充這塊內容

    結合SSH隧道運行遠端GUI應用

    為解決剛說的’NAT敏感’問題. 我們常常使用SSH隧道上的端口轉發功能來繞過問題, 其原理圖如下:

    遠端上的X-Client應用程序訪問其本地SSH-Server開啟的轉發監聽端口PORT1, SSH-Server將其在Port1在監聽接入的數據通過已經建立好連接的SSH隧道轉發到我們本地的SSH-Client, SSH-Client再將數據轉發到本地X-Server所監聽的TCP端口PORT2

    以PORT1為6010, PORT2為6002為例, 其SSH隧道建立及開啟轉發功能的連接命令為:

    ssh -R 127.0.0.1:6010:127.0.0.1:6002 user@remotehost

    ssh有個簡潔的-X參數能自動根據環境配置以上轉發參數及遠端SSH終端的DISPLAY環境變量. 可以自行翻閱文檔查看詳情, 這功能需要在SSH-Server開啟’X11 Forwarding’選項

    這樣一來就避開了’NAT敏感’的問題, 從X-Client看來他只是訪問本地的X-Server, 從X-Server看來他只是接入本地的X-Client, 所有X層面上看到的IP都是127.0.0.1

    同時這個做法避開了X-Security的f遠程主機驗證,因為都認為是本地主機的訪問,只需允許本地訪問即可

    應用案例

    本地MAC端運行遠端GUI應用

    下面演示使用XQuartz結合SSH的’Forwarding’運行遠端GUI

  • 先在本地運行XQuartz:

    • 配置允許網絡客戶端接入(開啟使用TCP方式):

    • 關閉XQuartz, 重新打開XQuartz. 此時已發現tcp6000端口已經在監聽:

    • 允許本地主機訪問XQuartz. XQuartz默認沒允許本機IP訪問

      xhost + 127.0.0.1

  • 用ssh的’-R’選項在SSH會話上開啟隧道端口轉發功能:

    意思為將本地XQuartz的X-Server端口tcp6000映射到遠端本地上的tcp6010

    root@test:~# ssh -R 127.0.0.1:6010:127.0.0.1:6000 user@remotehost

  • 配置遠程終端的DISPLAY環境變量

    root@test:~# export DISPLAY=:10

    如步驟2截圖

  • 執行GUI

    root@test:~# xterm& root@test:~# xeyes

    如步驟2截圖

    ?

  • 使用X11-Forwarding(即’ssh -X user@host’)操作會比較簡單, 其實他自動做的事的步驟就是以上說的

    本地Ubuntu端運行遠端GUI應用

    下面演示使用Xorg結合SSH的’Forwarding’運行遠端GUI

  • 先在本地的tty5運行Xorg

    當前在tty2:

    rock@ubuntu17:~$ sudo X :2 vt5 -listen tcp -retro&

    tty5:

    ctrl+alt+F2回到tty2, 確認已經在本地開啟Displayer2對應是tcp6002監聽:

    ?

  • 用ssh的’-R’選項在SSH會話上開啟隧道端口轉發功能:

    ssh -R 127.0.0.1:6010:127.0.0.1:6002 user@remotehost

    確認SSH-Server已為我們啟動端口轉發功能:已開啟tcp6010監聽

    ?

  • 配置遠程終端的DISPLAY環境變量, 執行GUI

    配置DISPLAY=:10指向SSH啟動的轉發端口6010:

    ctrl+alt+F5 :

    最終已轉發到我們本地的6002端口:

  • 使用X11-Forwarding(即’ssh -X user@host’)操作會比較簡單, 其實他自動做的事的步驟就是以上說的

    本地Windows端運行遠端GUI應用

    下面演示使用Xmanager套件結合SSH的’X11 Forwarding’運行遠端GUI

  • 先在本地運行X-Server:
  • 現在X-Server已啟動, 為Displayer0, 監聽tcp6000

  • 接下來運行Xshell, 配置遠端會話屬性, 開啟SSH隧道中的’轉發X11’選項:
  • 注意: SSH服務端也需要開啟’X11 Forwarding’選項. 不開的話Xshell配置隧道中用’TCP/IP轉移’也行, 原理就是前面所說的

  • 登錄SSH,并執行GUI, 相應的UI已經在windows本地顯示出來:
  • 可看到’X11 Forwarding’已經幫我們終端配置好DISPLAY環境變量了

    遠端的SSH Server在本地也開啟的相應的tcp6015監聽, 用于隧道上的端口轉發

    總結

    以上是生活随笔為你收集整理的X-Window结构分析与应用的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。