2014年5月11日 星期日

遠端桌面連線軟體 VNC 也可以當成電子白板或廣播教學軟體來用

在 Nexus S 手機的 CyanogenMod 上面執行 VNC, 連線到 antix 電腦 [2017/8/8 改用 ubuntu 16.04 + tigervnc 整篇小幅度整理重寫] 我在 「商業炒作之前的雲端運算簡史」 一文當中曾經提到 Virtual Network Computing。 它讓不同的作業系統可以遠端登入、 看見彼此的桌面。 它除了可以讓你從家裡遙控辦公室的電腦之外, 也可以當做遠端開會時共用的桌面/電子白板, 或是老師派送畫面給學生看的(跨越區網)廣播教學軟體。 本文在 ubuntu 16.04 上面使用輕薄短小的 tigervnc 來展示它的用法, 並提醒一些注意事項。 至於 Windows 使用者則可以改參考相關文章或搜尋 「putty vnc 安全」:

  1. SSH X11 Forwarding
  2. 透過SSH的VNC連線
  3. 使用SSH+VNC实现安全的Linux远程桌面管理

vnc 服務跟 apache 或 mysql 不一樣。 apache 或 mysql 由一位系統管理員大大架好伺服器; 其他人就只需要在自己的電腦裝客戶端軟體 (瀏覽器或 mysql-client); 所有客戶端都連到伺服器上同一個 port (80 或 443 或 3306)。 然而 vnc 通常是給自己用的, 所以你要自己用 ssh 登入你所管理的伺服器、 在那裡啟動 vnc 服務, 然後從本地終端機開另一個分頁用 vnc viewer 去連線。 如果那是一部公用伺服器, 那麼每個 vnc 用戶都要各自找一個不同的 port (5900 到 5999 之間) 才能保有隱私。 只有當你想拿它當電子白板或廣播教學時, 才會請不同客戶端連到同一個 port 去。

一、 安裝 tigervnc

Debian 系列 (含 ubuntu) 的版本的官網, 只有較古老的 tightvnc 而沒有較新的 tigervnc。 所以請到 release 頁面、 最顯眼的當前版本 (TigerVNC 1.8.0) 那一節下方有一個 「Binaries are available from bintray」 的連結, 點進去後有好幾個綠色頁籤, 再點其中的 Files, 點進你的版本 (ubuntu-16.04LTS), 再點進你的 CPU 類型 (amd64)。 裡面有五個檔案。 *-dbgsym-* 應該是除錯用的, 我們不需要; *-java* 也不需要。 就只要下載 tigervncserver_1.8.0-1ubuntu1_amd64.deb 跟 xtigervncviewer_1.8.0-1ubuntu1_amd64.deb 兩個檔案。

抓回來之後, 在伺服器上用 sudo dpkg -i tigervncserver*.deb 安裝, 會失敗, 因為欠了一些相依套件。 再補一句 sudo apt-get install -f 就會 fix broken, 也就是把剛剛欠缺的套件補裝上去, 這樣就 ok 了。 在客戶端則是用同樣的方式安裝 xtigervncviewer*.deb。

我會改用 tigervnc, 主要是因為在 tightvnc 裡面打中文, 有時可以有時不行。 改用 tigervnc (也是從 tightvnc 改來的) 就沒問題了。 此外, tigervnc 的客戶端可以隨時放大縮小視窗, 比 tightvnc 方便。

二、 在伺服器端啟動 vnc 服務

  1. ssh 連線進入伺服器。
  2. 以普通用戶的身份, 在伺服器上啟動 vnc server: tigervncserver :7 這裡的 :7 可以改成 (100 以下的) 任意數字。 這個連線服務將會使用 port 5907, 並且被 vnc 稱為 display :7。 如果你選 :26 , 那麼將使用 port 5926, 並且被 vnc 稱為 display :26。
  3. 如果是第一次啟動 vnc 服務, vnc 會要求你設定一個密碼, 將來客戶端要連線時必須輸入你現在設定的這個密碼。
  4. tigervncserver 還會問你要不要設定一個 view-only 的密碼。 先回答 no 比較簡單。
  5. ps ax | grep -i vncps ax | grep -i 'vnc.*:[0-9]' 可以查看本伺服器上目前在哪幾個 display 上面開啟了 vnc 服務。
  6. 另外, 可以下 tail -f ~/.vnc/apstsn\:7.log 追蹤錯誤訊息。 等一下客戶端開始連線時, 這裡會出現 (登入成功或失敗) 的訊息。 不想看的時候, 就按 ctrl-c 結束。

如果啟動失敗, 有可能是因為那個 port 已被 (自己或別人) 佔用 (那就要 kill 掉先前的服務, 或是改用別的 port) 也有可能是因為先前密碼設定失敗 (那就要把 ~/.vnc/ 清空)。 下詳。

