ProxmoxVE 7.0 LXC环境下搭建OpenWrt软路由

前言

本文探讨在赛扬J1900双网卡系统上使用ProxmoxVE 7.0 LXC环境下搭建OpenWrt软路由。

整体网络结构如下:

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
+----------------------------------------------------------------+
| LXC |
| +------------------------------------------------+ |
| | OpenWrt | |
| | +--------+ +--------+ +--------+ | |
| | | br-lan |←---→| eth0 | | enp4s0 | | |
| | +--------+ +--------+ +--------+ | |
| | 192.168.1.1 ↑ ↑ | |
| +------------------------|-------------|---------+ |
| veth phys |
|................................|.............|.................|
| ProxmoxVE 7.0 | | |
| | | |
| ↓ ↓ |
| +------+ +--------+ +------+ |
| |enp3s0|←---→| vmbr0 | |enp4s0| |
| +------+ +--------+ +------+ |
| ↑ 192.168.1.2 ↑ |
| | | |
| | | |
+-------------------|--------------------------|-----------------+
↓ ↓
+----+ +--------+ +----+ +-------+
| PC |←---→ | switch |←---→| TV | | modem |
+----+ +--------+ +----+ +-------+

一、创建容器

  1. 下载模版
    可以选择Koolshare 的LEDE制作LXC模板

  2. 上传模板到PVE

  1. 新建LXC容器
    通过SSH或者是网页端打开PVE终端,执行以下命令创建新容器
1
2
3
4
5
6
7
8
9
10
pct create 100 \
local:vztmpl/openwrt-21.02.0-rc3-x86-64-rootfs.tar.gz \
--rootfs local-lvm:4 \
--ostype unmanaged \
--hostname OpenWrt \
--arch amd64 \
--cores 2 \
--memory 2048 \
--swap 0 \
-net0 bridge=vmbr0,name=eth0

各参数说明:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
各参数说明:
vmid:100
容器编号,可以根据需要自行设置,这里设为100,后面的相关设置会用到该编号。
local:vztmpl/openwrt-21.02.0-rc3-x86-64-rootfs.tar.gz
容器模板, local:vztmpl/ 指向 /var/lib/vz/template/cache/目录,是pve的默认模板存放目录,webUI上传的模板就存在该位置,可根据需要改为其他目录,openwrt-21.02.0-rc3-x86-64-rootfs.tar.gz为模板文件名。
--rootfs local-lvm:4
根磁盘位置,local-lvm可以根据实际情况修改为其他存储位置,4表示空间大小为4G。
--ostype unmanaged
系统类型,之后可在设置文件中修改。
--hostname OpenWrt
容器名称,之后可在设置文件中修改。
--arch amd64
系统架构,amd64 | arm64 | armhf | i386。
--cores 2
分配给容器的核心数。
--memory 2048
分配给容器的内存大小,这里是2G。
--swap 0
分配给容器的交换区大小,这里是0。
-net0 bridge=vmbr0,name=eth0
容器网络设置,这里设置网络0为容器中增加网卡eth0,桥接到主机的vmbr0接口。

二、修改容器设置

  1. 修改容器配置文件

    1
    vim /etc/pve/lxc/100.conf

    添加以下内容

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # openwrt.common.conf是PVE自带的openwrt配置文件示例,内含一些基本设置
    lxc.include: /usr/share/lxc/config/openwrt.common.conf
    # /dev/ppp pppoe拨号等功能需要用到
    lxc.cgroup.devices.allow: c 108:0 rwm
    # 钩子脚本,用于添加 /dev/ppp等设备
    hookscript: local:snippets/hookscript.pl
    # 将主机的网卡enp4s0分配给容器使用,根据自己的实际情况更改
    lxc.net.1.type: phys
    lxc.net.1.link: enp4s0
    lxc.net.1.flags: up

