如何使用 TigerVNC 在 Linux 上配置和保护 VNC 服务器?(在无屏幕服务器或经典机器上)
由于大多数 Linux 发行版上的 VNC Server (TigerVNC) 配置都是相同的,只是安装方法不同,所以本问题针对:OpenSUSE、Fedora、CentOS、RHEL、Debian、Mageia、Void Linux、Arch Linux、Manjaro 和 FreeBSD(在为了对更多人有用)
答案1
安装VNC服务器
在 Linux 上(在经典机器或无屏幕服务器上),VNC 服务器有多种(开源)可能性,例如 TightVNC、TigerVNC 和 TurboVNC(这是一个非详尽列表,本指南将使用 TigerVNC 的本机版本) :
- TigerVNC Server:使用本机或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
,这是一个配置示例geometry
(另请注意,在某些系统(如 Suse 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 设置不对交换流使用加密,以下是保护 VNC 连接的 4 种常见方法:
使用 X509 证书:证书的位置需要添加到配置文件中,并且您还需要在客户端上进行认证(在客户端应用程序上设置其位置)。下面进一步解释生成 X509 证书。
通过 SSH 会话建立 VNC 隧道使用 SSH 会话提供的本地 sock 代理:在服务器上编辑
/etc/ssh/sshd_config
并启用/添加AllowTcpForwarding yes
,然后重新启动 sshd 服务,systemctl restart sshd.service
然后您可以使用vncviewer
以下选项-via
或者手动建立隧道连接,然后使用任何客户端连接:然后使用任何VNC客户端
ssh serverIP -p 22 -i /home/my/private/key -L 5900:127.0.0.1:5900 -C -N
连接。127.0.0.1:5900
在服务器上运行 vncviewer 并在客户端上显示它的 x 窗口通过 SSH 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 证书
对于简单的安全设置,此官方维基可以遵循,否则这不是一个轻松的主题,要进一步了解此类加密,请参阅本节的文档/链接。简而言之,文档/链接表明截至 2020 年,大多数安全密钥都是具有高密钥大小(至少 4096 位)的 RSA,并且埃德DSAEd25519 实现是使用 SHA-512 (SHA-2) 和 Curve25519(提供 128 位安全性的椭圆曲线)的 EdDSA 签名方案。 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 Viewer 连接:
- 复制
ca.sign.eddsa.ed448.key.pem
到客户端 - 在 TigerVNC Viewer 的选项 > 安全下,在加密部分仅保留
TLS with X509 certificates
选中并将路径设置为ca.sign.eddsa.ed448.key.pem
打开Path 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) 来限制这种副作用。
vncviewer
需要更新的 OpenSSL 版本来生成 Ed25519/ED448 密钥,而(客户端查看器)/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 服务配置文件上使用),并且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 协议需要声明自身,因此无需创建服务器和客户端的自定义版本,没有什么比可以在全球互联网暴露的情况下混淆 VNC 服务器。