2014年5月11日 星期日

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

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

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

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

注意: 並不是系統管理員大大把伺服器架好就 ok 了。 每位用戶想要用 vnc 連線時, 都要做這一節 -- 自己的 vnc 服務自己啟動。 (而不是靠系統管理員大大幫你啟動。)

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

如果想要修改 vnc 連線密碼, 可以下 vncpasswd。

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

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

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

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

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

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

roxterm &
icewm &

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

#!/bin/sh
xrdb $HOME/.Xresources
xsetroot -solid black
roxterm &
icewm &
# Fix to make GNOME work
export XKL_XMODMAP_DISABLE=1
/etc/X11/Xsession

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

四、 透過 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 -fNL 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 跟本地端的隧道口連線: xtightvncviewer :61

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

五、 管理你的 vnc 服務

幾個提醒:

  1. 在伺服器端, 要記得不時用 ps ax | grep -i vnc 查看一下目前有哪些 vnc 服務在待命。 用完了, 記得把它關掉。 例如上述指令如果印出:
    12828 ?        S      0:19 Xtightvnc :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 Xtightvnc :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. 但是如果你想改變桌面的解析度, 則必須在命令列上指定: tightvncserver -geometry 640x480 :31

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

真正需要處理的狀況是: 畫面一片空白, 連選單都沒有, 或是在 xstartup 裡面啟動的應用程式有出現, 但沒有邊框可移動/放大/縮小。 這是因為系統沒有啟動 window manager。 請在 xstartup 裡面加一句 icewm & 啟動 icewm 或是其他視窗管理員。

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

六、 進階使用方式

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

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

2 則留言: