作者使用的是riscv架构的Visionfive2开发板,本博客内的步骤也适用于其他开发板。交叉编译环境为ubuntu20.04。

编译内核

由于visionfive2开发板官方提供的debian镜像中的kernel未开启netfilter模块,因此我们需要重新编译内核以开启该功能,如果开启了该功能,可跳过这部分。

  1. 安装所需工具

    1
    2
    sudo apt install -y build-essential gcc-riscv64-linux-gnu libncurses-dev git 
    sudo apt install -y flex bc bison
  2. 下载源码

    1
    2
    3
    4
    5
    git clone https://github.com/starfive-tech/linux.git
    # 执行以下命令,切换到代码分支:
    cd linux
    git checkout origin/JH7110_VisionFive2_devel
    git pull
  3. 设置编译Linux内核的默认设置

    1
    make starfive_visionfive2_defconfig CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv

    修改编译Linux内核的设置,我们先使用默认的设置进行编译,编译完成后再进行修改,因此可以直接退出

    1
    make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv -j4 bindeb-pkg LOCALVERSION=-test
  4. 编译内核

    1
    make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv -jX
  5. 编译完成后,再次打开Linux内核配置页面,依次进入Networking support -> Network option ->Network packet filtering framework(Netfilter)->Core Netfilter Configuration,增加内核对netfilter的redirect、nat、reject功能的支持。再次进行编译。

    1
    2
    make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv menuconfig
    make CROSS_COMPILE=riscv64-linux-gnu- ARCH=riscv -j4 bindeb-pkg LOCALVERSION=-netfilter

编译完成后..目录会出现三个安装包, 分别为linux-image-*.deblinux-libc-dev_*.deblinux-headers-*.deb, 这里我们只需要使用image内核安装包。

安装内核

1
2
dpkg -i linux-image-5.15.0-netfilter_5.15.0-netfilter-1_riscv64.deb #安装内核
dpkg --get-selections | grep linux-image #查看已安装的内核信息

修改extlinux.conf文件,将默认启动项修改为我们刚刚编译的kernel

1
vim /boot/extlinux/extlinux.conf

重启系统,查看内核信息

1
uname -srm

内核安装失败的问题

博主在重启失败时出现了内核启动失败的问题,具体问题如下

1
2
3
4
5
[FAILED] Failed to mount Huge Pages File System.
[FAILED] Failed to mount POSIX Message Queue File System.
[FAILED] Failed to mount Kernel Debug File System.
[FAILED] Failed to mount FUSE Control File System.
[FAILED] Failed to mount Kernel Configuration File System.

经过了很长时间的筛查,发现是gcc编译器的问题:一开始博主通过目标机编译kernel,而不是交叉编译,而开发板中自带的gcc版本较低,导致编译出来的kernel无法被加载。更换为ubuntu20.04进行交叉编译后,解决了这个问题。

安装clash

在开发板上下载clash-core,并解压

1
2
gzip -d clash-linux-riscv64-v1.18.0.gz
install clash-linux-riscv64-v1.18.0 /usr/local/bin/clash

创建clash的systemd文件

1
vim /etc/systemd/system/clash.service
1
2
3
4
5
6
7
8
9
10
11
[Unit]
Description=Clash daemon, A rule-based proxy in Go.
After=network.target

[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/clash -d /etc/clash

[Install]
WantedBy=multi-user.target

设置clash为开机启动

1
2
systemctl enable clash --now
systemctl status clash

配置clash管理页面

1
git clone -b gh-pages --depth 1 https://github.com/haishanh/yacd.git /opt/clash-dashboard

开启 Linux 内核的转发功能

  1. 编辑配置文件 /etc/sysctl.conf 并向其中添加如下内容

    1
    net.ipv4.ip_forward=1
  2. 保存退出后,执行以下命令使修改生效

    1
    sysctl -p
  3. 查看 /proc/sys/net/ipv4/ip_forward 的内容,如果是 1 表示设置成功生效

    1
    cat /proc/sys/net/ipv4/ip_forward

配置nftables

安装nftables

1
apt -y install nftables

创建 nftables 配置文件扩展目录

1
mkdir /etc/nftables.conf.d

创建私有地址的定义文件

1
2
3
4
5
6
7
8
9
10
define private_list = {
0.0.0.0/8,
10.0.0.0/8,
127.0.0.0/8,
169.254.0.0/16,
172.16.0.0/12,
192.168.0.0/16,
224.0.0.0/4,
240.0.0.0/4
}

修改 nftalbes 配置文件,内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/sbin/nft -f

include "/etc/nftables.conf.d/private.nft"

table ip nat {
chain proxy {
ip daddr $private_list return
ip protocol tcp redirect to :7892
}
chain prerouting {
type nat hook prerouting priority 0; policy accept;
jump proxy
}
}

清空 nftalbes 规则,并使新规则生效, 查看 nftalbes 当前规则

1
2
3
nft -f /etc/nftables.conf
nft flush ruleset
nft list ruleset

设置 nftalbes 开机自启动

1
systemctl enable nftables --now

配置机场订阅

将机场订阅文件下载至/etc/clash文件夹内, 并添加如下内容。

1
2
3
external-controller: '0.0.0.0:9090'
secret: ''
external-ui: /opt/clash-dashboard #web控制台文件地址

重启clash

1
2
systemctl restart clash
systemctl status clash

通过http://server-ip:9090/ui网页访问clash控制台。

  • 测试代理

    1
    2
    3
    4
    export http_proxy="http://127.0.0.1:7890"
    export https_proxy="http://127.0.0.1:7890"
    export -p #查看环境变量
    curl google.com
  • 查看clash日志

    1
    journalctl -u clash.service

使用了代理后使用apt install出现了如下报错

1
2
3
E: Failed to fetch https://snapshot.debian.org/archive/debian-ports/20221225T084846Z/pool/main/t/toilet/toilet-fonts_0.3-1.4_all.deb  Unsupported proxy configured: 127.0.0.1://7890
E: Failed to fetch https://snapshot.debian.org/archive/debian-ports/20221225T084846Z/pool-riscv64/main/t/toilet/toilet_0.3-1.4%2bb1_riscv64.deb Unsupported proxy configured: 127.0.0.1://7890
E: Failed to fetch https://snapshot.debian.org/archive/debian-ports/20221225T084846Z/pool-riscv64/main/w/w3m/w3m_0.5.3%2bgit20220429-1%2bb2_riscv64.deb Unsupported proxy configured: 127.0.0.1://7890

原因为export http_proxy="http://127.0.0.1:7890"写成了export http_proxy="127.0.0.1:7890"