踩了好多好多大坑,感觉用N100在docker中使用openwrt并且WAN口进行PPPoE拨号的教程不是太多,给我折磨完了

前言

最近入手了一个 699 双网口的 N100 小主机,自己有内存和硬盘,装上就开始酷酷捯饬,装上 Ubuntu22.04,双网口的第一步当然是 openwrt,启动!

相同情况的教程的确有点少,酷酷踩坑,感觉可能是没人用 docker openwrt 当主路由,而且 WAN 口还是 PPPoE 拨号

先罗列一下参考过的教程

能用,好用的教程

与我情况不同

镜像选择

1.下载镜像后导入

官网:https://archive.openwrt.org/releases/23.05.3/targets/

资源站:https://github.com/kiddin9/openwrt-packages

资源站:https://openwrt.ai/?target=x86%2F64&id=generic(最下面)

xxx-rootfs.tar.gz,是可解压固件,一般用于Docker

gunzip xxx-rootfs.tar.gz
docker xxx-rootfs.tar openwrt:rootfs

https://archive.openwrt.org/releases/23.05.3/targets/x86/64/openwrt-23.05.3-x86-64-rootfs.tar.gz

2.docker镜像拉取

docker pull sulinggg/openwrt:x86_64,这个镜像虽然不维护了但是还是很棒,预装了很多插件,本教程使用这个进行演示

3.自己编译

OP 启动!

一、开启网口混杂模式

1.查看网口名字

