分类目录归档:System Maintenance

WSL SSH 登录

仅做记录。

Step 1:在 WSL 中重新安装 OpenSSH

sudo dpkg-reconfigure openssh-server

Step 2:修改 /etc/ssh/sshd_config,将 Port 改为一个 1024 以上的值,如果没有配置密钥的话,允许密码登录

Step 3:重启 SSH 服务

sudo service ssh --full-restart

这样就可以从另一台 PC 上登录进本机的 WSL 了,VSCode Remote 之类的也都能正常运行。

使用 Docker 快速架设一个 IPSec VPN Server

仅作记录使用,环境为 Ubuntu 18.04 LTS

Docker Image 来自 hwdsl2/docker-ipsec-vpn-server

# Install docker
apt update
apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt update
apt install docker-ce docker-ce-cli containerd.io

# Pull the docker image
docker pull hwdsl2/ipsec-vpn-server

之后创建一个 env 文件规定 IPSec 使用的 PSK、用户名和密码,假设存储在 /home/user/.config/vpn.env

# Define your own values for these variables
# - DO NOT put "" or '' around values, or add space around =
# - DO NOT use these special characters within values: \ " '
VPN_IPSEC_PSK=your_ipsec_pre_shared_key
VPN_USER=your_vpn_username
VPN_PASSWORD=your_vpn_password

# (*Optional*) Define additional VPN users
# - Uncomment and replace with your own values
# - DO NOT put "" or '' around values, or add space around =
# - Usernames and passwords must be separated by spaces
# VPN_ADDL_USERS=additional_username_1 additional_username_2
# VPN_ADDL_PASSWORDS=additional_password_1 additional_password_2

# (*Optional*) Use alternative DNS servers
# - Uncomment and replace with your own values
# - By default, clients are set to use Google Public DNS
# - Example below shows Cloudflare's DNS service
# VPN_DNS_SRV1=1.1.1.1
# VPN_DNS_SRV2=1.0.0.1

# (*Optional*) Advanced users can set up IKEv2. See:
# https://git.io/ikev2docker

使用 systemd 开机自启动,假设文件在 /etc/systemd/system/ipsec.service:

[Unit]
Description=IPSec Docker
After=docker.service
Requires=docker.service

[Service]
User=root
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/usr/bin/docker stop ipsec-vpn-server
ExecStartPre=-/usr/bin/docker rm ipsec-vpn-server
ExecStart=/usr/bin/docker run --name ipsec-vpn-server --env-file /home/user/.config/vpn.env --restart=always -p 500:500/udp -p 4500:4500/udp -d --privileged hwdsl2/ipsec-vpn-server
ExecStop=/usr/bin/docker stop ipsec-vpn-server
ExecStopPost=/usr/bin/docker rm ipsec-vpn-server

[Install]
WantedBy=multi-user.target

之后使用 docker logs ipsec-vpn-server 就能看到本次使用的登录凭据。

Xfinity Gateway 桥接模式使用

给手上的 RT-ACRH17 刷了梅林,然后实在是看那个 Double-NAT 不爽,打算把 Xfinity 的那个 modem 改成桥接模式。折腾一番之后终于搞定了,这里记录下几个问题。

我这个 modem 是 ARRIS TG1682G,型号是 XB3,调成桥接模式只要按照 Xfinity 的文档操作即可,调整完以后理论上只有 LAN1 可用,用一根网线从 modem 的 LAN1 直接接到 PC 上,看下通不通,如果通的话,说明 modem 本身没有问题,然后记录下 PC 有线网卡的 MAC 地址。

之后进入 RT-ACRH17 的设置界面,按照下图调整:

这里 DNS 我用的是 CloudFlare 的 public DNS,也可以换成例如 Google DNS 之类,这个无所谓。重点在于,在 ISP 特殊要求下,将 MAC 地址一栏中填入刚刚记下的 PC 有线网卡 MAC 地址,然后将 DHCP 查询频率改成普通。似乎 Xfinity 那里会限制这个 MAC 地址,如果不做克隆的话会无法完成 DHCP。也就是说,垃圾 Comcast 实际上是限制你用自己的无线路由的。

然后是 IPv6 的配置:

如果没有将 modem 改为桥接模式的话,这里类型应该选 Passthrough,在本文的场景下,应选择 Native,其他选项按照图内配置。同样的,这里的 DNS 我用的是 CloudFlare 的 DNS,可以改成其他你喜欢的地址。

稍等一段时间这里会出现一个 /64 的 prefix,说明配置成功。这里响应稍微有些慢,在 IPv4 上线以后可能还要两三分钟这里才会出现,是正常情况,等一下就好。

然后就结束了,重点就在于 MAC 地址要克隆 PC 的有线网卡地址,不然服务端会做一些奇怪的限制导致 DHCP 失败连不上网。

关于 VSCode SSH 插件出现 flock: 99: Input/output error 的解决方案

VSCode 的 SSH 插件默认会在 ~/.vscode-server 下获取 lock,但是在某些 home 目录挂载在 NFS 的服务器上会出现 > flock: 99: Input/output error 的错误。

解决方案是在 /tmp 下获取 lock,在 SSH 插件的设置中选中 LockFiles In Temp 即可,或者搜索 remote.SSH.lockfilesInTmp 也可以找到这个设置。

在 Linux 下使用 Office 365

在 Windows 上用习惯了微软全家桶,切到 Linux 就没指望了,又不能说装个 Windows 虚拟机就为了用 Office 365,那只好尝试找找替代品了。

首先是 Outlook,包含了学校账户的 Exchange ActiveSync,个人 Outlook 邮箱还有日程功能。在 Linux 上比较常见的邮件客户端是 Mozilla Thunderbird,通过插件配置可以最低限度地支持 Outlook 提供的一些服务。

  • owl for exchange 提供 Exchange ActiveSync 的邮件支持
  • lightning 提供 Outlook 日历的基础功能支持
  • tbsync + provider for exchange activesync 提供到 Office 365 账户的日历同步功能
  • provider for google calendar 为 lightning 提供到 Google Calendar 的同步功能

有了这些插件以后,就可以依次添加自己的账户开始同步了。不能说多好用,勉强能用吧。

然后是 Microsoft To-Do,这个有好事者开发了一个跨平台的版本:klaussinani/ao。通过 snap 就可以安装。

还有 OneNote,这个似乎除了网页版就没有什么比较好用的版本,不过也有好事者用 Electron 做了一个本地网页客户端:patrikx3/onenote。还算能用,也是通过 snap 安装。

OneDrive 的同步,也有好事者写了 Linux 上可用的版本:skilion/onedrive。这个要写一下正确的安装流程,我装的时候差点就把 OneDrive 里面的文件全部删掉了,幸好有回收站。

对于 Ubuntu 18.04,安装流程是这样的:

sudo apt install libcurl4-openssl-dev
sudo apt install libsqlite3-dev

# Ubuntu 18
sudo snap install --classic dmd && sudo snap install --classic dub

git clone https://github.com/skilion/onedrive.git
cd onedrive
make
sudo make install

注意,在运行之前,一定是在运行之前,自行在 ~/.config 下创建配置文件目录,以 ~/.config/onedrive 为例,如果需要同步多个账户则应使用不同的目录名称:

mkdir -p ~/.config/onedrive
cp ./config ~/.config/onedrive/config
nano ~/.config/onedrive/config

config 文件结构类似这样:

# Directory where the files will be synced
sync_dir = "~/OneDrive"
# Skip files and directories that match this pattern
skip_file = ".*|~*"

标记了默认的同步路径为 ~/OneDrive,由于在首次运行 onedrive 的时候默认就是授权,因此如果要更改同步目录的话,在这里要先在配置文件里面写好。然后运行 onedrive –confdir=”~/.config/onedrive” 开始进行授权操作,这样就会在 sync_dir 处创建对应的文件夹,然后开始下载。

如果要自动同步,在 make install 之后,在 /usr/lib/systemd/user 下已经被创建了一个 onedrive.service 文件,类似这样:

[Unit]
Description=OneDrive Free Client
Documentation=https://github.com/skilion/onedrive

[Service]
ExecStart=/usr/local/bin/onedrive -m
Restart=no

[Install]
WantedBy=default.target

如果想要同步多个账户的话,把 ExecStart 改成类似于 onedrive -m –confdir=”~/.config/onedrivePersonal” 这样带有配置文件目录的形式。之后:

systemctl --user enable onedrive
systemctl --user start onedrive

就可以启动服务自动运行了。

