Linux

如何在 Linux 上設置 VNC 伺服器?

  • September 26, 2021

如何使用 TigerVNC 在 Linux 上配置和保護 VNC 伺服器?(在無螢幕伺服器或經典機器上)

由於大多數 Linux 發行版的 VNC 伺服器 (TigerVNC) 配置相同,只是安裝方法不同,因此此問題針對:OpenSUSE、Fedora、CentOS、RHEL、Debian、Mageia、Void Linux、Arch Linux、Manjaro 和 FreeBSD(在為了對更多人有用)

安裝 VNC 伺服器

在 Linux 上(在經典機器或無螢幕伺服器上)VNC 伺服器有多種(開源)可能性,例如 TightVNC、TigerVNC 和 TurboVNC(這不是詳盡的列表,本指南將使用 TigerVNC 的本機版本) :

  • TigerVNC 伺服器:使用本機或 Java 程式碼並積極維護。
  • TurboVNC Server:只使用Java,積極維護。
  • TighVNC 伺服器:截至 2020 年,目前 Linux 的版本是 2009 年的 v1.3.10。

我們首先需要一個桌面(例如 XFCE 或 KDE):

# OpenSUSE (XFCE)
zypper in -t pattern xfce

# OpenSUSE (KDE)
zypper install -t pattern kde kde_plasma

# Fedora/OpenSUSE (XFCE)
dnf groupinstall -y "Xfce Desktop"

# Fedora/OpenSUSE (KDE)
dnf -y group install "KDE Plasma Workspaces" 

# CentOS/RHEL (Gnome)
dnf -y group install "Server with GUI"

# CentOS/RHEL (XFCE)
dnf --enablerepo=epel group -y install "Xfce" "base-x" 

# CentOS/RHEL (KDE)
dnf --enablerepo=epel group -y install "KDE Plasma Workspaces"

# CentOS v8 (KDE) 
dnf --enablerepo=epel,PowerTools 
dnf -y group install "KDE Plasma Workspaces" "base-x" 

# Debian (XFCE)
apt install task-xfce-desktop

# Debian (KDE)
apt install task-kde-desktop

# Mageia (XFCE)
dnf install task-xfce

# Mageia (KDE)
dnf install task-plasma5

# FreeBSD (XFCE)
pkg install xfce

# FreeBSD (KDE)
pkg install x11/kde5

# Void Linux (XFCE)
xbps-install -S xfce4

# Void Linux (KDE)
xbps-install -S kde5
# and optionally, kde5-baseapps

# Arch Linux (XFCE)
pacman -S xfce4 xfce4-goodies

# Arch Linux (KDE)
pacman -S plasma-desktop
# or plasma for the full desktop
# pacman -S plasma

# Manjaro (XFCE)
pacman -S xfce4-gtk3 xfce4-goodies xfce4-terminal \
network-manager-applet xfce4-notifyd-gtk3 \
xfce4-whiskermenu-plugin-gtk3 tumbler engrampa

# Manjaro (KDE)
pacman -S plasma kio-extras
# optional kde-applications

安裝 TigerVNC X 伺服器:

# The package name may change depending on the used distro

# CentOS
yum install tigervnc-server

# Mageia/Fedora/CentOS/RHEL
dnf install tigervnc-server

# ALT Linux
apt install tigervnc-server

# openSUSE DNF
dnf install xorg-x11-Xvnc

# openSUSE
zypper install xorg-x11-Xvnc

# Debian
apt install tigervnc-standalone-server tigervnc-common

# FreeBSD
pkg install tigervnc-server

# Void Linux
xbps-install -S tigervnc

# Arch Linux
pacman -S tigervnc

# Manjaro
pacman -S tigervnc 

設置和配置

設置密碼(雜湊版本將保存在~/.vnc/passwd):

vncpasswd

編輯配置文件(啟動腳本,在伺服器啟動時執行)~/.vnc/xstartup如下:

#!/bin/sh

unset SESSION_MANAGER
unset DBUS_SESSION_BUS_ADDRESS

exec startxfce4

# XFCE: startxfce4 or xfce4-session
#exec startxfce4
#exec xfce4-session

# KDE: startkde or startplasma-x11
#exec startkde
#exec startplasma-x11

# Gnome: startx
#exec startx

在以下位置準備和/或定位 VNC 伺服器的配置文件:

~/.vnc/config or /etc/vnc/config

使用配置文件調整 VNC 伺服器的設置…以獲取我們可以使用的可用選項的完整列表,Xvnc -help或者man Xvnc,這是一個配置範例*(另請注意,在 Suse 等某些系統上,如果geometry未設置該選項,VNC 將/可能無法工作)* :

## Supported server options to pass to vncserver upon invocation can be listed
## in this file. See the following manpages for more: vncserver(1) Xvnc(1).
## Several common ones are shown below. Uncomment and modify to your liking.
##
##
# -------------
#  Xvnc --help
# -------------
##
# Start server : vncserver
# Stop server : vncserver -kill :1
##
###############################################################################

# Only allow connection from local hosts
#localhost

# VNC tcp port
rfbport=5900

# TCP port to listen for HTTP (default=0)
httpport=0

# Directory containing files to serve via HTTP (default=)
httpd=

# Protocols...
#nolisten=UDP
#listen=TCP

# IP settings
useipv4
#useipv6

# Interface, listen on the specified network address (default=all)
#interface=127.0.0.1

# Use protocol version 3.3 for backwards compatibility
protocol3.3=0

# Unix socket access mode (default=384)
#rfbunixmode=384

# Unix socket to listen for RFB protocol (default=)
rfbunixpath=

# Name of VNC desktop
desktop=MyVNC

# Geometry original peppy
geometry=1366x768

# Colors
depth=24

# Sharing with multiple clients
#alwaysshared
nevershared

# Disconnect existing clients if an incoming connection is non-shared. 
# If combined with NeverShared then new connections will be refused while 
# there is a client active
disconnectclients

# Security, specify which security scheme to use (None, VncAuth, Plain,
# TLSNone, TLSVnc, TLSPlain, X509None, X509Vnc, X509Plain) (default=TLSVnc,VncAuth)
securitytypes=TLSVnc,VncAuth

# Path to the key of the X509 certificate in PEM format (default=)
#X509Key=

# Path to the X509 certificate in PEM format (default=)
#X509Cert=

# Set maximum number of clients (power of two)
#maxclients=64

# Terminate after s seconds of user inactivity (default=0)
#maxidletime=0

# Terminate when a client has been connected for s seconds (default0)
#maxconnectiontime=0

# Terminate when no client has been connected for s seconds (default=0)
#maxdisconnectiontime=0

# The number of seconds after which an idle VNC connection will be dropped 
# (zero means no timeout) (default=0)
#idletimeout=0

# Zlib compression level (default=-1)
#zlibLevel=-1

# The maximum number of updates per second sent to each client (default=60)
#framerate=60

# GnuTLS priority string that controls the TLS session’s handshake algorithms.  
# See the GnuTLS manual for possible values. Default is NORMAL.
#GnuTLSPriority=

可以使用以下命令啟動/停止 VNC 伺服器;啟動後,您可以使用任何 VNC 客戶端連接到您的伺服器server-ip:used-port (請注意,您可能需要在防火牆上打開使用的埠)

# Start the server
vncserver

# Stop the server :1
vncserver -kill :1

# Forcing multiple server to stop
killall Xvnc

安全

基本 VNC 設置不對交換的流使用加密,這裡有 4 種保護 VNC 連接的常用方法:

  • **使用 X509 證書:**證書的位置需要添加到配置文件中,並且您還需要在客戶端上進行認證(在客戶端應用程序上設置它的位置)。下面將進一步解釋生成 X509 證書。
  • 通過 SSH 會話與 SSH 會話提供的本地 sock 代理建立 VNC 隧道:在伺服器上編輯/etc/ssh/sshd_config並啟用/添加AllowTcpForwarding yes,然後重新啟動您的 sshd 服務systemctl restart sshd.service,然後您可以使用vncviewer該選項-via 手動建立隧道連接,然後使用任何客戶端進行連接:

ssh serverIP -p 22 -i /home/my/private/key -L 5900:127.0.0.1:5900 -C -N

然後連接到127.0.0.1:5900任何 VNC 客戶端。

  • 在伺服器上執行 vncviewer 並通過 SSH X 轉發會話在客戶端上顯示它的 x 視窗:在伺服器上編輯/etc/ssh/sshd_config並啟用/添加X11Forwarding yes然後重新啟動您的 sshd 服務systemctl restart sshd.service

在 SSH 會話(伺服器的 SSH shell)上執行vncviewer :1將在客戶端顯示 vncviewer 視窗。

  • **通過 VPN 連接建立 VNC 隧道:**此處未涉及。

VNC 作為系統服務

VNC 伺服器可以通過以下配置文件用作 Systemd 的服務/etc/systemd/system/vncserver.service,啟用該服務systemctl enable vncserver.service將使其在系統啟動時自動啟動(這不適用於 Void Linux 或 Systemd less Linux 的發行版)。

# /etc/systemd/system/vncserver.service

[Unit]
Description=TigerVNC Server
After=syslog.target network.target

[Service]
Type=simple
#Type=forking
User=MY-USER
Group=MY-USER-GROUP

#If ran with root
#WorkingDirectory=/root
#PIDFile=/root/.vnc/%H%i.pid

#If ran with any other user
WorkingDirectory=/home/MY-USER
PIDFile=/home/%u/.vnc/%H%i.pid

#Environment is required when using a custom GnuTLS version
#Environment=LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib

ExecStartPre=-/usr/bin/vncserver -kill :%i > /dev/null 2>&1
#ExecStart for forking type version
#ExecStart=/usr/bin/vncserver
ExecStart=/usr/bin/vncserver -fg
ExecStop=/usr/bin/vncserver -kill :%i

[Install]
WantedBy=multi-user.target

生成 X509 證書

對於簡單的安全設置,可以遵循這個官方 wiki ,否則這不是一個簡單的話題,要進一步了解這種加密,請參閱本節的文件/連結。簡而言之,文件/連結表明,截至 2020 年,大多數安全密鑰是具有高密鑰大小(至少 4096 位)的 RSA 和EdDSA 的Ed25519 實現,這是使用 SHA-512 (SHA-2) 和 Curve25519 的 EdDSA 簽名方案(一個橢圓曲線提供 128 位安全性)。Ed25519 抗性相當於具有 3072 位密鑰的 RSA。(或者有 EdDSA 的 ED448,它是使用 SHAKE256 (SHA-3) 和 Curve448 的 EdDSA 簽名方案;它相當於具有 ~12448 位密鑰的 RSA,需要更新的 OpenSSL 安裝)

為 CA 生成 RSA-4096-Bits/Ed25519/ED448 私鑰:

對於 Ed25519 和 ED448,需要更新版本的 OpenSSL 和 GnuTLS(請查看下一節)。

mkdir ~/.vnc/ssl

# Generate an RSA 4096-bits key
openssl genrsa -out ~/.vnc/ssl/ca.private.rsa.4096.key.pem 4096
#
# genrsa is superseded by genpkey (PKCS#1 vs PKCS#8 format), the following command is similar to the previous one.
# openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out ~/.vnc/ssl/ca.private.rsa.4096.key.pem

# Or an ED25519 key (equivalent to an RSA with a 3072-bits key, updated openssl required)
openssl genpkey -algorithm ED25519 -out ~/.vnc/ssl/ca.private.eddsa.ed25519.key.pem   

# Or an ED448 key (equivalent to an RSA with a ~12448-bits key, updated openssl required)
openssl genpkey -algorithm ED448 -out ~/.vnc/ssl/ca.private.eddsa.ed448.key.pem

上一步可以通過使用密碼保護密鑰以更安全的方式完成,但 TigerVNC 不支持。

檢查/查看新生成的密鑰(不需要):