➜  ~ ifconfig
enp2s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::c07f:75dc:901a:49b6  prefixlen 64  scopeid 0x20<link>
        ether 00:e0:4c:08:6a:4f  txqueuelen 1000  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 38  bytes 6249 (6.2 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0x80c00000-80cfffff  

enp4s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::6bb:2302:767e:7b3d  prefixlen 64  scopeid 0x20<link>
        ether 00:e0:4c:08:6a:50  txqueuelen 1000  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 35  bytes 5650 (5.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0x80900000-809fffff  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (本地环回)
        RX packets 474  bytes 36598 (36.5 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 474  bytes 36598 (36.5 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

wlp1s0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        ether f8:89:d2:69:42:df  txqueuelen 1000  (以太网)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

如上,我的网口是enp2s0enp4s0wlp1s0是无线网卡,先不管

我这里选择enp2s0是LAN口负责本地分派IP,enp4s0为WAN口负责拨号上网

2.开启网口混杂

sudo ip link set enp4s0 promisc on
sudo ip link set enp2s0 promisc on

然后上面的ifconfig输出后面会新增PROMISC字段,就是开启成功

enp2s0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
enp4s0: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500

3.开机自自动

一重启网口混杂就会消失,所以需要写进开机脚本,这里我用systemctl实现

先写脚本,vim /home/{your_name}/sh/network_op.sh,写入下面的内容,your_name替换成你的

sudo ip link set enp4s0 promisc on
sudo ip link set enp2s0 promisc on

再新建system,sudo vim /etc/systemd/system/network_op.service,写入下面的内容,your_name替换成你的

[Unit]
Description=Enable op network

[Service]
Type=oneshot
ExecStart=/usr/bin/sh /home/{your_name}/sh/network_op.sh
User=root
Group=root

[Install]
WantedBy=multi-user.target

运行一次服务并设置开启自启动

sudo systemctl start network_op
sudo systemctl enable network_op

二、创建网络并启动OP

这里我们使用 docker 的 macvlan,从物理网口虚拟出一个新的网口,并且挂载进 openwrt 镜像中

# 创建 LAN 口虚拟网络,指定网段为 100.x,网关是 100.1,设备使用 enp2s0,名字叫 op_lan
# (如果要修改名字请看完上面的《三网口(卡)及以上需要注意顺序》)
docker network create -d macvlan --subnet=192.168.100.0/24 --gateway=192.168.100.1 -o parent=enp2s0 op_lan
# 创建 WAN 口网络,我是 PPPoE 拨号所以网关网段什么的都不指定了
docker network create -d macvlan -o parent=enp4s0 op_wan
# 启动 docker openwrt,我使用的是 sulinggg/openwrt:x86_64 镜像,设置自启动,名字叫 openwrt,把 op_lan 连接进去
# 有些教程会在这里加上 --ip 直接设置成 .100.2,但我感觉 op 就是网关,所以这里不指定,直接在 op 里面设置,占住 100.1的 ip
docker run --restart always --name openwrt -d --network op_lan --privileged sulinggg/openwrt:x86_64 /sbin/init
# 再把 op_wan 也连接进去
docker network connect op_wan openwrt

实际过程

(base) ➜  python_and_sh docker network create -d macvlan --subnet=192.168.100.0/24 --gateway=192.168.100.1 -o parent=enp2s0 op_lan
e5c68630a0198f2985a7313c68dbcae0165a60b867e8efa6b9694fb39cc42ed2
(base) ➜  python_and_sh docker network create -d macvlan -o parent=enp4s0 op_wan
d284f0d8cde3ac57faae92ab2f2739b4aace7064f7f5bf0556077e51785969e2
(base) ➜  python_and_sh docker run --restart always --name openwrt -d --network op_lan --privileged sulinggg/openwrt:x86_64 /sbin/init
bbe19438aa00be18e2feb1d38ca860a7eeb42e90b756ebaf393f4ce11c7ceac6
(base) ➜  python_and_sh docker network connect op_wan openwrt
(base) ➜  python_and_sh docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
97dae32aa936   bridge    bridge    local
5fca31148366   host      host      local
07b5461851d7   none      null      local
e5c68630a019   op_lan    macvlan   local
d284f0d8cde3   op_wan    macvlan   local
(base) ➜  python_and_sh docker ps -a     
CONTAINER ID   IMAGE                     COMMAND        CREATED          STATUS          PORTS     NAMES
bbe19438aa00   sulinggg/openwrt:x86_64   "/sbin/init"   13 seconds ago   Up 12 seconds             openwrt

三、配置LAN&WAN网络

接下来要进入容器内修改配置

# 进入openwrt镜像内部
docker exec -it openwrt bash
vim /etc/config/network

把 lan 改为下面的参数,删掉多余的字段

config interface 'lan'
        option type 'bridge'
        option ifname 'eth0'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.100.1'

重启网络

/etc/init.d/network restart

!!!!!然后第一个小坑,固件默认 lan 口不开启 DHCP,所以插上 lan 口需要自行设定 IP 和网关!!!!!

1.png

然后浏览器输入192.168.100.1即可进入 openwrt 的后台管理页面

这么说起来我当时直接输了我自己密码就登进去了,难道他是自动把第一次输入的密码当密码?如果没有的话就试试root、pass、password什么的

我们先把 lan 口 DHCP 打开,网络->接口->lan->修改->最下面->忽略此接口->取消勾选,高级设置->强制也勾选上,保存&应用

网络->DHCP/DNS->基本设置->取消勾选重绑定保护不然一些域名解析的结构是192.x10.x的保留地址不会被返回!!!!!!仅本地服务业也可以关了

配置 wan 口,添加新接口

2.png

填入账号和密码 !!!!在 wan 的防火墙设置 选中 wan!!!!,不然一切端口转发都会失效

有时候会自动选中 但有时候不会

如果卡住可以重启docker,docker restart openwrt

这时候 wan 口可以正常拨号获得 IP,LAN 口也会自动分配 ip 了,但是,宿主机是无法使用网络,我们需要给宿主机也分配一个192.168.100.x的地址

四、宿主机使用 openwrt 的网络

这里我们使用 ip 指令给网卡创建 macvlan,因为 macvlan 的安全机制,宿主机与容器内不能通过 macvlan 数据互通,但是 macvlan 之间可以互通

# 先创建一个名叫 me_to_op 的 macvlan,使用设备 enp2s0
sudo ip link add me_to_op link enp2s0 type macvlan mode bridge
# 把宿主机的 ip 设置为 192.168.100.100
sudo ip addr add 192.168.100.100 dev me_to_op
# 启动 me_to_op
sudo ip link set me_to_op up
# 添加路由
sudo ip route add 192.168.100.1 dev me_to_op
# 修改默认路由
sudo route add default gw 192.168.100.1 me_to_op

配置完成之后就可以互相 ping

宿主机到 openwrtping 192.168.100.1

openwrt 到宿主机docker exec -it openwrt bash -c "ping 192.168.100.100 -c 3"

这时候路由正确(route -n)但是域名解析不对,能 ping ip 但是不能上网,我们接着配置 DNS

sudo sh -c 'echo "nameserver 192.168.100.1" > /etc/resolv.conf'

/etc/systemd/resolved.conf的 dns 字段是更加规范的操作,但是怕以后换网络环境忘记了,所以直接改/etc/resolv.conf

宿主机联网测试:curl baidu.com

(base) ➜  ~ curl www.baidu.com
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://........................

为了使上面的修改重启后一直生效,修改/home/{your_name}/sh/network_op.sh文件为如下内容

sudo ip link set enp4s0 promisc on
sudo ip link set enp2s0 promisc on

sudo ip link add me_to_op link enp2s0 type macvlan mode bridge
sudo ip addr add 192.168.100.100 dev me_to_op
sudo ip link set me_to_op up
sudo ip route add 192.168.100.1 dev me_to_op
sudo route add default gw 192.168.100.1 me_to_op

sudo sh -c 'echo "nameserver 192.168.100.1" > /etc/resolv.conf'

Tips:两个怪问题

  • 1.**LAN 口不插东西宿主机就 ping 不通192.168.100.1**,就是这么的神奇,必须得要 LAN 口有一个设备,不然就是 ping 不通,我的理解是 LAN 口不插东西就没有被激活,所以上面设置的 macvlan 没有生效,比如接个电脑是可以的,接个交换机(交换机不接其他东西)也是可以的,只要 LAN 口灯亮着就是可以的,没亮就是不行的

  • 2.LAN 口下的网络不能正常访问域名解析到 WAN 口 IP 上的内容,具体点来说是,我的 openwrt 的 80 端口转发到了宿主机192.168.100.100的 80 上,然后由 nginx 反代,op.xx.xx代理到 op 的管理页面,files.xx.xx代理到 GoWebDav 上,跟 WAN 口同网段的10.x.x.x.的设备可以正常使用,但是 LAN 口下的设备用域名不能访问,而直接端口 + IP 是可以的,需要做如下改动(是与桥接网络过滤器有关的内容,具体原因不是很清楚)

    1.ssh连接openwrt系统后,编辑/etc/sysctl.d/11-br-netfilter.conf文件。
    net.bridge.bridge-nf-call-arptables=0
    net.bridge.bridge-nf-call-ip6tables=0
    net.bridge.bridge-nf-call-iptables=0
    确认后面的值是0,如果不是,需要改为0
    2.编辑/etc/sysctl.conf文件。文件内容可能是空的,把上面的内容复制进sysctl.conf文件,保存退出。
    3.ssh内输入sysctl -p命令,查看输出结果是不是上面提到的那三行内容。
    4.重启
    

参考教程:https://www.right.com.cn/forum/forum.php?mod=redirect&goto=findpost&ptid=8192269&pid=16637078

部分教程提及了 80 端口转发的NAT 环回请勿关闭

NAT环回(NAT loopback)是指在网络中使用网络地址转换(NAT)时,当内部主机尝试通过其外部公共IP地址访问在同一内部网络中的另一台主机时发生的情况。简单来说,当内部主机试图通过公共IP地址访问自己所在的内部网络中的另一台主机时,数据包被NAT路由器接收并重新发送给内部网络中的相应主机,这种情况就被称为NAT环回。这种行为可能会影响网络性能和行为,因此需要在NAT路由器上进行适当的配置来处理这种情况。

一旦关闭NAT 环回,所有的访问到 WAN 的 IP 会直接打到 op 后台,不会被端口转发,宿主机上的 nginx 将无法生效

五、插件&其他一些使用


系统

1.管理权

Dropbear 实例按需修改

2.挂载点&启动项

我这里需要持久化挂载一块硬盘到 openwrt 里面,试了下挂载点的操作不生效,我就直接把mount /dev/sda1 /mnt/sda1写到启动项最下面的本地启动脚本里面了


服务

1.微信推送

微信pushplus不限制条数,好用。但在 op 的实际推送中感觉用处不大,IPV4 和 IPV6 变动可以用 DDNS解决。

2.DDNS/动态DNS

修改->启用,然后按需修改即可,我这里 IPV4 来源选的是接口->pppoe-wan查询主机名域名都直接填xxx.xxx.xxx就行,成功配置后上次更新 下次更新那会变成两行时间,出现问题可以查看日志

如果你的域名是192.x10.x等保留地址,全局设置->允许非公网 IP一定要勾选上!!!!!!!!


NAS

1.GoWebDav

简单使用,点击即用,但是有个开关叫只读模式,但是我没发现应该怎么往上上传😭

2.网络共享

Samba,好用,踩了点小坑,如果要在 WAN 口同网段下使用需要把 445 和 139 端口转发到内部 192.168.100.1 的 445 和 139排错参考教程

先进行命令行操作:

# 更新源
opkg update
# 安装软件
opkg install shadow-common
opkg install shadow-useradd
# 添加名叫smbkirin的用户
useradd smbkirin
# 为smbkirin设置密码
passwd smbkirin
# 添加smbkirin到Samba中
smbpasswd -a smbkirin
# 重启Samba
service samba restart

然后在网页控制界面中添加文件夹,名称随便取,路径看你定,用户用上面的,新文件0666(可读可写不可执行),目录0777

Windows 下载资源管理器输入\\{IP}即可访问,可以映射到网络驱动器方便使用


其他的

1.使用IPV6

如果你的网络不发放 IPV6,改了也没有的

在 openwrt 中安装组件

opkg update
opkg install ipv6helper

修改vim /etc/config/network追加如下内容

config interface 'wan6'
        option proto 'dhcpv6'
        option ifname 'pppoe-wan'
        option reqaddress 'try'
        option reqprefix 'auto'

详细解释 ipv6:https://post.smzdm.com/p/awzodmpp/

如果要实现 ipv6 转发到 ipv4 端口,socat软件包能直接在软件包里面点一下安装,socat 教程

如果要监听 80 和 443 端口,因为被uhttpd占住了所以需要改一下设置,让uhttpd不监听 IPV6 地址

# 查看uhttp监听情况
netstat -tlnp | grep uhttpd
# 修改配置,注释掉ipv6的监听
vi /etc/config/uhttpd
# 重启uhttpd
/etc/init.d/uhttpd restart
# 再次查看
netstat -tlnp | grep uhttpd

如果要在 LAN 网络下使用 IPV6 域名解析,网络->DHCP/DNS->高级设置->禁止解析 IPV6 DNS 记录

测试端口通断nmap -6 {IPV6 地址} -p 80,4438080,20000,30004 -Pn

clash 开着会影响 ipv6 地址的访问,无敌了,后面发现原因是会域名代理,如果你买的机场的这个节点有 IPV6,甚至可以用代理脸上,即使你自己没有 IPV6 网络

不知道为啥我的 IPV6 防火墙没生效,可以直接访问内网的设备,发现 IPV4 也是一样的,防火墙没有阻断,有点奇怪,这个教程有 nmap 使用方法,哎不管了,开就开吧

2.加入无线网卡

题外话一句,我买的 N100 自带 AX101 网卡,是 WiFi6 但是很垃圾 ,最重要的是官方没有适配驱动,在 Ubuntu22.04 系统上开机即可使用,但是带宽甚至跑不满百兆,个人猜测是识别成了其他网卡能用但是调度不好,跑不满千兆也能理解,但是跑不满百兆就有点离谱了。

最后从室友的泡水机上取了个 MT7921,无线发射带宽实测刚好 100M,能用还行

有尝试使用 macvlan 等操作挂进 openwrt,不过想了想好像用处不大,最终的方法是直接开一个热点,把192.168.100.100获得的网络共享出去

# 使用nmcli启用WiFi
sudo nmcli device wifi hotspot ifname {网卡名称,如wlp1s0} con-name {在nm中的名字} ssid {WiFi名字} password {密码}
# 如下
# sudo nmcli device wifi hotspot ifname wlp1s0 con-name nmcli-wifi ssid n100-wifi password 123456789

也是重启会失效,所以加入之前写的开机脚本里

最终的脚本内容,为了以防万一又加入了两句删除指令sudo ip link del me_to_opnmcli connection delete nmcli-wifi

sudo ip link set enp4s0 promisc on
sudo ip link set enp2s0 promisc on

sudo ip link del me_to_op
sudo ip link add me_to_op link enp2s0 type macvlan mode bridge
sudo ip addr add 192.168.100.100 dev me_to_op
sudo ip link set me_to_op up
sudo ip route add 192.168.100.1 dev me_to_op
sudo route add default gw 192.168.100.1 me_to_op

sudo sh -c 'echo "nameserver 192.168.100.1" > /etc/resolv.conf'

sudo nmcli connection delete nmcli-wifi
sudo nmcli device wifi hotspot ifname wlp1s0 con-name nmcli-wifi ssid n100-wifi password 123456789

因为使用的是热点,所以ifconfig中无线会变成一个10.x的网段,链接上WiFi的设备也会获得10.x的网段,不过跟我的 WAN 口地址不冲突,所以我也就不管了,应也该可以改网段的。

如果要把 WiFi 挂进 openwrt 而非上面那样,则需操作如下

docker network create -d macvlan --subnet=192.168.200.0/24 --gateway=192.168.200.1 -o parent=wlp1s0 op_wifi
docker network connect op_wifi openwrt

修改/etc/config/network

config interface 'lanwifi'
        option type 'bridge'
        option ifname 'eth2'
        option proto 'static'
        option netmask '255.255.255.0'
        option ip6assign '60'
        option ipaddr '192.168.200.1'

同样设置防火墙到 LAN

似乎这样做链接上 WIFI 的设备先会得到10.x的 IP,然后变成一个192.168.200.x的 IP,为了操作简洁我还是选择了前面的那种做法,因为我感觉这样也不是很优雅而且显得很乱,我感觉应该找一找 WiFi 热点能发送但是不分配 IP 的方案,然后直接让 op 来发 IP,跟 LAN 就一样的了,而且这样就不会像 LAN 一样还的插个东西才能工作。或许还可以考虑一下都分进 100 网段里面,两个 DHCP 服务器各发各的,或许也不会冲突?

后记

从购入到今天刚好十天,终于捯饬的差不多了,爽!从昨天开始狂写 4K 字的教程,必须狠狠地记录!我终将成为 op 高手!

以及感谢 zzsqwq 的分析排错,神!还有 KirCute 的一问:“这灯怎么没亮”,从而想到 LAN 口不插东西就不工作,无敌!