分类
linux

在 Fedora 34 上启动 VNC DISPLAY

大家可以先阅读 使用 Node.js 驱动 FFmpeg 在 Linux + vncserver 下完成视频录制 了解产品目标和技术选型。

前两天在系统更新里看到 Fedora 34 发布,作为更新党,我当然迫不及待就升级了。升级过程蛮顺利的,升级后,系统里的“在线账户”也能正常走 VPN 了,感觉还蛮好的。

然后,前两天需要调试录视频的程序,发现新系统的 tigerVNC 有一个巨大的变化:不再支持用 vncserver 命令创建虚拟显示器,必须用 systemctl start service,目的是方便绑定系统启动,因为很多服务器的运维需要自动化。

不过这可苦了我。我是系统运维菜鸡,基本只能照抄文章,搞了半天也没搞好。不过感谢开源,在 GitHub issue 里讨论的只言片语让我知道了其实 vncserver 是个脚本,它调用的其实是 Xvnc 这个命令。

那就好办了,我开始按图索骥,寻找 vncserverXvnc 之间的关联。最终找到解决方法如下:

  1. 修改 /etc/X11/Xwrapper.config,加入 allowed_users=anybody。这样才能直接使用 Xvnc 创建虚拟显示器,不然会报告只有 console 用户才能创建的错误。
  2. 使用 vncpasswd 命令创建密码文件,创建后的密码文件位于 ~/.vnc/passwd
  3. 然后用 Xvnc :5 -geometry 1280x720 -PasswordFile ~/.vnc/passwd 创建显示器,跟之前的命令很类似,不过需要 -PasswordFile 选项指定密码
  4. 使用 VNC viewer 登录 VNC,输入密码。(我不知道这一步是否必须)
  5. 可以继续使用 DISPLAY=:5

不过问题并没有完美解决,虽然我的 puppeteer JS 能跑,FFmpeg 也能录。但是 DISPLAY=:5 firefox https://cn.bing.com 只会在当前屏幕打开窗口,不知道为什么。留待以后解决吧。

最后吐槽下,这种稳定版里换大版本的行为真的要不得,开源团队也不能滥用自己的地位。


参考阅读

分类
linux

Linux 命令行科学上网

前些天因为工作需要,装了 Fedora 33 开发 Showman 的视频录制功能。准备顺势双机工作一段时间,自然也就需要给新系统配置好科学上网。这里简单记录一下过程,方便日后回查。

0. 更新系统

第一部当然是更新系统,保证系统组件均为最新版,这样可以规避大多数问题。

sudo dnf update

1. 使用 pip 安装 shadowsocks 客户端

Fedora 33 自带 python 3.9,所以直接使用 pip 安装 shadowsocks 客户端即可:

sudo pip install shadowsocks

这里可以用 sudo 也可以不用,差别就在于,sudo 之后会将执行脚本安装到 /usr/local/bin;而不带 sudo 则会安装到 ~/.local/bin。两者的执行环境不一样。我无意间使用了后者,所以后面也会按照后者来记录。

2. 配置客户端

接下来编辑配置文件,如果是图形界面,建议使用 IDE,纯命令行的话用 vim 也可以。配置文件一般放在 /etc/shadowsocks.json。内容大概如下,顾名思义,我就不一一解释了:

{
  "server":"server-ip",
  "server_port":8000,
  "local_address": "127.0.0.1",
  "local_port":1080,
  "password":"your-password",
  "timeout":600,
  "method":"aes-256-cfb"
}

与前面 Ubuntu 20.04 科学上网 一样,本文不打算介绍服务器的制备——其实我也不建议大家自己制备服务器,除非你本来就有一些资源或者需求。不然的话,以我的经验,比较出名的迷你 VPS(类似 Vultr,DO,$5/月甚至 $2.5/月),IP 大部分都在规则库里,流量大一点,比如看个视频,不出半个小时 IP 就被封了,然后一个月后解封,基本没法用。

如果你是 macOS 或者 iPhone,或者其它可以用 anyconnect 的系统,可以考虑直接买现成的,比如链接里这个

3. 配置系统代理