三、 從客戶端登入 (裸奔!)

  1. 這是未加密、 不安全的設定! 請只在安全的網路環境底下測試! 假設你的伺服器的 IP 是 192.168.9.5 那麼你可以從客戶端這樣連線: xtigervncviewer 192.168.9.5:7 回答完密碼之後, 就會出現伺服器那頭的桌面了。 不過現在你與伺服器之間的所有資料傳輸都是未加密的!
  2. 可以試著執行一下 "伺服器上有安裝、 客戶端上面沒有安裝" 的軟體。
  3. 不想玩了, 不需要登出或關機。 建議正常關閉所有應用軟體, 然後直接暴力關閉 vnc 視窗。 在伺服器那頭, 桌面 -- 含所有應用軟體 -- 會停留在目前的狀態。 如果下次 (不一定是你、 不一定從這部機器) 再有人連上去, 他就會看到你剛剛離開前的畫面。 如果沒有手動停止服務 (下詳) 的話, 這個桌面會一直保留到伺服器關機為止。

「混合 Windows 與 Linux 工作環境」 這篇舊講義有更多提示, 包含分享桌面、 事後修改密碼、 查詢已被佔用的數字、 錯誤處理等等技巧。

四、 可以連線, 但只有一片空白畫面?

如果客戶端連線成功, 也開啟了 vnc 視窗, 但只有一片空白 (或一片灰色), 連選單都沒有, 那麼有可能是 vnc server 沒有自動啟動視窗管理員 (window manager)。 請先在伺服器端安裝 icewm roxterm, 然後編輯伺服器上的 ~/.vnc/xstartup , 在 /etc/X11/Xsession 那一句之前的任何地方加上以下兩句:

roxterm &
icewm &

例如我的 ~/.vnc/xstartup 長這樣:

#!/bin/sh
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
# ibus-daemon -xrd
xrdb $HOME/.Xresources
xsetroot -solid black
roxterm &
icewm &
# Fix to make GNOME work
export XKL_XMODMAP_DISABLE=1
/etc/X11/Xsession

當然你也可以啟用其他任何類似 roxterm 跟 icewm 的替代軟體。 總之這會令 tigervncserver 一啟動便打開終端機跟視窗管理員, 這樣客戶端連進來時才能操作。

五、 透過 ssh tunnel 安全連線, 順便翻牆

讓 VNC 走 ssh 隧道, 安全連線順便翻牆 就像 firefox 可以透過 ssh tunnel 安全地上網瀏覽 一樣, vnc 也可以透過 ssh tunnel 安全地與遠端桌面連線。 以下動作在客戶端執行。 (右圖參考 SSH Local and Remote Port Forwarding with VNC 一文)

  1. 假設你在 192.168.9.5 這部機器上面有一個名為 greg 的 ssh 帳號, 那麼你可以 用 ssh 鑿一個隧道: ssh -4fNL 5961:localhost:5907 greg@192.168.9.5 意思是: 「開一條隧道, 從本機的 port 5961 進入, 從 192.168.9.5 的 port 5907 出來。 在遠端, 使用 greg 的 ssh 身份通行。」 注意: 此時要敲入 greg 在遠端機器的 ssh 帳號的密碼, 而不是 vnc 的密碼。 敲完之後, 好像什麼事都沒發生一樣。 但是下 ps ax | grep ssh 指令, 會看到有剛剛下的指令已經變成一個背景程序在待命。
  2. 然後叫 vnc 跟本地端的隧道口連線: xtigervncviewer :61

就像 firefox 走 ssh 隧道不僅可以保護隱私而且可以翻牆一樣, vnc 走 ssh 隧道也同時具有保護隱私跟翻牆兩重效果。 我在系上管了一部伺服器, 從圖書館或從校外都無法用 vnc 連線; 但是改走 ssh 隧道就暢通無阻。

六、 管理你的 vnc 服務

