使用ssh進行X協議的轉發(和NX的比較)
背景
至少到目前為止(2018年2月24日),Linux上的圖形系統都依賴於X。gemfield預計各個發行版到wayland的遷移還得到2020年才成熟,那時候我們就是全面小康社會了。X是個CS架構,有客戶端和服務端。這就神奇了,因為這種架構的存在,X的客戶端和服務端可以不在同一台機器上。有的時候這種能力非常有用。
一般來說,X的客戶端部分一般都使用的是libxcb(更早些時候是xlib)這樣的庫,其實主要的圖形程序也不是直接使用libxcb或者xlib的,而是使用更流行的封裝,比如Qt或者gtk。而服務端則是Xorg進程:
gemfield@ThinkPad-X1C:~$ ps -ef |grep Xorgroot 1002 807 0 2月16 tty7 01:23:43 /usr/lib/xorg/Xorg -nolisten tcp -auth /var/run/sddm/{ab81e385-8f3c-4f6c-881d-a2c8d17bbbef} -background none -noreset -displayfd 17 vt7
X採用C/S模型實現了一個X server 和多個應用程序(client)通信。server接收client的請求繪製窗口,並將來自滑鼠、鍵盤等設備的輸入傳遞給client。
現在的發行版默認情況下,Xorg這個server進程只接收本機的client。但是通過ssh建立隧道進行X協議的轉發就可以克服這個障礙。要轉發X11,我們需要在ssh的客戶端和服務端都開啟支持x11的功能,注意了,是ssh的客戶端和服務端,從X協議的視角出發,它們正好是相反的。
設置
在ssh客戶端部分(也就是X的Server端),如果是Linux系統的話,事情就簡單了。直接使用ssh -X參數即可。如果想要省掉每次都敲-X這個麻煩,則可以在~/.ssh/config中配置ForwardX11使得-X變成默認行為。
gemfield@ThinkPad-X1C:~$ ssh -X ai.gemfield.orgWelcome to Ubuntu 17.10 (GNU/Linux 4.13.0-32-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage * Meltdown, Spectre and Ubuntu: What are the attack vectors, how the fixes work, and everything else you need to know - https://ubu.one/u2Know0 packages can be updated.0 updates are security updates.Last login: Sat Feb 24 09:52:30 2018 from 192.168.1.119/usr/bin/xauth: /home/gemfield/.Xauthority not writable, changes will be ignoredgemfield@ai:~$ which xauth/usr/bin/xauth
如果是Windows系統,麻煩就來了。因為。。。windows沒有X Server 啊,所以你得安裝個X Server在Windows上的實現,比如Xming, 然後啟動X server;另外,windows沒有原生的ssh啊,所以你還得安裝個ssh的客戶端,比如putty。然後相關的設置你自己搜下吧,原理類似。
在ssh的服務端部分(也就是X的客戶端),必須保證xauth是在PATH中的,一般情況下都是滿足的。然後必須在/etc/ssh/sshd_config文件中將X11Forwarding打開(默認是不打開的)。
gemfield@ai:~$ grep X11 -n /etc/ssh/sshd_config89:X11Forwarding yes
使用ssh -X登陸後,ssh會在當前的會話中自動設置環境變數:DISPLAY=localhost:10.0,不需要我們手動介入。
gemfield@ai:~$ echo $DISPLAYlocalhost:10.0
現在就可以啟動個圖形程序試試了:
gemfield@ai:~$ kinfocenter
錯誤處理
當然有時候不會這麼順利,比如會出現下面這樣的情況:
gemfield@ai:~$ kinfocenter X11 connection rejected because of wrong authentication.QXcbConnection: Could not connect to display localhost:10.0Aborted (core dumped)
那麼為什麼會報錯:X11 connection rejected because of wrong authentication ?
我們可以使用-v參數來進行debug:
gemfield@ThinkPad-X1C:~$ ssh -X -v ai.gemfield.orgOpenSSH_7.5p1 Ubuntu-10ubuntu0.1, OpenSSL 1.0.2g 1 Mar 2016debug1: Reading configuration data /etc/ssh/ssh_configdebug1: /etc/ssh/ssh_config line 19: Applying options for *debug1: Connecting to ai.gemfield.org [192.168.1.188] port 22.debug1: Connection established.......Last login: Sat Feb 24 16:03:05 2018 from 192.168.1.119/usr/bin/xauth: timeout in locking authority file /home/gemfield/.Xauthoritygemfield@ai:~$
可以看到問題就出現在:/usr/bin/xauth: timeout in locking authority file /home/gemfield/.Xauthority,這一定是許可權問題了。立馬查看這個文件的許可權:
gemfield@ai:~$ ls -l /home/gemfield/.Xauthority-rw------- 1 root root 96 1月 5 11:42 /home/gemfield/.Xauthority
我的天啊,這個文件怎麼是root產生的呢?過去肯定發生了什麼混亂不堪的事情,所以才有今天的錯誤!把/home/gemfield/.Xauthority刪除掉出新使用gemfield用戶進行touch,結果就好了。
有個訣竅,如果還是各種出錯的花,可以使用strace命令探測哪個系統調用出錯了:
gemfield@ai:~$ strace xauth list 2>&1 |grep -E "^stat|^access"access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)stat("/home/gemfield/.Xauthority-c", 0x7ffc764cd060) = -1 ENOENT (No such file or directory)statfs("/home/gemfield/.Xauthority-c", {f_type=EXT2_SUPER_MAGIC, f_bsize=4096, f_blocks=59699623, f_bfree=13717887, f_bavail=10667878, f_files=15237120, f_ffree=13507556, f_fsid={val=[776034305, 2830689012]}, f_namelen=255, f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0stat("/home/gemfield/.Xauthority-c", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0access("/sys/fs/ext4/nvme0n1p2", F_OK) = 0access("/home/gemfield/.Xauthority", F_OK) = 0access("/home/gemfield/.Xauthority", W_OK) = 0gemfield@ai:~$
但是你要能夠區分出哪個是真正的致命的錯誤。
速度問題
當然了,在歡呼圖形程序能夠顯示在另外的機器上的時候,悲傷也一併來了:它太慢了!!!這個時候,我們有幾種方案:
1,還是X over ssh,但是我們啟用壓縮:
gemfield@ThinkPad-X1C:~$ ssh -X -C ai.gemfield.org
再進一步的話(當然這是可選的),在登錄到伺服器後,我們啟動圖形程序的時候,將標準錯誤扔掉:
gemfield@ai:~$ dolphin 2>/dev/null
或者在ssh客戶端機器上直接這樣:
gemfield@ThinkPad-X1C:~$ ssh -X -C -n ai.gemfield.org dolphin 2>/dev/null
2,使用vnc:
gemfield一般使用tigervncserver,但是不知道為什麼,在安裝有NVIDIA專屬驅動的機器上,vncserver不能啟動X會話,至今還沒找到原因。
另外,chrome瀏覽器商店裡可以下載安裝realvnc的客戶端!
另外,KDE自帶KRDC也支持VNC!
3,使用NoMachine的NX:
下載NoMachine 客戶端:
gemfield@ThinkPad-X1C:~$ wget http://download.nomachine.com/download/6.0/Linux/nomachine-enterprise-client_6.0.78_1_amd64.deb
安裝客戶端:
gemfield@ThinkPad-X1C:~/下載$ sudo dpkg -i nomachine-enterprise-client_6.0.78_1_amd64.deb[sudo] gemfield 的密碼: 正在選中未選擇的軟體包 nomachine-enterprise-client。(正在讀取資料庫 ... 系統當前共安裝有 462343 個文件和目錄。)正準備解包 nomachine-enterprise-client_6.0.78_1_amd64.deb ...正在解包 nomachine-enterprise-client (6.0.78-1) ...正在設置 nomachine-enterprise-client (6.0.78-1) ...NX> 700 Starting install at: 六 2月 24 17:36:19 2018.NX> 700 Installing: nxclient version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 Compiling the USB module.NX> 700 Installing: nxplayer version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 To connect the remote printer to the local desktop,NX> 700 the user account must be a member of the CUPS System Group: lpadmin.NX> 700 Install completed at: 六 2月 24 17:36:23 2018.
下載NoMachine 服務端:
gemfield@edge:~$ wget http://download.nomachine.com/download/6.0/Linux/nomachine_6.0.78_1_amd64.deb
安裝服務端:
gemfield@edge:~$ sudo dpkg -i nomachine_6.0.78_1_amd64.deb[sudo] password for gemfield: 正在選中未選擇的軟體包 nomachine。(正在讀取資料庫 ... 系統當前共安裝有 284060 個文件和目錄。)正準備解包 nomachine_6.0.78_1_amd64.deb ...正在解包 nomachine (6.0.78-1) ...正在設置 nomachine (6.0.78-1) ...NX> 700 Starting install at: 六 2月 24 17:23:08 2018.NX> 700 Installing: nxclient version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 Compiling the USB module.NX> 700 Installing: nxplayer version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 To connect the remote printer to the local desktop,NX> 700 the user account must be a member of the CUPS System Group: lpadmin.NX> 700 Installing: nxnode version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 Creating configuration in: /usr/NX/etc/node.cfg.NX> 700 Installing: nxserver version: 6.0.78.NX> 700 Using installation profile: Ubuntu.NX> 700 Install log is: /usr/NX/var/log/nxinstall.log.NX> 700 Creating configuration in: /usr/NX/etc/server.cfg.NX> 700 Install completed at: 六 2月 24 17:23:56 2018.NX> 700 NoMachine was configured to run the following services:NX> 700 NX service on port: 4000
NX服務監聽在4000埠上:
gemfield@edge:~$ sudo netstat -antp |grep 4000tcp 0 0 0.0.0.0:4000 0.0.0.0:* LISTEN 10441/nxd tcp6 0 0 :::4000 :::* LISTEN 10441/nxd
然後啟動客戶端程序,在系統的開始菜單里有(/usr/NX/bin/nxplayer.bin)。
4,使用x2go(基於ssh)。
推薦閱讀: