[TOC]

0x00 基础介绍

Q: 什么是 Xrdp ? 它有何作用 ?

描述: Xrdp 是一个微软远程桌面协议(RDP)的开源实现,它允许你通过图形界面控制远程系统。通过 RDP 你可以登录远程机器,并且创建一个真实的桌面会话就像你登录本地机器一样。

Q: 其它的可视化界面远程访问方式有那些?

描述: 最常见的是通过xrdp和vnc这两种远程桌面协议来进行可视化远程操作。

xrdp和vnc之间区别介绍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
远程协议      xrdp 	      vnc
BIOS屏幕显示 能 不能
全彩支持 能 能
更改分辨率 能 能
多显示器 只有一个屏幕 多显示器支持
图像传输 图像传输 图像和图形传输
视频播放支持 不能 GPU加速支持
音频传输 不能 双向语音可以控制
鼠标控制 服务器端控制 服务器端控制
USB传输 不能 USB可以通过网络传输
多桌面支持 支持多人连接 只支持一个桌面
原生的Unit桌面 支持 支持
```

**XRDP 和 VNC 适用场景:**
- XRDP
> 适用系统:windows、linux
> 网络流量:较小/正常使用100-200k左右
> 适用场景:由于在色彩、音频、usb及本地磁盘映射方面较好`非常适用于虚拟桌面`;

- VNC
> 适用系统:windows、linux
> 网络流量:较小,常用100k左右
> 适用场景:主要用于linux的服务器的管理,由于无声音和usb传输,不满足于虚拟桌面的使用

Tips : 用Xrdp是因为比VNC好很多,磁盘共享这种附带功能不说,关键是RDP的算法,用起来要比VNC这RFB快VNC采用的RFB算法,下面放一下他们俩的主要区别:
* RFB是在服务器端将窗口在显存中画好之后将图像传给客户端,客户端只充当一个图像解码显示的角色;
* RDP则将画图的工作交给了客户端,服务器需要了解客户端显示能力的具体情况,以便作出相应调整。 RFB主要传图像,RDP主要传指令。就一般应用而言,RFB数据量太大,RDP对客户端要求较高,因此RFB适用于瘦客户端,RDP适用于低速网络。

---

## 0x01 安装桌面环境
描述: CentOS(精简版) / Ubuntu 服务器通常使用命令行进行管理,并且默认没有安装桌面环境, 如果你正在运行 Ubuntu / CentOS 桌面版,忽略这一步。
目的: 配置一个远程桌面,允许你从你的本地机器通过一个简单易用的图形界面来管理你的 Ubuntu 20.04 服务器。


### Ubuntu 系列
在 Ubuntu 源仓库有很多桌面环境供你选择;
- (1) Gnome : 它是 Ubuntu 20.04 的默认桌面环境, 界面炫酷但是比较耗费资源,通常是在桌面版本中使用。
- (2) xfce : 它是快速,稳定,并且轻量的桌面环境,使得它成为远程服务器的理想桌面。

PS : Xrdp 使用默认的 X Window 桌面环境(`Gnome or XFCE`)。

---

## 0x02 Xrdp 安装使用
### How to Install xrdp on Ubuntu ?
**Ubuntu 20.04 Gnome 桌面**
```bash
# (1) 更新源
nano /etc/apt/sources.list
apt-get update && apt-get upgrade

# (2) 安装Ubuntu Gnome桌面与XRDP
apt-get install -y ubuntu-desktop && apt-get install -y xrdp
# sudo apt install xubuntu-desktop # 安装 Xfce

# (3) 查看xrdp服务
sudo systemctl status xrdp

# (4) 默认情况下 Xrdp 使用/etc/ssl/private/ssl-cert-snakeoil.key,它仅仅对“ssl-cert” 用户组成语可读。
# 运行下面的命令将 xrdp 用户添加到这个用户组:(缺省未采用ssl)
# sudo adduser xrdp ssl-cert