openssl pkey -in ~/.vnc/ssl/ca.private.rsa.4096.key.pem -text
# or
openssl pkey -in ~/.vnc/ssl/ca.private.eddsa.ed25519.key.pem -text
# or
openssl pkey -in ~/.vnc/ssl/ca.private.eddsa.ed448.key.pem -text

生成一個簽名 CA,使其有效期為 2 年並添加伺服器 IP(這是必需的,88.44.88.33隨您的 IP 更改):

# RSA 4096-bits 
openssl req -new -x509 -days 730 -key ~/.vnc/ssl/ca.private.rsa.4096.key.pem -out ~/.vnc/ssl/ca.sign.rsa.4096.key.pem -subj '/CN=88.44.88.33' -addext "subjectAltName=IP:88.44.88.33"

#Or ED25519
openssl req -new -x509 -days 730 -key ~/.vnc/ssl/ca.private.eddsa.ed448.key.pem -out ~/.vnc/ssl/ca.sign.eddsa.ed448.key.pem -subj '/CN=88.44.88.33' -addext "subjectAltName=IP:88.44.88.33"

# Or ED448
openssl req -new -x509 -days 730 -key ~/.vnc/ssl/ca.private.eddsa.ed448.key.pem -out ~/.vnc/ssl/ca.sign.eddsa.ed448.key.pem -subj '/CN=88.44.88.33' -addext "subjectAltName=IP:88.44.88.33"

更新伺服器配置以使用 X509:

# Security, specify which security scheme to use (None, VncAuth, Plain,
# TLSNone, TLSVnc, TLSPlain, X509None, X509Vnc, X509Plain) (default=TLSVnc,VncAuth)
securitytypes=X509Vnc

# Path to the key of the X509 certificate in PEM format (default=)
X509Key=/home/USER/.vnc/ssl/ca.private.eddsa.ed448.key.pem

# Path to the X509 certificate in PEM format (default=)
X509Cert=/home/USER/.vnc/ssl/ca.sign.eddsa.ed448.key.pem

與 TigerVNC 查看器連接:

  • 複製ca.sign.eddsa.ed448.key.pem到客戶端
  • 在選項 > 安全性下的 TigerVNC 查看器上,在加密部分僅TLS with X509 certificates選中並打開路徑ca.sign.eddsa.ed448.key.pemPath to X509 CA certificate將 CRL 部分留空)
  • 在身份驗證部分僅選擇Standard VNC

檢查 GnuTLS 會話的握手算法

TigerVNC 使用 GnuTLS 進行加密,在伺服器/客戶端上,設置GnuTLSPriority設置控制 TLS 會話握手算法的優先級字元串(TLS1.0/TLS1.1/TLS1.2/TLS1.3/等);支持的算法可以列出gnutls-cli --list

例如,我們可以使用以下內容測試 TLS v1.2 支持:

vncviewer GnuTLSPriority=NORMAL:-VERS-ALL:+VERS-TLS1.2 -log='*:stdout:100' 

以下是我們如何在伺服器配置文件上強制執行 TLS v1.2/v1.3:

# GnuTLS priority string that controls the TLS session’s handshake algorithms.  
# See the GnuTLS manual for possible values. Default is NORMAL.

# Only TLS v1.2
#GnuTLSPriority=NORMAL:-VERS-ALL:+VERS-TLS1.2

# Only TLS v1.3
GnuTLSPriority=NORMAL:-VERS-ALL:+VERS-TLS1.3

# Verifying if only TLS v1.2/v1.3 policy is working with the following
# vncviewer GnuTLSPriority=NORMAL:-VERS-TLS1.2 -log='*:stdout:100' # v1.2
# vncviewer GnuTLSPriority=NORMAL:-VERS-TLS1.3 -log='*:stdout:100' # v1.3
# This mean use all but v1.2/v1.3 to test if the setting is enforced correctly,
# and thus the connection will be refused for handshake algorithm mismatch.

