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

  1. 已安装桌面环境

以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,如接下来这小节所示

  1. 未安装桌面环境,使用最纯净的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

  1. 先在本地运行XQuartz:

    • 配置允许网络客户端接入(开启使用TCP方式):

    • 关闭XQuartz, 重新打开XQuartz. 此时已发现tcp6000端口已经在监听:

    • 允许本地主机访问XQuartz. XQuartz默认没允许本机IP访问

      xhost + 127.0.0.1

  2. 用ssh的’-R’选项在SSH会话上开启隧道端口转发功能:

    意思为将本地XQuartz的X-Server端口tcp6000映射到远端本地上的tcp6010

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

  3. 配置远程终端的DISPLAY环境变量

    root@test:~# export DISPLAY=:10

    如步骤2截图

  4. 执行GUI

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

    如步骤2截图

使用X11-Forwarding(即’ssh -X user@host’)操作会比较简单, 其实他自动做的事的步骤就是以上说的

本地Ubuntu端运行远端GUI应用

下面演示使用Xorg结合SSH的’Forwarding’运行远端GUI

  1. 先在本地的tty5运行Xorg

    当前在tty2:

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

    tty5:

    ctrl+alt+F2回到tty2, 确认已经在本地开启Displayer2对应是tcp6002监听:

  2. 用ssh的’-R’选项在SSH会话上开启隧道端口转发功能:

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

    确认SSH-Server已为我们启动端口转发功能:已开启tcp6010监听

  3. 配置远程终端的DISPLAY环境变量, 执行GUI

    配置DISPLAY=:10指向SSH启动的转发端口6010:

    ctrl+alt+F5 :

    最终已转发到我们本地的6002端口:

使用X11-Forwarding(即’ssh -X user@host’)操作会比较简单, 其实他自动做的事的步骤就是以上说的

本地Windows端运行远端GUI应用

下面演示使用Xmanager套件结合SSH的’X11 Forwarding’运行远端GUI

  1. 先在本地运行X-Server:

现在X-Server已启动, 为Displayer0, 监听tcp6000

  1. 接下来运行Xshell, 配置远端会话属性, 开启SSH隧道中的’转发X11’选项:

注意: SSH服务端也需要开启’X11 Forwarding’选项. 不开的话Xshell配置隧道中用’TCP/IP转移’也行, 原理就是前面所说的

  1. 登录SSH,并执行GUI, 相应的UI已经在windows本地显示出来:

可看到’X11 Forwarding’已经帮我们终端配置好DISPLAY环境变量了

远端的SSH Server在本地也开启的相应的tcp6015监听, 用于隧道上的端口转发

X-Window结构分析与应用相关推荐

  1. 转]Window, Linux动态链接库的分析对比

    转]Window, Linux动态链接库的分析对比 摘 要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高 ...

  2. 长难句结构分析最新经典一百句

    <script type="text/javascript">function StorePage(){d=document;t=d.selection?(d.sele ...

  3. AI神经网络-CNN基本结构分析( Conv层、Pooling层、FCN层/softmax层)

    <link href="https://csdnimg.cn/public/favicon.ico" rel="SHORTCUT ICON"> &l ...

  4. 【JAVA进阶】java中的集合(番外篇3)- HashMap源码底层数据结构分析

    写在前面的话 脑子是个好东西,可惜的是一直没有搞懂脑子的内存删除机制是什么,所以啊,入行多年,零零散散的文章看了无数,却总是学习了很多也忘了很多. 痛定思痛的我决定从今天开始系统的梳理下知识架构,记录 ...

  5. 2021年大数据Flink(十八):Flink Window操作

    目录 ​​​​​​​Flink-Window操作 为什么需要Window Window的分类 按照time和count分类 ​​​​​​​按照slide和size分类 ​​​​​​​总结 Window ...

  6. Ipython的Window与Linux详细安装

    IPython 是一个 python 的交互式 shell,支持补全等等一些强大的功能: IPython 为交互式计算提供了一个丰富的架构,包含: 强大的交互式 shell Jupyter 内核 交互 ...

  7. window 10 桌面显示计算机的操作

    点击设置--个性化设置--主题--桌面图标设置--勾选即可 (这个个性化设置可以点击window右键点击可以,这个看自己的习惯.win7的计算机在win10叫此电脑) 下面放一些图片

  8. [skill] vim 操作多个window

    前言: 分辨率越来越高,屏幕越来越大,行最长80不变,屏幕利用空白越来越大. 开多个window吧! 开window的命令: 平行开一个window :split <//path/file> ...

  9. How to set window title name on Oracle EBS Form?

    --1. 置換掉原來Winodw Property上的Title String ex. SET_WINDOW_PROPERTY('XXDII_INV_MISC_TXN_V',TITLE,:misc_t ...

  10. JS中window.event事件使用详解

    一.描述 event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等. event对象只在事件发生的过程中才有效. event的某些属性只对特定的事件有意义.比如:from ...

最新文章

  1. boost::mpi模块is_mpi_op 功能的测试
  2. python 如何将代码中的输入保存到txt里边
  3. Java谓词的延迟执行
  4. Consolidate Duplicate Conditional Fragments(合并重复的条件片段)
  5. js过渡效果_干货 | Vue事件、过渡和制作index页面
  6. MultipartFile转为File
  7. chrome charset使用_SourceMap-使用教程
  8. 凌阳单片机c语言延时函数,凌阳单片机C语言(网站整理).doc
  9. WCF集成COM+应用程序遇到的问题
  10. HTML无法显示下一页,为何我的浏览器不能直接打开下一页
  11. 【数据分析】电商平台订单报表分析思路及案例
  12. python手机自动化测试脚本语言_python脚本语言? Appium移动自动化测试
  13. C盘太满怎么办? 这些文件可以放心删除!
  14. 一级造价工程师和一级建造师,你更想考哪一个?
  15. Linux系统的下载神器XDM
  16. unity物体自身轴旋转_Unity实现物体沿自身的任意轴向旋转
  17. python平方数_【python】升序查找100内最大平方数的方法
  18. 分享3个实用工具,提取视频中的字幕其实可以很轻松
  19. la是什么牌子_la是什么牌子 La Prairie莱珀妮品牌护肤品怎么样
  20. matlab nan 无色_MATLAB中出现NAN怎么回事

热门文章

  1. 面试题:一头牛重800公斤,一座桥承重700公斤,牛应该怎么过桥
  2. Matlab GUI编程技巧(十五):scroll滚动到组件内的位置及ScrollBar动画演示
  3. 图片转PDF软件免费获取激活码
  4. 穿搭网在线头像试衣间
  5. linux udt 源码,UDT linux下关闭链接耗时过长
  6. 每日一课 | 机器学习入门—如何学习机器学习
  7. 拍拍乐(一)如何在照片里变瘦
  8. 寻根究底,探讨 chi -square特征词选择方法后面的数学支持
  9. Oracle闪回报错,Oracle闪回恢复 - osc_pnw2apz4的个人空间 - OSCHINA - 中文开源技术交流社区...
  10. 鉴权kafka生产端(SCRAM)