# (5) 重启 Xrdp 服务使得修改生效:
sudo systemctl restart xrdp

Tips: 安装完成后即可使用Windows远程桌面工具登录Ubuntu, 非常注意并不需要在家目录中创建.xsession的文件并输入xfce4-session等命令信息(坑);


Ubuntu 20.04 xfce4 桌面
描述: 安装与使用方式与上面相差不大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
apt-get update
apt install xfce4 xfce4-goodies tightvncserver xrdp
# - 以及在 vi /etc/X11/Xsession首行添加xfce4-session
# 创建~/.xsession 和 ~/.xsessionrc
$ echo "xfce4-session" > ~/.xsession
$ D=/usr/share/xfce4:/usr/share/xubuntu:/usr/local/share
$ D=${D}:/usr/share:/var/lib/snapd/desktop:/usr/share
$ cat <<EOF > ~/.xsessionrc
export XDG_SESSION_DESKTOP=xubuntu
export XDG_DATA_DIRS=${D}
export XDG_CONFIG_DIRS=/etc/xdg/xdg-xubuntu:/etc/xdg:/etc/xdg
EOF


# - 支持断开连接后同用户恢复链接
vi /etc/xrdp/xrdp.ini
[Reconnect]
name=Reconnect
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=5910

[Xvnc]
name=Xvnc
lib=libvnc.so
username=ask
password=ask
ip=127.0.0.1
port=-1 # 代表自动分配端口,为其他数字则指定(第一次连接时不可指定)
#xserverbpp=24
#delay_ms=2000

[Xorg]
name=Xorg
lib=libxup.so
username=ask
password=ask
ip=127.0.0.1
port=-1
code=20

# 编辑完保存,执行service xrdp restart 或systemctl restart xrdp重启xrdp


How to Install xrdp to CentOS?

在 CentOS/Redhat 系列操作系统上的安装方法

  • Step 1.扩展源以及采用yum方式安装xrdp;

    1
    2
    yum install -y epel-release && yum install -y xrdp
    systemctl enable xrdp && systemctl start xrdp
  • Step 2.查看启动状态

    1
    systemctl status xrdp


How to use Xrdp ?

描述:现在你已经设置好你的 Xrdp 服务器,是时候打开你的 Xrdp 客户端并且连接到服务器。

Step 1.如果你有一台 Windows 电脑,你可以使用默认的 RDP 客户端,执行mstsc命令调出远程桌面连接,并且在“Computer”区域输入远程服务器 IP地址,并且点击“Connect”。;

Step 2.在登录屏幕,输入你的用户名和密码,点击“OK”。

Step 3.一旦登录你将看到默认的 Gnome 或者 Xfce 桌面,它应该像下面这样,现在你可以从你的本地机器上使用你的键盘和鼠标和远程桌面进行交互了

WeiyiGeek.xrdp远程桌面

WeiyiGeek.xrdp远程桌面


0x03 XRDP 基础配置

配置文件目录结构

描述: Xrdp 配置文件定位在 /etc/xrdp 目录,对于基本的 Xrdp 链接你不需要对配置文件做任何改动,注意如果您修改配置文件后必须要重启Xrdp服务。

1
2
3
4
5
~$ ls /etc/xrdp/
cert.pem km-00000409.ini km-00000410.ini km-00000415.ini km-00000807.ini km-00000813.ini pulse startwm.sh
key.pem km-0000040a.ini km-00000411.ini km-00000416.ini km-00000809.ini km-00000816.ini reconnectwm.sh xrdp.ini
km-00000406.ini km-0000040b.ini km-00000412.ini km-00000419.ini km-0000080a.ini km-0000100c.ini rsakeys.ini xrdp_keyboard.ini
km-00000407.ini km-0000040c.ini km-00000414.ini km-0000041d.ini km-0000080c.ini km-00010409.ini sesman.ini

  • /etc/xrdp/xrdp.ini : 主配置文件,该文件被分成不同的段,允许你设置全局配置,例如安全,监听地址,创建不同的 xrdp 登录会话等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    # Xrdp 监听端口
    ; Examples:
    ; port=3389
    ; port=unix://./tmp/xrdp.socket
    ; port=tcp://.:3389 127.0.0.1:3389
    ; port=tcp://:3389 *:3389
    ; port=tcp://<any ipv4 format addr>:3389 192.168.1.1:3389
    ; port=tcp6://.:3389 ::1:3389
    ; port=tcp6://:3389 *:3389
    ; port=tcp6://{<any ipv6 format addr>}:3389 {FC00:0:0:0:0:0:0:1}:3389
    ; port=vsock://<cid>:<port>
    port=3389

    # 证书设置与SSL 协议
    ; X.509 certificate and private key
    ; openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 365
    ; note this needs the user xrdp to be a member of the ssl-cert group, do with e.g.
    ;$ sudo adduser xrdp ssl-cert
    certificate=
    key_file=
    ssl_protocols=TLSv1.2, TLSv1.3

    # 会话类型(如Xorg、X11rdp和Xvnc)会启动显示服务器。
    # ;配置显示服务器的启动命令行参数(可连接到其他服务器之上)
    [Xorg]
    name=Xorg
    lib=libxup.so
    username=ask
    password=ask
    ip=127.0.0.1
    port=-1
    code=20

    [Xvnc]
    name=Xvnc
    lib=libvnc.so
    username=ask
    password=ask
    ip=127.0.0.1
    port=-1
    #xserverbpp=24
    #delay_ms=2000

    [vnc-any]
    name=vnc-any
    lib=libvnc.so
    ip=ask
    port=ask5900
    username=ask
    password=ask
    #pamusername=asksame
    #pampassword=asksame
    #pamsessionmng=127.0.0.1
    #delay_ms=2000

    [neutrinordp-any]
    name=neutrinordp-any
    lib=libxrdpneutrinordp.so
    ip=ask
    port=ask39393
    username=ask
    password=ask
  • /etc/xrdp/startwm.sh : Xrdp 使用startwm.sh文件启动 X 会话, 如果你想使用另外一个 X Window 桌面,编辑这个文件。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    #!/bin/sh
    # xrdp X session start script (c) 2015, 2017 mirabilos
    # published under The MirOS Licence

    if test -r /etc/profile; then
    . /etc/profile
    fi

    if test -r /etc/default/locale; then
    . /etc/default/locale
    test -z "${LANG+x}" || export LANG
    test -z "${LANGUAGE+x}" || export LANGUAGE
    test -z "${LC_ADDRESS+x}" || export LC_ADDRESS
    test -z "${LC_ALL+x}" || export LC_ALL
    test -z "${LC_COLLATE+x}" || export LC_COLLATE
    test -z "${LC_CTYPE+x}" || export LC_CTYPE
    test -z "${LC_IDENTIFICATION+x}" || export LC_IDENTIFICATION
    test -z "${LC_MEASUREMENT+x}" || export LC_MEASUREMENT
    test -z "${LC_MESSAGES+x}" || export LC_MESSAGES
    test -z "${LC_MONETARY+x}" || export LC_MONETARY
    test -z "${LC_NAME+x}" || export LC_NAME
    test -z "${LC_NUMERIC+x}" || export LC_NUMERIC
    test -z "${LC_PAPER+x}" || export LC_PAPER
    test -z "${LC_TELEPHONE+x}" || export LC_TELEPHONE
    test -z "${LC_TIME+x}" || export LC_TIMEs
    test -z "${LOCPATH+x}" || export LOCPATH
    fi

    if test -r /etc/profile; then
    . /etc/profile
    fi

    # - 防止黑屏命令(最新版本不用添加)
    unset DBUS_SESSION_BUS_ADDRESS
    unset XDG_RUNTIME_DIR
    # - 切换到xfsce4桌面
    echo xfce4-session > ~/.xsession
    xfce4-session

    test -x /etc/X11/Xsession && exec /etc/X11/Xsession
    exec /bin/sh /etc/X11/Xsession