# Other example of gnutlspriority values (warning, this is just for the syntax)
#GnuTLSPriority=NORMAL:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1:-VERS-TLS1.3
#NORMAL:+SECURE128:-SHA384:-SHA256:-VERS-SSL3.0:-VERS-TLS1.0:-VERS-TLS1.1
#NORMAL:+VERS-TLS1.2:+VERS-TLS1.3:+AES-128-CBC:+RSA:+SHA1:+COMP-NULL

更新 OpenSSL 和 GnuTLS

OpenSSL 和 GnuTLS 是大多數 Linux 系統的兩個主要應用程序/庫,手動更新它們可能會引入安全問題,因為它們將不再自動更新,我們可以通過使用自定義版本(TigerVNC)來限制副作用。

需要更新的 OpenSSL 版本來生成 Ed25519/ED448 密鑰,而vncviewer(客戶端的查看器)/Xvnc(TigerVNC 伺服器)需要 GnuTLS 以添加對 Ed25519/ED448 算法的支持

查看目前支持的算法:

#GnuTLS
gnutls-cli --list | grep EdDSA

#OpenSSL
man -P cat genpkey | grep "Valid built-in algorithm"
openssl list -public-key-algorithms | grep ED

#If EdDSA targeted algorithm is supported there is no need to install from sources

建構、安裝和使用 OpenSSL:

wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz
tar -xvf openssl-1.1.1g.tar.gz
cd openssl-1.1.1g/
./config no-nextprotoneg no-weak-ssl-ciphers no-ssl3 no-shared -DOPENSSL_NO_HEARTBEATS -fstack-protector-strong enable-tls1_3
make install -j2

# After install, OpenSSL can be used 
# for instance as follow to generate the needed key  
/usr/local/bin/openssl genpkey -algorithm ED448 -out ~/.vnc/ssl/ca.private.eddsa.ed448.key.pem

建構、安裝和使用 GnuTLS:

wget https://www.gnupg.org/ftp/gcrypt/gnutls/v3.6/gnutls-3.6.14.tar.xz
tar -xvf gnutls-3.6.14.tar.xz
cd gnutls-3.6.14/
./configure --without-tpm --disable-tests --disable-full-test-suite --disable-non-suiteb-curves --disable-ssl2-support
make install -j2

# This is required for Xvnc and vncviewer, after install can be used 
# by setting LD_LIBRARY_PATH before running vncviewer or Xvnc, 
# like the following example

# TigerVNC Server
export LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib
vncserver

# TigerVNC Viewer
env LD_LIBRARY_PATH=/usr/local/lib64:/usr/local/lib:/usr/lib vncviewer

# To check the used version we can use ldd for instance 
ldd /usr/bin/vncviewer

實驗筆記

在使用帶有 TigerVNC 伺服器的 KDE 時;多次停止/啟動伺服器時,一些 X 應用程序仍在執行,可能與此 systemd問題有關,以修復以下腳本可用於停止伺服器(也可用於 systemd 服務配置文件),以及ps aux | sort | grep USER-NAME | grep -v '\['命令可用於檢查停止伺服器後是否仍在執行。

#cat /usr/bin/vncserver-stop (this is meant for KDE)

#!/bin/sh

vncserver -kill :0
vncserver -kill :1
vncserver -kill :2
vncserver -kill :3

killall Xvnc -9
killall kwin_x11 -9
killall startplasma-x11 -9
killall plasma_session -9

killall Xvnc -9
killall kwin_x11 -9
killall startplasma-x11 -9
killall plasma_session -9

在對查看器進行多次測試後,獲得了最佳速度性能vncviewer -QualityLevel=4 -CompressLevel=2 -PreferredEncoding=Raw

如果伺服器需要暴露在網際網路上,請注意 VNC 伺服器可以通過 nmap 掃描nmap -sV -sC TARGET-IP(在全球網際網路暴露的情況下,可以混淆 VNC 伺服器。


文件資料

link-4link-5link-6link-7link-8link-9link-10link-11連結 12連結 13連結 14連結 15連結 16連結 17。*

引用自:https://unix.stackexchange.com/questions/593570