然后启动服务:

sslocal -c /etc/shadowsocks.json -d start
  • -c 用来指定配置文件的地址
  • -d 表示启动服务

这里可能会遇到几个问题(也是上次我放弃命令行转投 qt5 客户端的原因)。我们来逐个解决它们:

3.1 openssl 错误

执行后报错:

$ sslocal -c /etc/shadowsocks.json -d start
INFO: loading config from /etc/shadowsocks.json
 2021-05-05 15:17:00 INFO     loading libcrypto from /root/anaconda3/lib/libcrypto.so.1.1
 Traceback (most recent call last):
   File "/root/anaconda3/bin/sslocal", line 8, in <module>
     sys.exit(main())
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/local.py", line 39, in main
     config = shell.get_config(True)
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/shell.py", line 262, in get_config
     check_config(config, is_local)
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/shell.py", line 124, in check_config
     encrypt.try_cipher(config['password'], config['method'])
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/encrypt.py", line 44, in try_cipher
     Encryptor(key, method)
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/encrypt.py", line 82, in __init__
     self.cipher = self.get_cipher(key, method, 1,
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/encrypt.py", line 109, in get_cipher
     return m[2](method, key, iv, op)
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/crypto/openssl.py", line 76, in __init__
     load_openssl()
   File "/root/anaconda3/lib/python3.9/site-packages/shadowsocks/crypto/openssl.py", line 52, in load_openssl
     libcrypto.EVP_CIPHER_CTX_cleanup.argtypes = (c_void_p,)
   File "/root/anaconda3/lib/python3.9/ctypes/__init__.py", line 395, in __getattr__
     func = self.__getitem__(name)
   File "/root/anaconda3/lib/python3.9/ctypes/__init__.py", line 400, in __getitem__
     func = self._FuncPtr((name_or_ordinal, self))
 AttributeError: /root/anaconda3/lib/python3.9/lib-dynload/../../libcrypto.so.1.1: undefined symbol: EVP_CIPHER_CTX_cleanup

其中文件、行号可能有所不同,不过错误内容大多一致。

这是因为 OpenSSL 升级至 1.1.0 以上后,内部 API 有一些变化,废弃了 EVP_CIPHER_CTX_cleanup() 函数而引入了 EVE_CIPHER_CTX_reset(),shadowsocks 客户端处于无人维护的状态,没有适配这些变化。

好在修复方案并不复杂,我们只需要修改文件 ~/.local/lib/python3.9/site-packages/shadowsocks/crypto/openssl.py,将里面的 cleanup 都替换成 reset 即可。

3.2 permission denied /var/run/shadowsocks.pid

前面写过,因为我安装的时候没使用 sudo,所以把客户端装在当前用户的目录里。于是面临一个矛盾:

  1. 直接使用当前用户启动客户端,会报告标题里的错误
  2. 使用 root 即 sudo 启动客户端,会报告库有错误(即 3.1),因为我修改的是当前用户的本地库

这里有两个解决方案,一是手动创建 pid,然后修改权限:

sudo touch /var/run/shadowsocks.pid
sudo chmod 777 /var/run/shadowsocks.pid

这个方法重启后会失效,还得再跑一遍。所以我比较推荐另一种做法:使用 sudo -u $user -i 的方式,sudo 的同时仍然使用当前用户的环境(这个方案实测失败了,还要再研究下):

sudo -u meathill -i sslocal -c /etc/shadowsocks.pid -d start

4. 加入自动启动

上一步测试成功之后就可以把这段代码加入 /etc/rc.local,以便实现开机自动启动。

5. 其它步骤

接下来,需要配置 pac 文件、文件服务和系统代理,可以完全参考 Ubuntu 20.04 科学上网 一文。

其中下载 gfwlist.txt 时,如果访问不到 https://raw.githubusercontent.com/gfwlist/gfwlist/master/gfwlist.txt,可以试着修改 /etc/hosts,加入下一行:

199.232.28.133 raw.githubusercontent.com

完成剩余步骤后,配置成功。


在 macOS/iOS 设备上使用科学上网有更简单的方法,扫码可得: