N6000 迷你主机配置记录(软件篇)

N6000 迷你主机配置记录(软件篇)

RayAlto OP

1. I use Arch, btw

当然要装 ArchLinux 了,软件包可以参考一下:

robot sticker: nerd
  1. 一个能跑起来的 Linux:
1
base grub intel-ucode linux-zen $(pacman -Ssq linux-firmware)

$() 这种是为了方便,不用写全包名,比如 $(pacman -Ssq linux-firmware) 会输出所有包含 linux-firmware 的包,每行一个,安装时可以像这样:

1
pacman -S $(pacman -Ssq adobe-source) $(pacman -Ssq noto-fonts) --needed
  1. 一个更能跑起来的 Linux:
1
arch-install-scripts bluez-utils brightnessctl chntpw efibootmgr evtest gnu-netcat moreutils os-prober pacman-contrib usbutils v4l2loopback-dkms
  1. 视频相关:
1
glfw-wayland intel-gpu-tools intel-media-driver libva libva-mesa-driver mesa mesa-utils vdpauinfo vulkan-intel vulkan-tools
  1. 音频相关:
1
alsa-utils pipewire pipewire-alsa pipewire-jack pipewire-pulse pipewire-zeroconf
  1. 网络相关:
1
bind cifs-utils dhcpcd hostapd ifplugd inetutils iwd netctl openresolv openssh rsync sshfs traceroute websocat wireless-regdb wpa_supplicant

这里 openresolvnetctl 的必须依赖,这里写出来的原因是用 pacstrap 装软件遇到必须依赖有多个可选项时会自动安装第一个,这里 netctl 依赖 resolvconf ,可选的有 systemd-resolvconfopenresolvpacstrap 会自动安装 systemd-resolvconf ,这个 systemd-resolvconf 很难用,理论上开箱即用的东西处在一个薛定谔的可用状态,尤其是配置静态 IP 的时候,换成 openresolv 可以解决这个问题。

  1. 桌面环境:
1
bemenu-wayland blueman kvantum kvantum-theme-materia lxappearance lxsession-gtk3 mako materia-gtk-theme pamixer papirus-icon-theme pavucontrol pcmanfm-gtk3 polkit qt5-wayland qt5ct qt6-wayland slurp sway swaybg swayidle swaylock waybar wayvnc wf-recorder wl-clipboard xcursor-vanilla-dmz-aa xdg-desktop-portal xdg-desktop-portal-wlr xdg-user-dirs xorg-xev xorg-xeyes xorg-xwayland
  1. 开发相关:
1
base-devel bear clang cmake docker gdb git go gperf gtkmm-4.0 imagemagick jdk-openjdk jdk17-openjdk jq jupyterlab libvirt libwebsockets libzip man-db man-pages neovim nginx nodejs npm opencv python-beautifulsoup4 python-jupyter-server-terminals python-matplotlib python-opencv python-pylint python-pymupdf python-pynvim python-requests qemu rust rust-analyzer texinfo texlive-bin tldr tmux valgrind virt-manager yapf yarn zsh zsh-autosuggestions zsh-completions zsh-history-substring-search zsh-syntax-highlighting zxing-cpp
  1. 日常工具:
1
aria2 atril fcitx5-im ffmpeg firefox gameconqueror gamescope gimp gnome-terminal gparted grim htop imv inkscape kdenlive kitty krita mpv ncdu neofetch obs-studio p7zip perl-image-exiftool qrencode ranger retroarch samba steam thunderbird tree unrar unzip wget yt-dlp zbar zip
  1. 字体:
1
terminus-font ttf-fantasque-nerd $(pacman -Ssq adobe-source) $(pacman -Ssq noto-fonts)

2. 配置网桥

家里的电信有一个光猫负责光电转换和拨号,很早,而且我不在的时候这个东西就安装好了,现在不好再改,所以只好桥接了。这里因为装了 ArchLinux ,必须体验一下 ArchLinux 的 netctl

2.1. 设置别名

这个 N6000 有 4 个 I226 ,插上一个 mt7921 之后在我这边被命名为 enp{3,4,5,6}s0 这里因为我不会再更改硬件(主要是懒),就不设置别名了,如果需要的话可以用 udev 实现,比如现在想要把 enp3s0 赋予 net0 别名,先看这个设备的目录:

1
find /sys/devices -name enp3s0

我这边的输出是:

1
/sys/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/enp3s0

这条 udev 就可以这么写:

1
2
3
# ===== /etc/udev/rules.d/10-network.rules =====

SUBSYSTEM="net", DEVPATH="/devices/pci0000:00/0000:00:1c.4/0000:03:00.0/net/enp3s0", NAME="net0"

2.2. 桥接

用 netctl 会非常方便,比如想要这个网桥叫 br0 ,配置可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
# ===== /etc/netctl/br0 =====

Description="Bridge br0"
Interface=br0
Connection=bridge
BindsToInterfaces=(enp3s0 enp4s0 enp5s0 enp6s0)
MACAddress=enp3s0
IP=static
Address=('192.168.1.222/24')
Gateway='192.168.1.1'
DNS=('192.168.1.1')
IP6=stateless

意思是把 enp{3,4,5,6}s0 放进网桥 br0 里,这个网桥的 MAC 地址跟 enp3s0 一样(因为这个接口连接了上级路由),并分配了 IP 地址(因为这台机器也要上网,而不是仅仅作为交换机使用)。

3. 配置 AP

这里我装的网卡是 MT7921 ,需要注意的是一般的无线网卡不一定能开 AP , Intel 最近几代网卡更是如此,可以去 Linux Wireless Driver 找一个支持 AP 模式的网卡。

3.1. 关于信道

可用信道可以去 List of WLAN channels - Wikipedia 找。

我也知道可以用 WiFiAnalyzer 之类的东西找一个空闲信道,但因为各种限制,你找到的空闲信道大概率是用不了的, TLDR 最方便的信道是 149(155) ,也几乎是大陆上唯一一个能用的 5 GHz (802.11ac) 信道了,好像 6 GHz (802.11ax) 也可以,但我的手机不支持 6 GHz ,所以没有做测试。

3.2. hostapd

使用 hostapd 配置 AP 是相对方便的方法, hostapd 提供了一套很详细的配置,我只用了最简单的几个选项配置了一个 WiFi 6 :

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
# ===== /etc/hostapd/hostapd.conf =====

##### hostapd configuration file ##############################################
# Empty lines and lines starting with # are ignored

# 绑定的接口,我这里的 mt7921 被命名为了 wlan0
interface=wlan0
# 桥接到 br0
bridge=br0
# 这个驱动更通用一些
driver=nl80211
# 802.11ac/ax 要填 a
hw_mode=a
# 国家码,可以去 https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 找
country_code=CN
# 信道
channel=149
# 0b10 ,表示仅支持 WPA2 或 WPA3
wpa=2
# WPA3-Personal 或 WPA2
wpa_key_mgmt=SAE WPA-PSK
# 默认的 TKIP 貌似不安全,所以只用 CCMP
wpa_pairwise=CCMP

# AP 名
ssid=你的 AP 名
# AP 密码
wpa_passphrase=你的 AP 密码

# 802.11d 和 h 启用后 DFS 才能正常工作
ieee80211d=1
ieee80211h=1

# 802.11n (2.4 GHz) 相关
ieee80211n=1
ht_capab=[LDPC][HT40+][HT40-][GF][SHORT-GI-20][SHORT-GI-40][TX-STBC][RX-STBC1][MAX-AMSDU-7935]

# 802.11ac (5 GHz) 相关
ieee80211ac=1
vht_oper_chwidth=1 # 使用 80 MHz 频率
vht_oper_centr_freq_seg0_idx=155 # 信道为 149(155)
vht_capab=[RXLDPC][SHORT-GI-80][TX-STBC-2BY1][SU-BEAMFORMEE][MU-BEAMFORMEE][RX-ANTENNA-PATTERN][TX-ANTENNA-PATTERN][RX-STBC-1][BF-ANTENNA-4][MAX-MPDU-11454][MAX-A-MPDU-LEN-EXP7]

# 802.11ax (6 GHz) 相关
ieee80211ax=1
he_oper_chwidth=1 # 使用 80 MHz 频率
he_oper_centr_freq_seg0_idx=155 # 信道为 149(155)

4. 网络自由

现在可以把我的垃圾小米路由器扔一边了

找到了 trojan-go 的一个还在活跃的 fork : Potterli20/trojan-go-fork ,这个 fork merge 了 gfw-report 对于 TLS Client Hello 指纹问题的解决方案,还 merge 了一些其他的 fork 。

4.1. 服务端

我的部署方式是 trojan-go 监听 443 ,把 http fallback 到监听 8443 的 JupyterLab , tcp fallback 到监听 8444 的 nginx ,证书用 certbot 申请。配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"run_type": "server",
"local_addr": "0.0.0.0",
"local_port": 443,
"remote_addr": "127.0.0.1",
"remote_port": 8443,
"password": [
"7gwr1LiPtlLSpCh9A2s+hu/Y/6yJhYTn2ztJS+0fKWY="
],
"ssl": {
"cert": "/etc/letsencrypt/live/your.domain/fullchain.pem",
"key": "/etc/letsencrypt/live/your.domain/privkey.pem",
"sni": "your.domain",
"fallback_port": 8444
}
}

密码可以用 OpenSSL 生成一串随机字符来达到强密码的目的:

1
openssl rand -base64 32 # 生成 32 bytes 随机数据并用 base64 编码

fallback 到 JupyterLab 有很多好处,比如:

  • 不需要伪装网站
  • 可以用 JupyterLab 的 Terminal 进行日常的维护,走 WSS 理论上比用 ssh 更安全。
  • 有需要下载的大文件时可以先用 JupyterLab Terminal 下好后用 JupyterLab 的下载功能走 HTTPS 协议下到本地,避免产生大量 trojan 协议的流量,理论上更安全。

4.2. 客户端

把 release 里带的 example/client.json 稍微改一下:

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
{
"run_type": "client",
"local_addr": "127.0.0.1",
"local_port": 1080,
"remote_addr": "your.domain",
"remote_port": 443,
"password": [
"7gwr1LiPtlLSpCh9A2s+hu/Y/6yJhYTn2ztJS+0fKWY="
],
"ssl": {
"sni": "your.domain"
},
"mux": {
"enabled": true
},
"router": {
"enabled": true,
"bypass": [
"geoip:cn",
"geoip:private",
"geosite:cn",
"geosite:private"
],
"block": [
"geosite:category-ads"
],
"proxy": [
"geosite:geolocation-!cn"
],
"default_policy": "proxy",
"geoip": "/usr/share/trojan-go-fork/geoip.dat",
"geosite": "/usr/share/trojan-go-fork/geosite.dat"
}
}

透明代理可以用 iptables 实现,比如我的服务端 IP 为 1.2.3.4 ,我的四个 I226 的接口名为 enp{3,4,5,6}s0 ,刚才的 AP 用的接口为 wlan0

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
iptables -t mangle -N TROJAN_GO

iptables -t mangle -A TROJAN_GO -d $SERVER_IP -j RETURN

iptables -t mangle -A TROJAN_GO -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A TROJAN_GO -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A TROJAN_GO -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A TROJAN_GO -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A TROJAN_GO -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A TROJAN_GO -d 240.0.0.0/4 -j RETURN

iptables -t mangle -A TROJAN_GO -j TPROXY -p tcp --on-port 1080 --tproxy-mark 0x01/0x01
iptables -t mangle -A TROJAN_GO -j TPROXY -p udp --on-port 1080 --tproxy-mark 0x01/0x01

iptables -t mangle -A PREROUTING -p tcp -i enp3s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i enp3s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p tcp -i enp4s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i enp4s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p tcp -i enp5s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i enp5s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p tcp -i enp6s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i enp6s0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p tcp -i wlan0 -j TROJAN_GO
iptables -t mangle -A PREROUTING -p udp -i wlan0 -j TROJAN_GO

ip route add local default dev lo table 100
ip rule add fwmark 1 lookup 100

5. 远程桌面

有时会有一个需求:用家里网络下的一个设备的浏览器打开一个网页。可以用 VNC 来实现,在上面已经装了 sway 和 wayvnc 。

5.1. sway - headless

没有物理视频输出下启动 sway 需要添加 WLR_BACKENDS=headlessWLR_LIBINPUT_NO_DEVICES=1 两个环境变量,可以像这样使用 systemd 管理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[Unit]
Description=Swaywm
BindsTo=default.target
Wants=default.target
After=default.target

[Install]
WantedBy=default.target

[Service]
Type=simple
User=你的用户名
Group=你的组名
PAMName=login
Environment=WLR_BACKENDS=headless
Environment=WLR_LIBINPUT_NO_DEVICES=1
ExecStart=/usr/bin/sway
Restart=on-failure
RestartSec=1
TimeoutStopSec=10

在 sway 的配置文件里加上一个 headless output :

1
2
output HEADLESS-1 pos 0,0
output HEADLESS-1 mode 1920x1080

5.2. wayvnc - headless

wayvnc 可以设置 RSA-AES 加密,采用与 SSH 一样的 TOFU 模式,基本可以保证安全:

1
2
3
4
5
6
7
# ===== ~/.config/wayvnc/config =====
address=0.0.0.0
port=5900
enable_auth=true
rsa_private_key_file=$HOME/.config/wayvnc/rsa_key.pem
username=your-username
password=your-password

rsa 密钥对可以像这样生成:

1
ssh-keygen m pem -f ~/.config/wayvnc/rsa-key.pem -t rsa -N ""

因为 wayvnc 可能会需要一些 sway 的环境变量,所以比较方便的做法是用 sway 启动 wayvnc ,在 sway 的配置文件的最后加一行:

1
exec --no-startup-id wayvnc

总结(废话)

这次折腾总体来说还是挺开心的(除了那个不好评价的客服),不知道是不是心理作用,感觉我看 Youtube 都比用 RaspberryPi 的时候更流畅了。