Tips:不管有没有设置,容器都会加载/usr/share/lxc/config/common.conf配置文件

  1. 创建钩子脚本
    这里在官方示例guest-example-hookscript.pl的基础上进行修改,大家可以根据需要自行修改

    1
    2
    3
    mkdir /var/lib/vz/snippets
    cp /usr/share/pve-docs/examples/guest-example-hookscript.pl /var/lib/vz/snippets/hookscript.pl
    vim /var/lib/vz/snippets/hookscript.pl

    在第36行可以找到以下内容

    1
    2
    3
    4
    # Second phase 'post-start' will be executed after the guest
    # successfully started.

    print "$vmid started successfully.\n";

    修改为

    1
    2
    3
    4
    5
    # Second phase 'post-start' will be executed after the guest
    # successfully started.
    system("lxc-device add -n $vmid /dev/ppp");
    system("lxc-device add -n $vmid /dev/net/tun");
    print "$vmid started successfully.\n";

三、启动容器

  执行以下指令
1
pct start 100

由于PVE7.0 默认采用cgroupv2,缺少对系统类型为unmanaged的容器支持,会出现以下错误:

1
2
3
4
run_buffer: 316 Script exited with status 1
lxc_init: 816 Failed to run lxc.hook.pre-start for container "100"
__lxc_start: 2007 Failed to initialize container "100"
startup for container '100' failed

解决方法是修改/usr/share/perl5/PVE/LXC/Setup.pm文件

1
vim /usr/share/perl5/PVE/LXC/Setup.pm

翻到最后,可以看到以下内容

1
2
3
4
5
6
sub unified_cgroupv2_support {
my ($self) = @_;
$self->protected_call(sub {
$self->{plugin}->unified_cgroupv2_support();
});
}

修改为

1
2
3
4
5
6
7
sub unified_cgroupv2_support {
my ($self) = @_;
return if !$self->{plugin}; # unmanaged
$self->protected_call(sub {
$self->{plugin}->unified_cgroupv2_support();
});
}

继续执行pct start 100指令启动容器,会出现WARN: old systemd (< v232) detected, container won't run in a pure cgroupv2 environment! Please see documentation -> container -> cgroup version.警告,忽略就行。

如果还无法正常启动,可通过以下命令查看错误信息(日志保存于debug文件中)

1
lxc-start -n 100 --logfile debug --logpriority TRACE

四、OpenWrt基本设置

容器启动后,进入容器终端

1
lxc-attach 100

1.修改root密码

1
passwd

2.网络设置

1
vi /etc/config/network

