使用 Apache Guacamole 和 PopOS 搭建基于网页浏览器的无客户端远程桌面访问系统的完整指南。
概述
- Guacamole: 基于 Web 的远程桌面网关(HTML5,无需安装客户端软件)
- 目标系统: PopOS 配置 xrdp 服务器
- 访问方式: 任何设备通过浏览器访问
- 支持协议: RDP、VNC、SSH、Telnet、Kubernetes 连接
1. PopOS RDP 服务器配置
安装和配置 xrdp
# 安装 xrdp(比 GNOME 自带的远程桌面更稳定)
sudo apt update
sudo apt install xrdp
# 启动并设置开机自启
sudo systemctl enable xrdp
sudo systemctl start xrdp
# 验证服务状态
sudo systemctl status xrdp
解决 PolicyKit 权限问题
创建文件 /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
:
[Allow Colord All Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.*
ResultAny=no
ResultInactive=no
ResultActive=yes
[Allow PackageKit All Users]
Identity=unix-user:*
Action=org.freedesktop.packagekit.*
ResultAny=no
ResultInactive=no
ResultActive=yes
可选:防火墙配置
# 如果使用 Docker 和局域网 IP,通常不需要开放端口
# 只有需要外部访问时才开放
sudo ufw allow 3389
2. Guacamole Docker 配置
更新的 Docker Compose 配置
services:
guacdb:
container_name: guacamoledb
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'MariaDBRootPass2024'
MYSQL_DATABASE: 'guacamole_db'
MYSQL_USER: 'guacamole_user'
MYSQL_PASSWORD: 'MariaDBUserPass2024'
volumes:
- db-data:/var/lib/mysql
networks:
- guacamole-network
guacd:
container_name: guacd
image: guacamole/guacd:1.6.0
restart: unless-stopped
devices:
- /dev/snd:/dev/snd # 映射声音设备
networks:
- guacamole-network
guacamole:
container_name: guacamole
image: guacamole/guacamole:1.6.0
restart: unless-stopped
ports:
- "8080:8080"
environment:
GUAC_AUDIO: "audio/L16" # 改用更好的音频格式
GUAC_AUDIO_RATE: "44100" # 设置音频采样率
GUACD_HOSTNAME: "guacd"
MYSQL_HOSTNAME: "guacdb"
MYSQL_DATABASE: "guacamole_db"
MYSQL_USER: "guacamole_user"
MYSQL_PASSWORD: "MariaDBUserPass2024"
TOTP_ENABLED: "true"
WEBAPP_CONTEXT: "ROOT" # 允许直接通过 http://localhost:8080 访问
depends_on:
- guacdb
- guacd
networks:
- guacamole-network
networks:
guacamole-network:
driver: bridge
volumes:
db-data:
数据库初始化
# 1. 创建目录并设置
mkdir guacamole
cd guacamole
# 2. 生成数据库初始化文件
docker run --rm guacamole/guacamole:1.6.0 /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
# 3. 启动服务
docker-compose up -d
# 4. 等待数据库准备就绪
sleep 30
# 5. 导入数据库架构
docker exec -i guacamoledb mysql -u root -pMariaDBRootPass2024 guacamole_db < initdb.sql
# 6. 验证表已创建
docker exec -it guacamoledb mysql -u root -pMariaDBRootPass2024 -e "USE guacamole_db; SHOW TABLES;"
3. Guacamole 配置
初始设置
- 访问 Guacamole:
http://localhost:8080
(注意:没有 /guacamole 后缀!)
- 默认登录:
guacadmin
/ guacadmin
- 重要:立即更改默认密码
创建 RDP 连接
-
前往 设置 → 连接 → 新建连接
-
编辑连接:
- 名称:
PopOS 桌面
(或任意名称)
- 协议:
RDP
-
参数:
- 主机名:使用实际局域网 IP(例如:
192.168.1.100
)
- 端口:
3389
- 用户名:你的 PopOS 用户名
- 密码:你的 PopOS 密码
-
可选设置:
- 安全模式:
any
或 rdp
- 忽略服务器证书:✓(勾选)
- 禁用身份验证:✓(如果需要)
Guacamole 代理参数
- 通常保持空白(主机名、端口、加密字段)
- 只有在 guacd 运行在不同服务器时才需要配置
4. 关键网络配置说明
⚠️ Docker 网络注意事项
- 在连接主机名中使用 IP 地址,不要用域名
- 如果使用 Tailscale/VPN:使用物理网络 IP,不要用 VPN IP
- 容器 DNS 解析可能指向无法访问的网络
- Docker 可以通过局域网 IP 访问主机端口,无需防火墙规则
IP 地址查找示例
# 查找你的 PopOS IP
ip addr show | grep "inet 192"
# 在 Guacamole 连接中使用这个 IP,不要用 localhost 或域名
5. 测试
验证 RDP 服务
# 在 PopOS 上测试本地 RDP
telnet localhost 3389
测试 Guacamole 连接
- 登录 Guacamole Web 界面
- 点击你的连接
- 应该能在浏览器中看到 PopOS 桌面
故障排除
常见问题
- PolicyKit 密码提示:添加上述 polkit 配置
- 黑屏:在本地popOS上退出登录
调试命令
# 检查 xrdp 状态
sudo systemctl status xrdp
# 检查端口监听
sudo netstat -tlnp | grep 3389
# 检查 Guacamole 日志
docker logs guacamole
docker logs guacd
# 重启 PolicyKit(如果需要)
sudo systemctl restart polkitd
# 或者简单重启
sudo reboot
生产环境增强
Nginx 反向代理(可选)
添加 HTTPS 和自定义域名访问,支持 WebSocket:
server {
listen 443 ssl;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
access_log off;
}
}
性能说明
- 优秀适用场景:办公工作、编程、系统管理
- 良好适用场景:局域网内一般桌面使用
- 不适合场景:高帧率游戏、视频播放
- 最佳环境:低延迟的本地网络
支持的协议
- RDP:Windows/Linux 远程桌面
- VNC:跨平台图形界面访问
- SSH:终端访问和文件传输
- Telnet:传统终端协议
- Kubernetes:容器编排访问
安全考虑
- 更改 Guacamole 默认密码 (问题不大,有二次验证)
- 使用 HTTPS(添加反向代理)
实用价值
通过这个配置,你可以:
- 在任何地方用任何设备(手机、平板、电脑)通过浏览器访问你的桌面
- 统一的 Web 入口管理所有远程连接
- 无需在每个设备安装各种客户端软件
- 搭建个人的"云工作台"
本配置已经在 PopOS 22.04 上通过测试
主要参考来源:
A quick guide to set up clientless remote desktop access via web browser using Apache Guacamole and PopOS.
Overview
- Guacamole: Web-based remote desktop gateway (HTML5, no client software needed)
- Target: PopOS with xrdp server
- Access: Any device with a web browser
- Supports: RDP, VNC, SSH, Telnet, Kubernetes connections
1. PopOS RDP Server Setup
Install and Configure xrdp
# Install xrdp (more reliable than GNOME Remote Desktop)
sudo apt update
sudo apt install xrdp
# Start and enable service
sudo systemctl enable xrdp
sudo systemctl start xrdp
# Verify service
sudo systemctl status xrdp
sudo netstat -tlnp | grep 3389
Fix PolicyKit Permission Issues
Create /etc/polkit-1/localauthority/50-local.d/45-allow-colord.pkla
:
[Allow Colord All Users]
Identity=unix-user:*
Action=org.freedesktop.color-manager.*
ResultAny=no
ResultInactive=no
ResultActive=yes
[Allow PackageKit All Users]
Identity=unix-user:*
Action=org.freedesktop.packagekit.*
ResultAny=no
ResultInactive=no
ResultActive=yes
Optional: Firewall Configuration
# Usually NOT needed if using Docker with LAN IP
# Only open if external access required
sudo ufw allow 3389
2. Guacamole Docker Setup
Updated Docker Compose Configuration
services:
guacdb:
container_name: guacamoledb
image: mariadb:10.11
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 'MariaDBRootPass2024'
MYSQL_DATABASE: 'guacamole_db'
MYSQL_USER: 'guacamole_user'
MYSQL_PASSWORD: 'MariaDBUserPass2024'
volumes:
- db-data:/var/lib/mysql
networks:
- guacamole-network
guacd:
container_name: guacd
image: guacamole/guacd:1.6.0
restart: unless-stopped
networks:
- guacamole-network
guacamole:
container_name: guacamole
image: guacamole/guacamole:1.6.0
restart: unless-stopped
ports:
- "8080:8080"
environment:
GUACD_HOSTNAME: "guacd"
MYSQL_HOSTNAME: "guacdb"
MYSQL_DATABASE: "guacamole_db"
MYSQL_USER: "guacamole_user"
MYSQL_PASSWORD: "MariaDBUserPass2024"
TOTP_ENABLED: "true"
WEBAPP_CONTEXT: "ROOT" # Access via http://localhost:8080
depends_on:
- guacdb
- guacd
networks:
- guacamole-network
networks:
guacamole-network:
driver: bridge
volumes:
db-data:
Database Initialization (Correct Method)
# 1. Create directory and setup
mkdir guacamole
cd guacamole
# 2. Generate database initialization file
docker run --rm guacamole/guacamole:1.6.0 /opt/guacamole/bin/initdb.sh --mysql > initdb.sql
# 3. Start services
docker-compose up -d
# 4. Wait for database to be ready
sleep 30
# 5. Import database schema (no docker cp needed!)
docker exec -i guacamoledb mysql -u root -pMariaDBRootPass2024 guacamole_db < initdb.sql
# 6. Verify tables created
docker exec -it guacamoledb mysql -u root -pMariaDBRootPass2024 -e "USE guacamole_db; SHOW TABLES;"
3. Guacamole Configuration
Initial Setup
- Access Guacamole:
http://localhost:8080
(note: no /guacamole suffix!)
- Default login:
guacadmin
/ guacadmin
- Important: Change default password immediately
Create RDP Connection
-
Go to Settings → Connections → New Connection
-
Edit Connection:
- Name:
PopOS Desktop
(or any name)
- Protocol:
RDP
-
Parameters:
- Hostname: Use actual LAN IP (e.g.,
192.168.1.100
)
- Port:
3389
- Username: Your PopOS username
- Password: Your PopOS password
-
Optional Settings:
- Security mode:
any
or rdp
- Ignore server certificate: ✓ (check)
- Disable authentication: ✓ (if needed)
Guacamole Proxy Parameters
- Usually leave empty (Hostname, Port, Encryption fields)
- Only configure if guacd runs on different server
4. Critical Network Configuration Notes
⚠️ Docker Networking Gotchas
- Use IP addresses, not domain names in connection hostname
- If using Tailscale/VPN: Use physical network IP, not VPN IP
- Container DNS resolution may point to unreachable networks
- Docker can access host ports via LAN IP without firewall rules
Example IP Discovery
# Find your PopOS IP
ip addr show | grep "inet 192"
# Use this IP in Guacamole connection, not localhost or domain names
5. Testing
Verify RDP Service
# On PopOS, test local RDP
telnet localhost 3389
Test Guacamole Connection
- Login to Guacamole web interface
- Click your connection
- Should see PopOS desktop in browser
Troubleshooting
Common Issues
- "Non-numeric character in element length": Version mismatch or network issue
- "Connection refused": Check xrdp service and firewall
- PolicyKit password prompts: Add polkit configuration above
- Black screen: Try different security mode settings
- Slow performance: Normal on high-latency networks, excellent on LAN
Debug Commands
# Check xrdp status
sudo systemctl status xrdp
# Check port listening
sudo netstat -tlnp | grep 3389
# Check Guacamole logs
docker logs guacamole
docker logs guacd
# Restart PolicyKit (if needed)
sudo systemctl restart polkitd
# Or simply reboot
sudo reboot
Production Enhancements
Nginx Reverse Proxy (Optional)
Add HTTPS and custom domain access:
server {
listen 443 ssl;
server_name your-domain.com;
location / {
proxy_pass http://localhost:8080;
proxy_buffering off;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
access_log off;
}
}
Performance Notes
- Excellent for: Office work, programming, system administration
- Good for: General desktop use on LAN
- Not ideal for: High-framerate gaming, video streaming
- Best on: Local network with low latency
Supported Protocols
- RDP: Windows/Linux remote desktop
- VNC: Cross-platform graphical access
- SSH: Terminal access with file transfer
- Telnet: Legacy terminal protocol
- Kubernetes: Container orchestration access
Security Considerations
- Change default Guacamole passwords
- Use HTTPS in production (add reverse proxy)
- Consider VPN access for external connections
- Regularly update Docker images
- PolicyKit configuration limits privilege escalation
Setup tested on PopOS 22.04 with Guacamole 1.6.0 via Docker
Key Sources:
很多人不喜欢web app是因为要先打开浏览器再输入相应的网址,然而这一繁琐步骤是可以免去的,你完全可以像使用原生app一样使用web app。
我个人更喜欢web app,因此特意在这里告诉潜在的HappyNotes用户,只需几秒钟,你就能将它固定在手机桌面上,不论看起来还是用起来都像一个真正的移动App。
为什么 Webapp 如此棒
在介绍安装步骤前,我先啰嗦几句为什么 webapp 很酷:
- 你永远在使用最新版本,无需手动更新
- 体积小得令人惊讶
- 跨设备使用,随时随地
- 不受应用商店审核限制
iPhone 用户安装指南 📱
- 在 Safari 浏览器中打开 HappyNotes, 网址 https://happynotes.shukebeta.com
- 点击分享按钮(带箭头的方形图标)
- 向下滚动,选择"添加到主屏幕"
- 给它起个喜欢的名字(比如"HappyNotes")
- 点击"添加" - 大功告成!
Android 用户安装指南 🤖
- 打开 Chrome 浏览器,进入 HappyNotes, 网址 https://happynotes.shukebeta.com
- 点击菜单(三个点)或查找"+"图标
- 选择"添加到主屏幕"
- 为快捷方式命名
- 点击"添加" - 搞定!
现在,你可以直接从主屏幕点击 HappyNotes。随时随地,记你想记!
Ever wanted to use HappyNotes but thought it seemed complicated? This guide helps you add this webapp to your phone's home screen in just a few seconds, making it feel just like a native app!
Why Webapps Are Actually Amazing
Before we dive into installation, let me share why webapps like HappyNotes are fantastic:
- Always use the latest version automatically
- Zero download size (no massive app store downloads!)
- Work across all devices
For iPhone Users 📱
- Open HappyNotes in Safari
- Tap the share button (square with an arrow pointing up)
- Scroll and select "Add to Home Screen"
- Name it as you like (e.g., "HappyNotes")
- Tap "Add" - done!
For Android Users 🤖
- Open Chrome and navigate to HappyNotes
- Tap the menu (three dots) or look for a "+" icon
- Choose "Add to Home Screen"
- Name your shortcut
- Tap "Add" - you're all set!
Pro tip: The icon will look just like a regular app icon. Your friends won't even know the difference! 😉
Now you can tap HappyNotes directly from your home screen, just like any other app. Enjoy seamless, always-updated note-taking wherever you go!
我有一台老旧的 Asus C100P Chromebook,Google早在几年前就停止了对它的支持。它是32位ARM CPU,因此我没法替它更换BIOS,但我可以在developer mode下启用优盘启动,这样我就能够在优盘或者sd卡运行Linux。
然而,在使用 SD 卡或其他闪存设备作为操作系统存储时,合理管理写入操作至关重要。本文将介绍如何通过使用 tmpfs 文件系统、关闭 atime 来延长设备的使用寿命。
1. 使用 tmpfs
什么是 tmpfs?
tmpfs 是一种基于内存的临时文件系统,具有以下优点:
- 高速存储: 数据存储在内存中,读写速度极快。
- 动态大小: 根据实际使用情况动态分配内存,不会固定占用资源。
- 减少写入: 适合存储临时文件和日志,显著减少对闪存的写入操作。
如何配置 tmpfs
1.1 编辑 /etc/fstab 文件
打开终端并输入:
sudo nano /etc/fstab
添加以下行以创建 tmpfs 挂载点:
tmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0
tmpfs /var/log tmpfs defaults,noatime,mode=0755 0 0
1.2 挂载 tmpfs
保存文件后,运行以下命令使更改生效:
sudo mount -a
1.3 验证挂载
使用以下命令确认 tmpfs 是否成功挂载:
df -h
您应该能看到类似于 /tmp
和 /var/log
的 tmpfs 挂载点。
1.4 设置自动复制日志到 tmpfs
为了在系统启动时自动将日志复制到 tmpfs,我们需要修改 /etc/rc.local 文件:
a. 创建一个目录来存储持久化的日志:
sudo mkdir -p /var/log.hdd
sudo cp -a /var/log/* /var/log.hdd/
b. 编辑 /etc/rc.local 文件:
sudo nano /etc/rc.local
c. 在文件中添加以下内容:
#!/bin/sh -e
# 复制日志文件到 tmpfs
cp -a /var/log.hdd/* /var/log/
exit 0
d. 确保 rc.local 文件具有执行权限:
sudo chmod +x /etc/rc.local
2. 关闭 atime
atime (访问时间) 是文件系统的一个属性,每次访问文件时都会更新。关闭 atime 可以减少不必要的写入操作,从而延长 SD 卡的寿命。
如何关闭 atime
2.1 编辑 /etc/fstab 文件
打开 /etc/fstab 文件:
sudo nano /etc/fstab
2.2 修改挂载选项
找到 SD 卡对应的挂载项(通常是根分区 /),在挂载选项中添加 noatime
:
UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx / ext4 defaults,noatime 0 1
2.3 重新挂载文件系统
保存文件后,使用以下命令重新挂载文件系统:
sudo mount -o remount /
请记住,虽然这些方法可以有效延长 SD 卡的使用寿命,但仍然建议定期备份重要数据,以防意外发生。毕竟备份不做,十恶不赦!
又:
mode=1777
中的 1 表示设置了"粘滞位"(sticky bit)。具体含义如下:
-
777 部分:
- 7: 所有者(owner)有读、写、执行权限
- 7: 用户组(group)有读、写、执行权限
- 7: 其他用户(others)有读、写、执行权限
-
前面的 1:
粘滞位的作用:
- 对于目录,当设置了粘滞位时,只有文件的所有者、目录的所有者或 root 用户才能删除或重命名该目录中的文件。
- 这通常用于像 /tmp 这样的公共目录,允许所有用户创建文件,但防止用户删除或修改其他用户的文件。
所以 mode=1777 的含义是:
- 所有用户都可以在该目录中创建、读取和执行文件(777)
- 但只有文件所有者和目录所有者可以删除或重命名文件(1)
这种权限设置既保证了目录的共享性,又提供了一定的安全保护,防止用户互相干扰。