幾個提醒:

  1. 用完之後, 要記得到伺服器端 ps ax | grep -i vnc 查看一下目前有哪些 vnc 服務在待命, 以便把它關掉。 例如上述指令如果印出:
    12828 ?        S      0:19 Xtigervnc :7 -desktop X -auth /home/ckhung/.Xauthority -geometry 1024x768 -depth 24 -rfbwait 120000 -rfbauth /home/ckhung/.vnc/passwd -rfbport 5907 -fp /usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,/usr/share/fonts/X11/100dpi/ -co /etc/X11/rgb
    12835 ?        S      0:00 /bin/sh /home/ckhung/.vnc/xstartup
    15010 pts/2    S+     0:00 grep vnc
    29504 pts/2    S      0:02 Xtigervnc :26 -desktop X -auth /home/ckhung/.Xauthority -geometry 1024x768 -depth 24 -rfbwait 120000 -rfbauth /home/ckhung/.vnc/passwd -rfbport 5926 -fp /usr/share/fonts/X11/misc/,/usr/share/fonts/X11/Type1/,/usr/share/fonts/X11/75dpi/,/usr/share/fonts/X11/100dpi/ -co /etc/X11/rgb
    29512 pts/2    S      0:00 /bin/sh /home/ckhung/.vnc/xstartup
    
    那麼你可以 (比較優雅地) 用 vncserver -kill :26 或 (比較粗魯地) 直接用 kill 29504 砍掉位於 display :26 的服務。
  2. 如果想改變連線密碼, 可以下 vncpasswd 指令。
  3. 在 ~/.vnc 目錄底下, 存有 vnc 相關的設定檔跟紀錄檔。
  4. 其中 ~/.vnc/xstartup 這個檔案, 內含啟動 X Window 的指令。 例如在自己的電腦上, 我採用 gcin 作為中文輸入法; 但是透過 vnc 卻時, 無法啟動遠方伺服器的中文輸入。 後來找到這一篇: How to enable Korean language input keyboard on Ubuntu, 在伺服器上改安裝 ibus 作為中文輸入法就可以了。 於是我自己的電腦上, 在 ~/.xinitrc 裡面有著 gcin 的相關設定; 但是在遠方伺服器上, 則是在 ~/.vnc/xstartup 裡面放著 ibus 的相關設定。 有時如果無法啟動 vnc 服務, 可以試著把這個目錄清空, 再試一次。
  5. 如果兩頭都裝相同的輸入法, 也沒問題。 可以把 「中英輸入切換鍵」 設成不同的按鍵, 例如客戶端是 ctrl-space, 而伺服器端則是 super-space (就是 windows 鍵 加 spcae), 這樣伺服器端的切換鍵就不會被客戶端搶走。
  6. 啟動伺服器時, 可以直接在命令列上指定解析度: tigervncserver -geometry 640x480 :31。 不過這對舊的 tightvnc 比較有用; 對新的 tigervnc 來說, 客戶端反正隨時都可以拉視窗改變 vnc 視窗大小。

我曾經遇過啟動 xtigervncviewer 時, 在 vnc 視窗裡面出現這樣的錯誤訊息: 「GDBus.Error.org.freedesktop.PolicyKit1.Error. Failed: An authentication agent already exists for the given subject」 原因好像跟你啟動兩個 X Window 有關: 開機以來一直在用的這個桌面, 還有 xtigervncviewer 又啟動的第二個桌面。 如果全部登出、 改用文字模式登入、 用另一部電腦來連 vncserver, 這個錯誤就消失了。 其實它並不影響執行; 可以直接關掉就好。

老師請注意: 上完課後, 記得把學生忘記關閉的所有 vncserver 停掉, 不然很危險的!

七、 進階使用方式

  1. 如果你的網路環境支援 IPv6, 那麼鑿隧道那一句 ssh -4fNL ... 可以改成 ssh -fNL ...。 不過要記得先把舊的那個 process 砍掉, 否則新的這句會搶不到 port。
  2. 如果好幾個客戶端同時連線到同一個 vnc 服務 (同一個 display 代號), 那麼 vnc 就變成了遠端開會時的共用桌面。 例如可以開啟繪圖軟體, 就變成共用的電子白板。 所有連線者都會一起搶滑鼠跟鍵盤, 可以一起畫圖。
  3. 如果老師的電腦啟用 vnc 服務, 並且設定 "view-only" 密碼, 再邀請學生連線, 這就變成螢幕廣播軟體。 當然, 它不具強制性。 它跟 italc 誰比較快, 我沒實驗過。 不過它的設定應該比 italc 簡單一些。
  4. apt-cache search vnc | grep -v '^lib' 可以看到有好多不同版本的 vnc 實作。 寫完本篇後才發現有一個 ssvnc 直接就支援加密安全通道。 詳見 apt-cache show ssvnc
  5. vnc 不僅有 linux 版、 windows 版、 Mac OS 版, 還有 Android 版。 本文插圖是我在 CyanogenMod 上面安裝 androidVNC 客戶端, 連線到桌機的 antix 實況。 至於拿 android 當伺服器... f-droid 還沒有; 但若你不介意使用 「非自由的軟體」, 也可以搜尋 「android vnc server」。
  6. 但是 android 客戶端這樣的連線, 當然是不安全的。 還沒空研究 android 上透過 ssh 隧道的 vnc 連線
  7. 因為 html5 太強大了, 所以還出現了 Guacamole novnc, 可以讓客戶端直接拿瀏覽器來當作 vnc 連線工具。
  8. 這一篇 提到如何把連線鎖在一個應用軟體的介面, 透過這個嚴格的設定反而更能夠把你的電腦桌面同時分享給更多不同使用需求的人。

以上是想像出來跟搜尋到的可能性; 大部分自己還沒試過。 如果您寫了教學文, 或是在什麼樣有趣的情境底下使用 vnc, 請留言 (及連結) 分享一下吧!

3 則留言:

  1. 感謝您的分享!非常詳細:)

    回覆刪除
  2. tigervnc 可以隨時改變視窗大小, 好用! 切換中文也比較沒問題。 已改用 ubuntu 16.04 + tigervnc 整篇小幅度整理重寫。

    回覆刪除