我这个标题讲的事儿,估计不少运维同行都干过:手头一台装好 CentOS 7.6 的服务器,平时命令行操作没问题,但有些场景必须看图形界面,比如给开发同事演示、跑一些带 GUI 的监控工具、或者在客户现场临时整改系统。这时候最省事的办法,就是让 Windows 自带的 mstsc 远程桌面直接连到 Linux 桌面上,这就是今天要说的 Xrdp 方案。
Xrdp 这套东西,本质上是给 Linux 装一个 RDP 协议的服务端。Windows 的远程桌面客户端(mstsc)开箱即用,不需要额外装任何软件,输个 IP、输个账号密码就能进图形桌面。相比 VNC 那套需要单独客户端、默认端口还容易撞防火墙规则的玩法,Xrdp 在“Windows 用户连 Linux”这个场景里确实香得多。这篇文章我会把从零开始配置的完整过程、背后原理、常见坑都捋一遍,适合刚接触 Linux 图形远程的运维新人,也适合想把手头 CentOS 7 机器快速变成可远程图形桌面的老手做参考。
1. 为什么选 Xrdp,以及它是怎么工作的
先花点篇幅说清楚选型逻辑。很多人在做 Linux 远程图形方案时,第一反应是 VNC。VNC 有它的优势,比如协议跨平台、实现在各种 Linux 发行版上都成熟,但它有个致命短板:Windows 端要装 VNC Viewer 之类的客户端。公司内部还好说,到了客户现场,一个安全策略严格的环境里,你为了一台 Linux 机器往 Windows 上装第三方客户端,沟通成本特别高。Xrdp 就不一样,它直接和 Windows 自带的 mstsc 对接,客户端零部署,而且 RDP 协议本身在 Windows 平台上有原生优化,体验顺滑很多。
1.1 RDP 与 VNC 的本质区别
VNC 走的是 RFB(Remote Frame Buffer)协议,它传输的是纯图像帧,服务端把屏幕内容压缩后发给客户端。这种方式实现简单,但带宽占用大、延迟高,而且默认端口是 5900 起,很多企业防火墙对非标准端口策略很严格。
RDP(Remote Desktop Protocol)则是传输层面的协议,它更聪明:服务端和客户端之间会协商图形渲染指令,而不是简单地发整张截图。鼠标移动、窗口刷新这些操作,RDP 会通过指令描述“哪里变了”,而不是把整个屏幕重发一遍,所以同等网络条件下 RDP 的体验明显更流畅。Xrdp 做的事情,就是在 Linux 上实现了 RDP 协议的服务端,同时把收到的 RDP 图形指令翻译成 X Window 系统的操作,让 Linux 桌面能响应 Windows 客户端的输入和显示请求。
1.2 Xrdp 的整体工作流程
Xrdp 启动后跑两个主要进程:xrdp监听 3389 端口(RDP 默认端口),负责和 Windows 客户端通信;xrdp-sesman管理会话生命周期。用户通过 mstsc 连接时,xrdp 会调用 sesman 创建一个新的会话,然后在这个会话里启动 X Server(通常用 Xorg 或者 Xvnc 做后端)。CentOS 7 上最常见的组合是 xrdp + xorgxrdp,也就是用 xorgxrdp 这个驱动直接让 Xorg 和 xrdp 对接,不走 VNC 那一层,性能和稳定性都更好。
提示:xrdp 默认监听的是 TCP 3389 端口,和 Windows 远程桌面服务用的是同一个端口号。也就是说,你在一台 Windows 机器上连 Linux 的 Xrdp,和连另一台 Windows 的远程桌面,在客户端操作上完全一致。
2. 环境准备与前置检查
动手之前,先把环境捋清楚。我这边的实验机是一台 CentOS 7.6 的虚拟机,最小化安装,网络用的是 NAT 模式。当然在真实服务器上操作流程是一模一样的,区别只是网络环境复杂一些,防火墙规则可能需要和网络管理员确认。
2.1 系统版本确认
登录系统后,先确认一下版本信息和内核,避免后续装了不兼容的包。
cat /etc/redhat-release uname -r正常情况下你会看到类似这样的输出:
CentOS Linux release 7.6.1810 (Core) 3.10.0-957.el7.x86_64这里有个容易踩的坑:CentOS 7 的软件仓库里,xrdp 包在 epel-release 仓库中,而不是默认的 base 仓库。如果直接yum install xrdp报“没有可用软件包”,十有八九就是 epel 仓库没有配置好。
2.2 检查/安装桌面环境
Xrdp 本身只负责远程连接,真正的图形桌面需要系统里有桌面环境。CentOS 7 默认的桌面是 GNOME,但最小化安装的服务器多半没有桌面。如果你确定机器上没装桌面,先安装 GNOME:
yum groupinstall -y "GNOME Desktop"这个命令会安装 GNOME 桌面以及配套的图形工具,耗时比较长(10-30 分钟,取决于网络),建议在 tmux 或者 screen 里跑,防止终端断开导致中断。安装完成后先别急着重启,等 Xrdp 配好再一起验证。
注意:如果你不想装完整的 GNOME,也可以装 Xfce 这种轻量桌面,配置过程类似,只是在启动脚本里指定的桌面命令不同。服务器内存只有 2G 的话,强烈建议用 Xfce,GNOME 在这点内存下会卡到怀疑人生。
2.3 解决网络和 EPEL 源问题
CentOS 7 官方源停止维护后,新装机器建议先把 yum 源切到阿里云或者清华镜像,否则yum install会直接超时或者 404。具体步骤如下:
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo yum clean all && yum makecache然后安装并启用 EPEL 仓库:
yum install -y epel-releaseEPEL(Extra Packages for Enterprise Linux)是 Fedora 社区维护的软件包仓库,里面有大量不在官方仓库中的软件,xrdp 就在其中。装完以后最好再执行一次yum makecache,让仓库缓存生效。
网络这块还有一个隐蔽的坑:如果服务器用了代理,yum和wget这些命令很容易因为代理配置问题连不上外网,导致安装失败。检查一下/etc/yum.conf里的proxy字段,还有环境变量里的http_proxy、https_proxy,确保能正常访问外网镜像。
3. 安装 Xrdp 并进行核心配置
环境就绪后,进入正题。CentOS 7 的 xrdp 安装超级简单,两条命令搞定,但配置文件里的一些细节值得深挖。
3.1 安装 xrdp 和 xorgxrdp
yum install -y xrdp xorgxrdpxorgxrdp这个包很关键,它的作用是为 Xorg 提供 RDP 支持的驱动模块。没有它,xrdp 就只能退回到 Xvnc 作为后端,性能和分辨率适配都会打折扣。安装完成后,启动服务:
systemctl start xrdp systemctl enable xrdp systemctl status xrdp看到active (running)就说明基本服务起来了。再用ss确认端口监听状态:
ss -tlnp | grep 3389正常输出应该是:
LISTEN 0 5 0.0.0.0:3389 0.0.0.0:* users:(("xrdp",pid=12345,fd=11))如果这里没有任何输出,多半是服务没启动成功,查看日志/var/log/xrdp.log是最直接的排查方式。
3.2 理解 xrdp.ini 关键参数
xrdp 的主配置文件在/etc/xrdp/xrdp.ini。这个文件很长,我建议重点关注几个字段:
[Globals] port=3389 fork=true use_vsock=false [Logging] LogFile=xrdp.log LogLevel=DEBUGport=3389:RDP 服务监听端口。如果和现有服务冲突,可以改成 3390 之类的端口,但客户端连接时也要对应改地址,比如192.168.1.10:3390。fork=true:允许并发连接,多个用户同时远程或者一个用户开多个会话都需要它。LogLevel=DEBUG:排查问题时临时改成 DEBUG,跑通后再改回 INFO,避免日志刷爆磁盘。
往下翻,你会看到[Xorg]这样的会话类型定义:
[Xorg] name=Xorg lib=libxup.so username=ask password=ask ip=127.0.0.1 port=-1 code=20这里定义的其实是 xrdp 启动时会话的类型。lib=libxup.so表明使用 Xorg 后端,username=ask和password=ask表示每次连接时都询问用户和密码。不要动code=20这行,它是内部标识。
3.3 配置默认桌面(startwm.sh)
xrdp 在用户认证成功后,会去执行/etc/xrdp/startwm.sh这个脚本,由它启动桌面环境。CentOS 7 默认的startwm.sh大约是下面这样:
#!/bin/sh if [ -r /etc/default/locale ]; then . /etc/default/locale export LANG fi . /etc/X11/Xsession直接执行/etc/X11/Xsession,CentOS 7 会去读取用户的~/.xsession文件。如果用户的家目录下没有这个文件,Xsession 默认会尝试启动当前系统里已安装的桌面环境。这里容易出的问题我放在后面“常见问题”部分细说。
如果你装的是 Xfce,我一般会修改startwm.sh,在最后追加一段,显式指定会话类型。比如:
#!/bin/sh if [ -r /etc/default/locale ]; then . /etc/default/locale export LANG fi echo "startxfce4" > ~/.xsession chmod +x ~/.xsession . /etc/X11/Xsession技巧:与其改全局脚本,不如在具体用户的家目录下放一个
.xsession文件,内容写成exec startxfce4或exec gnome-session,对单个用户生效,不影响其他用户。全局改startwm.sh的方式适合所有用户都想用同一种桌面的场景。
3.4 SELinux 与防火墙放行
CentOS 7 默认是开启 SELinux 的,xrdp 这种需要起 X 会话、监听网络端口的服务,非常容易撞 SELinux 策略。很多人的 xrdp 配置看起来一切正常,但客户端连接后就是黑屏然后断开,最后发现是 SELinux 拦了。
我建议直接把 xrdp 相关的布尔值打开:
setsebool -P xserver_execmem on setsebool -P httpd_can_network_connect on如果对 SELinux 不太熟,图省事可以临时用setenforce 0验证是不是 SELinux 的问题,确认后要么按上面设置布尔值,要么把 SELinux 改成 permissive 模式。真生产环境建议精确设置布尔值,别直接禁 SELinux。
然后是防火墙。CentOS 7 默认启用 firewalld,需要放行 3389 端口:
firewall-cmd --permanent --add-port=3389/tcp firewall-cmd --reload firewall-cmd --list-all看到ports: 3389/tcp就说明防火墙已经放行。如果你用的不是 firewalld 而是 iptables,那就用下面这条命令:
iptables -I INPUT -p tcp --dport 3389 -j ACCEPT service iptables save这里要注意,云服务器(阿里云、腾讯云等)还有一层安全组策略,光在系统里放行不够,安全组的入方向规则也得把 3389 端口打开,否则外部访问依然不通。
4. Windows 端 mstsc 连接实操
服务器端配置完成后,接下来就是和 Windows 客户端联调。整个过程其实非常简单,但有几个细节点值得说道说道。
4.1 快速发起 mstsc 连接
Windows 下按Win + R,输入mstsc,回车打开远程桌面连接窗口。计算机地址栏填写 Linux 服务器的 IP,比如192.168.1.100,点击“连接”。
首次连接时,mstsc 会提示“无法验证此远程计算机的身份”,原因是 Xrdp 默认用的是自签名证书,不受 Windows 信任。直接选择“是”继续即可。
输入你在 Linux 上的用户名和密码,然后点击确定。正常情况下你会看到 Linux 桌面出现在 Windows 窗口里,此时就已经成功远程登录了。
4.2 分辨率与显示设置
mstsc 窗口默认会以当前窗口大小自适应远端分辨率。但如果你想要固定的分辨率,可以在 mstsc 里点“显示选项”,在“显示”标签页里调整“显示配置”滑块,选择1920x1080或者别的分辨率。
如果是多显示器环境,mstsc 还支持跨多个显示器显示远程桌面,选项在“显示”标签页的“所有监视器”下拉框里勾选即可。这个功能对需要在 Linux 桌面上同时开多个窗口做演示的场景非常实用,客户端和服务器端都不需要额外配置。
4.3 会话断开与重连
RDP 的一个好处是断开连接不会结束会话。你直接关掉 mstsc 窗口,远端的 Linux 桌面会话并不会退出,所有打开的程序继续运行。下次再用同一个用户连接,系统默认会重新连接到你上次的会话,而不是开一个新会话。这个特性对于跑长时间任务的场景尤其有用,比如你在 Linux 桌面上开了一个日志监控程序,本地关掉窗口,程序还继续跑着,回来再看还是原样。
如果确实想让用户“重新登录”(新开一个会话),可以在服务器端用xrdp-sesman的管理命令清理会话:
xrdp-sesman -k systemctl restart xrdp-sesman重启 sesman 会把当前所有会话都清掉,不建议在有用户在线时贸然操作,容易把人踢下线。
5. 常见问题排查实录
Xrdp 配置本身不难,但工程实践中总会遇到各种诡异问题。这一节我整理几个高频故障,附上排查思路和解决方案。
5.1 连上后黑屏,或者卡在 “starting the session”
这是 Xrdp 最常见的问题,没有之一。客户端输入账号密码后,界面一直停留在蓝色背景下的小窗口,写着 “starting the session...”,然后过一会儿就断开,或者干脆黑屏。
我遇到过几次,根因基本出自两个环节:一是用户家目录的.xsession文件指定了错误的桌面环境,比如写了exec gnome-session但系统根本没有安装 GNOME;二是/etc/xrdp/startwm.sh里的桌面启动命令执行时报错退出。
排查办法分两步走。先看日志:
tail -100 /var/log/xrdp.log tail -100 /var/log/messages如果日志里能看到Xorg启动的相关报错,比如找不到gnome-session,那就清楚了。解决办法是修改用户家目录下的.xsession文件,写成实际存在的桌面命令。以 Xfce 为例:
echo "exec startxfce4" > ~/.xsession chmod +x ~/.xsession然后再重新连接。如果还是不行,看看是不是用户目录权限或者.ICEauthority文件的问题,直接把家目录临时 chown 一下,或者删除有问题的.ICEauthority:
rm -f ~/.ICEauthority chown user:user ~/.ICEauthority5.2 登录后直接闪退,回到 mstsc 连接界面
这种情况通常是 xrdp-sesman 在启动会话时出现问题。先查看 sesman 的日志:
cat /var/log/xrdp-sesman.log常见错误包含Failed to start xrdp-sesman、Cannot open display这类。Cannot open display最可能的诱因是 Xvnc 或者 Xorg 后端启动失败。如果你装的是xorgxrdp,确认一下内核模块和驱动是否正常:
ls /usr/lib64/xorg/modules/drivers | grep rdp如果查询结果为空,说明 xorgxrdp 安装不完整,重新执行yum install -y xorgxrdp试试。
5.3 连不上,提示端口超时或拒绝连接
如果 mstsc 报“远程计算机无法连接”,第一步先确认服务器远端能不能通:
telnet 192.168.1.100 3389或者用nc:
nc -zv 192.168.1.100 3389如果命令报Connection refused,说明 xrdp 服务本身没起来或者端口没监听;如果一直卡住不动然后超时,多半是防火墙拦了,或者云服务器安全组设置不对。
再补充一个容易忽视的点:CentOS 7 默认内核的net.ipv4.tcp_tw_reuse等参数有时候会在高并发下导致端口连接异常,但单用户连接基本遇不到,这个不用太焦虑。
5.4 键盘布局、剪贴板和中文乱码问题
中文乱码在 Linux 远程里很常见,原因是环境变量LANG没设置正确。可以在/etc/xrdp/startwm.sh中强制加上:
export LANG=zh_CN.UTF-8前提是系统已经安装了中文语言包,没有的话先执行:
yum install -y langpacks-zh_CN localectl set-locale LANG=zh_CN.UTF-8键盘布局不对,比如在 Windows 上按@键输出的是双引号,通常是因为 Xorg 启动时的键盘配置不对。在startwm.sh里加一条:
setxkbmap -model pc105 -layout us如果国内用户习惯,可以改成-layout cn。注意这行要放在 X 会话启动之前,并且要求你的桌面环境允许执行外部命令。
剪贴板问题也很常见:Xrdp 的剪贴板共享默认已经启用,但有的时候从 Windows 复制文字,到 Linux 桌面上粘贴没反应。这个问题多半和剪贴板进程有关。用 GNOME 的时候,执行一下:
yum install -y xclip然后远程桌面里启动xclip守护进程,再试试粘贴。十有八九可以搞定。
6. 安全加固与多用户并发
Xrdp 部署完成后,生产环境绝不能裸奔。远程桌面服务面向公网开放的风险很大,无论是暴力破解还是扫描漏洞,都不是闹着玩的。下面这几条建议最好照做。
6.1 修改默认端口
把 3389 改成不常用的端口能显著降低被扫描到的概率。
sed -i 's/port=3389/port=3390/' /etc/xrdp/xrdp.ini systemctl restart xrdpWindows 客户端连接时,在计算机地址栏填192.168.1.100:3390就能连上。当然这只是提高安全性下限,不能当万灵丹。
6.2 限制来源 IP,只让指定地址访问
用 TCP Wrapper 或者 firewalld 的 rich rule 实现源地址限制。
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.0/24" port protocol="tcp" port="3389" accept' firewall-cmd --permanent --add-rich-rule='rule family="ipv4" port protocol="tcp" port="3389" drop' firewall-cmd --reload上面两条规则的意思是:只有192.168.1.0/24网段的机器能访问 3389,其他来源一律丢弃。如果你有固定办公 IP,把网段换成单个 IP 效果更好。
6.3 配置 TLS 证书加密通信
Xrdp 自带 TLS 支持,但默认使用自签名证书,通信数据虽然是加密的,但证书不被客户端信任。如果你有内部 CA 签发的证书,可以替换默认证书。编辑/etc/xrdp/xrdp.ini中的[Globals]段:
certificate=/etc/pki/tls/certs/server.crt key_file=/etc/pki/tls/private/server.key然后重启 xrdp。这样客户端连接时会弹出“证书信任”提示,点确定之后整个会话的流量就是证书加密的,比默认的自签名证书安全性高一个档次。
6.4 多用户并发与资源控制
Xrdp 天然支持多用户同时登录。fork=true开启后,多个用户可以分别建立会话,互不干扰。但每个图形会话都会占用一定的内存,GNOME 桌面下单个会话占用 500MB 到 1GB 内存非常常见。服务器内存有限时,用 Xfce 替代 GNOME 或者限制并发会话数。限制并发数可以在/etc/xrdp/xrdp.ini里调整MaxSessions参数:
[Globals] MaxSessions=4这个参数建议根据服务器内存和业务需求测算后再设。如果一台机器只有 4G 内存,MaxSessions设成 4 的话,很可能会出现内存打满、卡到完全无法操作的状况。
心得:我自己的习惯是,把 Xfce 作为远程桌面的默认会话,然后把 GNOME 留给本地显示器使用。这样远程连接只吃轻量资源,本地桌面体验不受影响。用 Xrdp 启动会话时指定
startxfce4,完全是文件级的选择,不需要改系统默认启动级别。
7. 从实际项目里提炼的两个细节
前面讲完了主流配置和故障排查,这里补充两个我在实际项目里踩过、但网上教程很少提到的细节,对生产部署很有参考价值。
7.1 关于“桌面会话残留”的坑
用了 Xrdp 一段时间后,有时候你会发现服务器内存占用越来越高,即使所有客户端都断开了,仍有残留的 Xorg 进程在跑。这是因为用户断开 RDP 连接时,如果桌面上还有未退出的 GUI 程序,会话不会自动清理干净。轻量情况下,它保留的是你的“上次桌面状态”,方便你重连后继续工作;但一直不清理,进程堆积多了就会拖垮服务器。
处理办法是定期检查会话进程,超过空闲时间的会话直接清理:
ps -ef | grep Xorg kill <PID>或者更优雅一点,给 xrdp-sesman 配会话超时。超时参数在/etc/xrdp/sesman.ini中配置,KillDisconnected和DisconnectedTimeLimit是控制会话断开后保留时长的字段。建议在公司内部环境设置DisconnectedTimeLimit=0,表示断开后立即清理,避免资源泄漏;如果需要保留断开会话状态,就设成具体秒数,比如DisconnectedTimeLimit=86400,代表保留 24 小时。
7.2 用脚本快速监控 Xrdp 服务状态
生产环境里服务挂掉不能总靠人工盯,定时脚本巡检是基本操作。下面这个简单脚本可以每 5 分钟检查一次 xrdp 进程和端口,异常时自动拉起并记录。
#!/bin/bash if ! pgrep -x "xrdp" > /dev/null; then echo "$(date) xrdp process is down, restarting..." >> /var/log/xrdp_monitor.log systemctl restart xrdp fi if ! ss -tln | grep -q ":3389"; then echo "$(date) xrdp port not listening, restarting..." >> /var/log/xrdp_monitor.log systemctl restart xrdp fi配合 crontab:
*/5 * * * * /usr/local/bin/xrdp_monitor.sh这个脚本逻辑很简单,主要就是两个判断,进程在不在、端口在不在。两条都正常就什么都不做,异常就重启并写日志。千万不要把脚本写得花哨复杂,生产环境里的监控越简单越可靠。
8. 最后分享一点个人经验
Xrdp 在 CentOS 7 上的部署,说实话难度不高,真正让人头疼的都是些边角问题。用了这么多年,我最想强调的还是那句老话:先确认需求,再选方案。如果你只是偶尔连一次看一下图形界面,VNC 也能凑合;如果是长期日常使用,Windows 用户居多,Xrdp 无疑是最平滑的路线。它把 Linux 桌面和 Windows 生态无缝衔接,省掉了客户端部署的麻烦,还顺手解决了远程会话断线重连的痛点。
配置过程中如果遇到问题,顺着xrdp.log和xrdp-sesman.log这两个日志文件捋,九成以上的报错都能找到线索。别一上来就重装系统或者瞎改配置文件,先在日志里找到真正的原因,然后小步调整,问题自然迎刃而解。希望这篇文章能帮你少走点弯路,如果后面在项目上踩到更刁钻的坑,欢迎回来继续交流。