如果不想使用 User Service,希望在系统启动时运行,则在 /etc/systemd/system 下创建 onedrive.service,写入类似于:

[Unit]
Description=OneDrive Free Client
Documentation=https://github.com/skilion/onedrive

[Service]
ExecStart=/usr/bin/sudo -u <user> /usr/local/bin/onedrive -m --confdir="/home/<user>/.config/onedrive"
Restart=always

[Install]
WantedBy=default.target

之后:

systemctl enable onedrive
systemctl start onedrive

切记,不能在授权完成之后,复制 config 文件并更改 sync_dir,然后直接用 -m 参数运行 onedrive,这样会使得该程序认为本地有全部删除的更改,会直接删掉 OneDrive 上所有文件。所以一定要先写配置文件再授权。

最后记录一下添加 SMB 打印机的过程,Linux 通过 CUPS 管理打印机,但是图形界面的管理未必好用,可以尝试用 localhost:631 来管理,注意 cups-2.2.7 在 Linux 版 Chrome 上有 bug,会出现 unauthorized error,这个需要升级到 2.2.8 或者使用 firefox。具体配置可以看 Arch Wiki

在物理机上全新安装 Ubuntu 的一些坑

起因是这样的,老板表示都搞 Research 了,日常使用就用 Ubuntu 吧……然后就在一台 Dell Optiplex 5060 上装起了 Ubuntu。

这台机器本身没有 SSD,IT 搬过来的时候系统就装在一块 500G/7200rpm 的海门酷鱼上(ST500LM034)。9102 年了,我用 SSD 装系统都用了 7 年了,没有 SSD 的机器完全没法用,遂购入一块 NVMe SSD 插在了 M.2 接口上,然后插入 xubuntu 安装 U 盘开始重装。

这时候问题来了,尽管在 BIOS 里能看到,但是 Ubuntu 死活检测不到那块 NVMe。经多处查询,发现可以尝试在 BIOS 中把默认的 SATA 模式改成 AHCI,而不是 RAID,改过来以后,就没问题了。此处要吐槽一下 Dell 知识库,里面写的完全是反的,表示应该把 AHCI 模式改成 RAID,我信你就有鬼了。

安装流程很快完成以后,又出现了另外一个问题,xubuntu 18.04.3 已经默认使用了 HWE Kernel,在尝试安装 openssh-server 的时候,表示有部分依赖无法满足。之前遇到这个问题的时候,尝试过 aptitude,给出的方案之一是降级大量的软件包,但是这样之后把系统的包搞得一团糟,apt 已经完全无法正常使用。考虑到默认使用的是 HWE kernel,在 aptitude 降级的时候也出现过卸载带 hwe 后缀的软件包,安装不带 hwe 后缀的软件包的操作,因此怀疑是软件源的问题。

于是在这里生成新的软件源列表,注意勾选 main restricted universe multiverse、security updates 和 backports 这些,生成链接之后,复制到 /etc/apt/sources.list 中。在 apt udpate 之后,发现整个系统终于能正常工作了。现在看来,ubuntu 18.04 使用 HWE Kernel 的版本在默认的软件源列表上是有坑的,似乎是 bionic-updates 没有被包含在其中,造成软件包版本混乱的问题。

在解决了这些问题之后,似乎至少能正常使用了。

iKoula 独服在 netplan.io 下配置 IPv6

netplan.io 实在是太烂了

假设 IPv4 地址是 AAA.BBB.CCC.DDD,修改 /etc/netplan/01-netcfg.yaml

# Network configuration file
# Auto generated by Ikoula

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      dhcp4: no
      addresses: 
        - AAA.BBB.CCC.DDD/24
        - "2a00:c70:1:AAA:BBB:CCC:DDD:1/96"
      gateway4: AAA.BBB.CCC.1
      gateway6: 2a00:c70:1:AAA:BBB:CCC::1
      nameservers:
        addresses: [213.246.36.14,213.246.33.144,80.93.83.11]

之后 netplan try 验证格式并回车应用,或者直接 netplan apply

WordPress 迁移

从……大概一年多以前?Offline 要涨价开始,我就说要抛弃他家 Scaleway,转到 Hetzner Cloud 上来,然而因为懒……所以就一直没弄。今天突发奇想就弄了一下。

WordPress 迁移的方法有很多,可以考虑底层的方法把网站目录、数据库和 nginx 配置文件连锅端,也可以用一些插件辅助完成这个事情。出于懒……我个人选择了插件。

在这个迁移中使用的是 All-in-One WP Migration 插件,其作者声称可以直接打包把站点导出,包含所有的文章、主题以及插件信息。为了测试该插件能否正常工作,我首先使用了另一个二级域名并安装 WordPress 作为测试平台,很顺利地完成了导入以后,就开始了主域名的迁移工作。

由于我的环境是 Oneinstack 的 LNMP 一件包,其 vhost 管理并没有提供相应的更改域名功能,在阅读了代码之后,发现其功能似乎是 stateless 的,也就是说包括 vhost 列表的查询以及 Let’s encrypt 证书管理在内都通过读取对应应用程序的配置文件完成,而非本地再对已有的域名进行配置文件的保存。这样的设计为我之后要干的事情提供了极大的方便,即手动更改本地域名地址之后,只要不变动文件夹结构,就不会影响该脚本的后续使用。

迁移这个简单的 WordPress 站点(没什么特殊配置,都在 WP 框架内完成,因此使用迁移插件即可),需要做的有这样几件事:

  • 导出原站点
  • 在新 VPS 上建立 vhost,并申请 Let’s encrypt 证书
  • 安装 WordPress
  • 导入原站点

需要注意的一点是,如果需要在 vhost 中更改域名,一定要在安装 WordPress 之前完成,因为 WordPress 似乎根据安装时保存在 MySQL 数据库中的网址自行进行 301 跳转,即使更改了 nginx 中的网址,Wordpress 仍然会在后续访问中跳转会原来的地址,进而会导致 https 证书地址不匹配的问题。

这个问题最开始是在完成了使用测试域名的导入以后,想更换为原来的主域名时发生的。在使用 acme.sh 生成证书并安装,且完成 nginx config 中的证书路径修改之后:

acme.sh --issue -d <domain> --webroot <web_root_dir>
acme-sh --install-cert -d <domain> --key-file /usr/local/nginx/conf/ssl/<domain>.key --fullchain-file /usr/local/nginx/conf/ssl/<domain>.crt --reloadcmd  "service nginx force-reload"

在访问原网址时仍然会跳转到之前使用的测试网址,这让我百思不得其解。在删除网站根目录下的所有文件,重新生成证书以及 vhost 配置文件等方法均无果之后,我使用了使用 curl -I 查看调试信息:

# curl -I https://blog.gloriousdays.pw
HTTP/2 301
server: nginx
date: Sun, 25 Aug 2019 16:36:56 GMT
content-type: text/html; charset=UTF-8
location: https://blog2.gloriousdays.pw/
x-redirect-by: WordPress
strict-transport-security: max-age=15768000

可以看到似乎是由 WordPress 完成的 301 跳转。与之相对的正常访问和 nginx 完成的 301 跳转是这样:

# curl -I https://blog.gloriousdays.pw
HTTP/2 200
server: nginx
date: Sun, 25 Aug 2019 17:46:59 GMT
content-type: text/html; charset=UTF-8
content-length: 41183
vary: Accept-Encoding
vary: Accept-Encoding, Cookie
cache-control: max-age=3, must-revalidate
last-modified: Sun, 25 Aug 2019 17:34:44 GMT
strict-transport-security: max-age=15768000

# curl -I http://blog.gloriousdays.pw
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Sun, 25 Aug 2019 17:47:03 GMT
Content-Type: text/html
Content-Length: 162
Connection: keep-alive
Location: https://blog.gloriousdays.pw/
Strict-Transport-Security: max-age=15768000

这样似乎就定位了问题所在,Wordpress 在某个地方存储了网站的地址,并且依照其进行跳转。后来想到,在进行网站测试导入时,已经完成了 WordPress 安装并连接了数据库,在之前删除网站目录文件重新放入 WordPress 安装包的时候也没有进行清除,或许那个数据库才是问题所在。于是果断进入 mysql 命令行 drop database,并重新进行安装和导入站点流程,这时候网站就已经正常工作了。

总结一下的话,就是在安装 WordPress 之后一定不要更改 nginx 对应的域名,说实话这也很奇怪,301 跳转这个功能委托给 nginx 完成就好,WP 何必多此一举呢。