配置防火墙

描述: Xrdp 守护程序在所有的网络接口上监听端口3389。如果你在你的 Ubuntu 服务器上运行一个防火墙,你需要打开 Xrdp 端口。

1
2
3
4
5
# 如果你想允许从任何地方访问(由于安全原因,这种方式不鼓励),运行:
sudo ufw allow 3389

# 想要允许从某一个指定的 IP 地址或者 IP 范围访问 Xrdp 服务器,例如192.168.33.0/24,你需要运行下面的命令:
sudo ufw allow from 192.168.33.0/24 to any port 3389

TIPS: 如果想要增加安全你可以考虑 Xrdp 仅仅监听 localhost,并且创建一个 SSH 隧道,将本地机器的3389端口到远程服务器的同样端口之间的流量加密。


0x04 入坑&出坑

问题1.Sesmal connect ok , sending login info to session mananger, please wait… Login failed for display 0

错误信息: Windows 连接 CentOS XRDP 错误信息 login failed for display 0

错误原因: 输入的操作系统密码有误,注意此处输入密码不是cat /etc/xrdp/xrdp.ini中的username、password而是操作系统中的;

CSDN.login failed for display 0

CSDN.login failed for display 0

其他解决办法:

1
2
3
# 方式1.将 allowed_users=console 改为 anybody
sudo vi /etc/X11/Xwrapper.config
allowed_users=anybody


问题2.Windows 连接 Xdrp(Ubuntu 20.04 server) 出现闪退,报错信息 xsession: line 1: xfce4-session: command not found

错误信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
~$ ls 
-rw------- 1 106 Jan 5 05:56 .Xauthority
-rw-r--r-- 1 16K Jan 5 05:56 .xorgxrdp.11.log
-rw-r--r-- 1 17K Jan 5 05:53 .xorgxrdp.11.log.old
-rw-rw-r-- 1 12 Jan 5 05:55 .xsession
-rw------- 1 4.3K Jan 5 05:56 .xsession-errors

~$ cat .xsession-errors
# Xsession: X session started for weiyigeek at Tue 05 Jan 2021 05:53:45 AM UTC
# dbus-update-activation-environment: setting DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
# dbus-update-activation-environment: setting DISPLAY=:11.0
localuser:weiyigeek being added to access control list # 登录的用户
# dbus-update-activation-environment: setting GTK_MODULES=gail:atk-bridge
# dbus-update-activation-environment: setting QT_ACCESSIBILITY=1
# ...
/home/weiyigeek/.xsession: line 1: xfce4-session: command not found
# Xsession: X session started for weiyigeek at Tue 05 Jan 2021 05:56:14 AM UTC
# dbus-update-activation-environment: setting DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
# dbus-update-activation-environment: setting DISPLAY=:11.0
localuser:weiyigeek being added to access control list # 登录的用户
# dbus-update-activation-environment: setting GTK_MODULES=gail:atk-bridge
# .....
# dbus-update-activation-environment: setting XDG_DATA_DIRS=/usr/local/share:/usr/share:/var/lib/snapd/desktop
/home/weiyigeek/.xsession: line 1: x11-session: command not found

错误原因: Ubuntu 20.04 Server 中默认采用 Gnome 桌面如果配置了没有安装的第三方桌面软件到.xsession将会出现改问题
1
2
3
4
5
6
7
8
# Unity 桌面(老版本)
echo unity> ~/.xsession

# ubuntu-desktop 原始桌面
echo gnome-session > ~/.xsession

# xubuntu-desktop xfce4桌面
echo xfce4-session > ~/.xsession


问题3.dconf-CRITICAL **: unable to create file ‘/run/user/1000/dconf/user’: Permission denied. dconf will not work properly.

问题信息:

1
2
3
4
5
6
7
8
9
$ cat .xsession-errors 
Xsession: X session started for at Sun May 21 22:03:26 CST 2017
X Error of failed request: BadValue (integer parameter out of range for operation)
Major opcode of failed request: 109 (X_ChangeHosts)
Value in failed request: 0x5
Serial number of failed request: 6
Current serial number in output stream: 8
localuser:fred being added to access control list
(xfce4-session:41354): dconf-CRITICAL **: unable to create file '/run/user/1000/dconf/user': Permission denied. dconf will not work properly.

问题描述: 新装的 ubuntu 的 利用 xrdp 登录 xfce4 桌面 普通用户登陆不了,而root管理员却能登陆。
问题解决: 家目录中权限问题
1
/home/fred# chown -R fred:fred *.*


问题4.Windows 桌面连接后远程使用Terminal时 ,Tab键无法自动补全。

描述: 默认情况下是使用ctrl+i的, Tab键被占用作为其他的快捷键;
解决办法: 在windows manager(窗口管理器)中,keyboard 里将用到 Super + Tab 的快捷键 clear 掉即可。


问题5.远程桌面进去之后没有菜单栏

解决办法: 右键面板-> 面板首选项-> backup and restore -> apply configuration图标


问题6.运行一段时间后,出现xrdp_mm_process_login_response: login failed

问题原因:远程桌面没有正确关闭,虽然在windows 系统关闭远程桌面连接,但是在里linux上的进程还在运行,导致连接数量达到上限出现问题。
问题解决:通过设置sesman.ini文件内的MaxSessions参数解决

1
2
3
4
5
6
vi /etc/xrdp/sesman.ini
# 修改会话设置最大会话限制
MaxSessions=50

# 每次断开连接时linux都会关闭会话进程
KillDisconnected=1


问题7.出现 password failed, error - problem connecting

问题信息:如果你的log也有类似 X server for display 10 startup timeout和another Xserver is already active on display 10。

1
2
3
4
5
6
7
8
# 信息1 
sudo vim /var/log/xrdp-sesman.log
# xrdp-sesman.log下错误为:
# [INFO ] starting Xvnc session...
# [ERROR] X server for display 10 startup timeout[INFO ] starting xrdp-sessvc - xpid=2924 - wmpid=2923
# [ERROR] X server for display 10 startup timeout
# [ERROR] another Xserver is already active on display 10
# [DEBUG] aborting connection...

问题原因: tightvnc 出现问题的版本跟X字体有冲突,导致连接Xserver出错。
解决办法:
1
2
3
4
5
apt-get purge tightvnc xrdp
apt-get install tightvncserver xrdp

# 重启启动xrdp服务并通过命令 netstat -tnl 查看监听状态
3350 3389 5910 # 一般这三个端口处于Listen

如果日志里跟第一种情况不同,可以考虑如下方式解决sudo vim /etc/xrdp/sesman.ini添加如下两行:

1
2
3
4
# 解决办法
[Xvnc]
param8=-SecurityTypes
param9=None

Tips: 若上述问题还是无法解决可卸载xrdp服务进行重装,并如上进行同样的操作,修改sesman.ini文件。

卸载xrdp的命令为:

1
2
sudo apt-get purge xrdp
sudo apt-get purge tightvncserver


问题8.xrdp service fails to start,xrdp用systemctl start启动时发现失败,查看错误信息、日志也没啥明确提示

解决办法:

1
2
3
4
touch /var/log/xrdp.log
chown xrdp:adm /var/log/xrdp.log
chmod 640 /var/log/xrdp.log
systemctl start xrdp && systemctl status xrdp


问题9.黑屏问题Xfce4会自动锁屏

描述: 当你远程桌面断开连接一阵子在恢复,会发现黑屏,这时候不管teamviewer还是什么都连不了的。
解决办法: 所以需要关掉自动锁屏,在第一次远程连接上桌面后,左上角Applications-->Settings-->Power Manager, Security标签,”Automatically lock the session”–>”Never” 从不锁定,就OK了。


问题10.ubuntu利用xrdp登陆xfce4桌面vscode无法启动

  • 问题信息:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 问题1.vscode版本信息
    code --version
    # 1.58.2 c3f126316369cd610563c75b1b1725e0679adfb3 x64

    # 问题2.在linux上安装vscode后,发现普通用户可以使用,管理员用户启动不了,报错如下:
    ou are trying to start Visual Studio Code as a super user which isn’t recommended. If this was intended, please specify an alternate user data directory using the --user-data-dir argument.

    # 问题3.发生系统错误无法写入程序用户数据请确保以下目录可写
    - ~/.config/code
    - ~/.vscode/extensions
    - /usr/lib
  • 问题解决:
    1
    2
    3
    4
    5
    6
    7
    8
    # 问题1-2.解决
    # 参考地址: https://github.com/Microsoft/vscode/issues/3451
    sudo sed -i 's/BIG-REQUESTS/_IG-REQUESTS/' /usr/lib/x86_64-linux-gnu/libxcb.so.1
    # 启动的时候,设置下–user-data-dir参数即可,如下所示:
    ./code --user-data-dir="~/.vscode"

    # 问题3.解决
    sudo chown -R weiyigeek:root /usr/lib


问题11.利于XRDP远程登陆切换使用xfce桌面报Environment variable XDG_SESSION_PATH not set. Is LightDM running? 错误。

  • 错误信息:

    1
    ** (light-locker:2769): ERROR **: 08:09:59.625: Environment variable XDG_SESSION_PATH not set. Is LightDM running?
  • 问题解决: 禁用 light-locker

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    $ sudo cp /usr/bin/light-locker /usr/bin/light-locker.orig
    $
    sudo tee /usr/bin/light-locker << EOF
    #! /bin/bash
    # The light-locker uses XDG_SESSION_PATH provided by lightdm.
    if [ ! -z "\${XDG_SESSION_PATH}" ]; then
    /usr/bin/light-locker.orig
    else
    # Disable light-locker in XRDP.
    true
    fi
    EOF
    $ sudo chmod a+x /usr/bin/light-locker


问题12. 解决QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to ‘/tmp/runtime-root’问题

解决办法:

1
2
3
4
5
6
# 在/etc/profile末尾增加两句
export XDG_RUNTIME_DIR=/usr/lib/
export RUNLEVEL=3

# 重载 /etc/profile
source /etc/profile


问题13.Ubuntu配置xrdp后出现 thinclient_drives 文件夹

描述: 下面我们将进行彻底删除 thinclient_drives

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 修改 /etc/xrdp/sesman.ini 文件,其
sudo vim /etc/xrdp/sesman.ini
; Fedora 26 or later : param=/usr/libexec/Xorg
; Debian 9 or later : param=/usr/lib/xorg/Xorg
; Ubuntu 16.04 or later : param=/usr/lib/xorg/Xorg
; Arch Linux : param=/usr/lib/xorg-server/Xorg
; CentOS 7 : param=/usr/bin/Xorg or param=Xorg
;
param=/usr/lib/xorg/Xorg
; Leave the rest paramaters as-is unless you understand what will happen.
param=-config
param=xrdp/xorg.conf
param=-noreset
param=-nolisten
param=tcp
param=-logfile
param=.xrdp/.xorgxrdp.%s.log
.....
# 把 FuseMountName=thinclient_drives 修改为 FuseMountName=xxxx/thinclient_drives,其中 xxxx 是任意一个不存在的位置(其实没有这个文件夹),如改为 FuseMountName=.xrdp/thinclient_drives。
[Chansrv]
; drive redirection, defaults to xrdp_client if not set
FuseMountName=.xrdp/thinclient_drives

# 删除 thinclient_drives 文件夹
sudo umount thinclient_drives
sudo rm -rf thinclient_drives