修改如下内容(根据自己的实际情况更改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
config device
option name 'br-lan'
option type 'bridge'
list ports 'eth0'

config interface 'lan'
option device 'br-lan'
option proto 'static'
option ipaddr '192.168.1.1'
option netmask '255.255.255.0'
option ip6assign '60'

config interface 'wan'
option device 'enp4s0'
option proto 'pppoe'
option username '1234567890'
option password 'abcdefghijk'

重启网络和防火墙

1
2
/etc/init.d/network restart
/etc/init.d/firewall restart

● 现在你应该能够上网,并能通过https://192.168.1.1打开OpenWrt页面了

五、安装常用软件(根据个人需要选择安装)

为了避免一些异常情况发生,修改/etc/hosts,添加以下内容

1
2
185.199.108.133 raw.githubusercontent.com
140.82.112.4 github.com

安装一些基本软件和中文语言包

1
2
opkg update
opkg install vim luci-i18n-base-zh-cn luci-i18n-firewall-zh-cn luci-i18n-opkg-zh-cn
  1. oh-my-zsh安装
    来源:https://github.com/felix-fly/openwrt-ohmyzsh

安装依赖

1
opkg install unzip zsh ca-certificates

安装

1
sh -c "$(wget -O- https://raw.githubusercontent.com/felix-fly/openwrt-ohmyzsh/master/install.sh)"

设为默认shell

1
which zsh && sed -i -- 's:/bin/ash:'`which zsh`':g' /etc/passwd

不想用时可以卸载

1
sh -c "$(wget -O- https://raw.githubusercontent.com/felix-fly/openwrt-ohmyzsh/master/uninstall.sh)"
  1. 阿里云ddns安装设置
    安装ddns中文包和依赖
1
opkg install luci-i18n-ddns-zh-cn wget-ssl openssl-util

下载 update_aliyun_com.sh脚本

1
wget -O /usr/lib/ddns/update_aliyun_com.sh https://raw.githubusercontent.com/sensec/ddns-scripts_aliyun/master/update_aliyun_com.sh

打开设置

DDNS

按步骤设置参数

DDNS设置

  1. zerotier安装设置
    安装zerotier软件包
1
opkg install zerotier

设置

1
2
3
uci set zerotier.sample_config.enabled='1'
# 0123456789ABCDE1替换成自己的网络ID
uci set zerotier.sample_config.join='0123456789ABCDE1'

启动zerotier

1
/etc/init.d/zerotier start

查看状态

1
zerotier-cli listnetworks

显示信息类似以下格式

1
2
200 listnetworks <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
200 listnetworks 0123456789ABCDE1 XX:XX:XX:XX:XX:XX ACCESS_DENIED PRIVATE ztqu1d2mhx -

显示status状态是 ACCESS_DENIED,需要去ZeroTier Central设置通过。之后再执行zerotier-cli listnetworks显示status状态是OK就说明设置成功

修改防火墙设置

1
vim /etc/firewall.user

添加以下内容,其中ztxxxxxxxx更改为zerotier-cli listnetworks显示的dev项

1
2
3
iptables -I FORWARD -i ztxxxxxxxx -j ACCEPT
iptables -I FORWARD -o ztxxxxxxxx -j ACCEPT
iptables -t nat -I POSTROUTING -o ztxxxxxxxx -j MASQUERADE

重启防火墙

1
/etc/init.d/firewall restart
  1. Server酱安装设置
    使用说明:https://github.com/tty228/luci-app-serverchan/

安装依赖,因为作者没有把luci-compat加进依赖库,需要手动安装(已安装的可忽略,比如安装dockerman的时候会自动安装luci-compat)

1
opkg install luci-compat

下载安装软件包

1
2
wget https://github.com/tty228/luci-app-serverchan/releases/download/v1.86/luci-app-serverchan_1.86-9_all.ipk
opkg install luci-app-serverchan_1.86-9_all.ipk

打开设置

微信推送

按照提示和格式要求填写“企业微信凭证”

Server酱官方配置说明文档点击这里
Server酱设置

设置好以后,点击“定时推送”–>“发送”

Server酱消息发送

可以收到下图格式的信息

Server酱

如果定时推送功能设置后没有收到消息,可能是由于\etc\crontabs\root文件不存在引起的,执行以下命令创建即可

1
touch \etc\crontabs\root

其他设置可以自行摸索

  1. docker安装设置
    修改容器配置文件
1
vim /etc/pve/lxc/100.conf

docker需要用到mount功能,添加以下内容来解除限制

1
lxc.apparmor.profile: unconfined

修改openwrt.common.conf文件

1
vim /usr/share/lxc/config/openwrt.common.conf

如下注释掉lxc.cap.drop = sys_admin

1
2
## docker
#lxc.cap.drop = sys_admin

重启容器

1
pct reboot 100

进入容器终端,安装软件包

1
opkg install dockerd luci-i18n-dockerman-zh-cn

运行hello-world

1
docker run hello-world

出现以下内容说明已安装配置完成

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
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:df5f5184104426b65967e016ff2ac0bfcd44ad7899ca3bbcf8e44e4461491a9e
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/

For more examples and ideas, visit:
https://docs.docker.com/get-started/

然后可以在网页界面进行相关操作

docker

  1. vlmcsd安装
    安装软件包
1
2
3
4
wget https://github.com/siwind/openwrt-vlmcsd/releases/download/svn1113/vlmcsd_svn1113-2020-5-20_x86_64.ipk
opkg install vlmcsd_svn1113-2020-5-20_x86_64.ipk
wget https://github.com/siwind/luci-app-vlmcsd/releases/download/v1.0.4/luci-app-vlmcsd_1.0.4-1_all.ipk
opkg install luci-app-vlmcsd_1.0.4-1_all.ipk

验证

1
nslookup -type=srv _vlmcs._tcp.lan

返回如下结果说明已安装设置完成(其中OpenWrt.lan应该是软路由的IP地址或主机名)

1
_vlmcs._tcp.lan service = 0 100 1688 OpenWrt.lan.

如果没有得到正常结果,可以执行以下指令后再试

1
/etc/init.d/dnsmasq restart
  1. 安装nginx替代默认的uhttpd
    安装以下软件包就可以,无需其他设置
1
opkg install nginx-util nginx-ssl-util nginx-mod-luci-ssl

如果想从外网访问openwrt网页界面,修改/etc/nginx/restrict_locally,把最后的deny all;改为allow all;

1
2
3
4
5
6
7
8
9
10
11
allow ::1;
allow fc00::/7;
allow fec0::/10;
allow fe80::/10;
allow 127.0.0.0/8;
allow 10.0.0.0/8;
allow 172.16.0.0/12;
allow 192.168.0.0/16;
allow 169.254.0.0/16;
#deny all;
allow all;

重启nginx

1
/etc/init.d/nginx restart

利用nginx搭建简单文件服务
新建conf配置文件,文件名任意

1
vim /etc/nginx/conf.d/fileserver.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
autoindex on;# 显示目录
autoindex_exact_size on;# 显示文件大小
autoindex_localtime on;# 显示文件时间

server {
listen 8880;#端口号,选择任意未使用的就可以
listen [::]:8880;#端口号,选择任意未使用的就可以
server_name _;
root /www/fileserver/;#文件所在主目录
charset utf-8;#防止中文乱码

location / {
}

}

添加nginx的php支持
安装php

1
opkg install php8-fpm

添加配置文件

1
vim /etc/nginx/conf.d/php.locations
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}

# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";

fastcgi_pass unix:/var/run/php8-fpm.sock;
fastcgi_index index.php;

# include the fastcgi_param setting
include fastcgi_params;

# SCRIPT_FILENAME parameter is used for PHP FPM determining
# the script name. If it is not set in fastcgi_params file,
# i.e. /etc/nginx/fastcgi_params or in the parent contexts,
# please comment off following line:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
1
vim /etc/nginx/conf.d/test.locations
1
2
3
location /test/ {
index index.php;
}
1
2
mkdir /www/test
vim /www/test/index.php
1
<?php phpinfo()?>

重启nginx

1
/etc/init.d/nginx restart

浏览器打开https://192.168.1.1/test/应该可以看到php的相关信息

六、其他

  1. 更新到openwrt-21.02.0
    如果之前安装了openwrt-21.02.0-rc3或rc4版本的可以更新到openwrt-21.02.0稳定版本

先需要进入终端,更新内核包

1
2
wget https://downloads.openwrt.org/releases/21.02.0/targets/x86/64/packages/kernel_5.4.143-1-b70ee1516753f10c063dd361f74167d4_x86_64.ipk
opkg install kernel_5.4.143-1-b70ee1516753f10c063dd361f74167d4_x86_64.ipk

然后如下图所示,将所有更新源地址中的21.02.0-rc3改为21.02.0

修改更新源

通过终端批量更新

1
2
opkg update
opkg list-upgradable | sed 's/ .*$//g' | xargs opkg upgrade

————————————————
版权声明:本文为CSDN博主「kangzeru」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/kangzeru/article/details/115373587


ProxmoxVE 7.0 LXC环境下搭建OpenWrt软路由
http://he.mk/2021/11/17/ProxmoxVE 7.0 LXC环境下搭建OpenWrt软路由/
作者
未必赢
发布于
2021年11月17日
许可协议