Docker 对比裸机安装 OpenWrt 的优势是很方便管理 OpenWrt 的板本,缺点是比直接安装 OpenWrt 系统复杂,并且网络情况也更加复杂。

1. Docker 安装 OpenWrt

  1. 查看有哪些镜像;

    1
    docker search openwrt
  2. 拉取符合架构的镜像;

    使用arch命令查看系统架构,x86、x86_64、AMD64 基本都是同一个架构

    1
    docker pull registry.cn-shanghai.aliyuncs.com/suling/openwrt:x86_64
  3. 打开网卡混杂模式;

    1
    ip link set enp2s0 promisc on # 或 ifconfig enp2s0 promisc

    防止启动失效,加入开机自启动

    1
    2
    echo "ip link set enp2s0 promisc on" >> /etc/rc.local
    chmod a+x /etc/rc.local
  4. 创建 Docker macvlan 网络;

    Docker 的 macvlan 容器网络模式是一种网卡虚拟化技术,可以将一张物理网卡虚拟出多张网卡,容器可通过这些虚拟网卡与主机网络互联,Docker 中的 macvlan 只支持 bridge 模式。

    1
    docker network create -d macvlan -o parent="enp2s0" --subnet "192.168.137.0/24" --gateway "192.168.137.1" macnet

    -d macvlan指定网络类型为 macvlan

    parent 取值为宿主机当前所用网卡名

    --sublet宿主机 IP 所在网段

    --gateway宿主机网关

    macnet为网络名

  5. 运行 OpenWrt 容器;

    1
    2
    3
    4
    docker run --name openwrt \
    --network macnet \
    -d --privileged=true \
    registry.cn-shanghai.aliyuncs.com/suling/openwrt:x86_64 /sbin/init
  6. 进入容器内,编写网络配置文件;

    1
    2
    docker exec -it openwrt bash
    vim /etc/config/network

    修改其中 lan 口的配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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.137.252' # 填写宿主机同网段 IP(不能冲突)
    option gateway '192.168.137.1' # 填写宿主机网关
    option dns '192.168.137.1' # 填写宿主机网关
  7. 重启网络;

    1
    /etc/init.d/network restart
  8. 通过刚刚设置的 IP 地址访问 OpenWrt 管理页面并登录,用户名root,密码password

2. Dokcer 安装 OpenWrt 做旁路网关(推荐)

推荐阅读:

1
2
https://blog.csdn.net/weixin_42708321/article/details/124720849
https://zhuanlan.zhihu.com/p/122233420

部份人把这个旁路设备叫做旁路网关或者旁路由,严格来说叫旁路由或者旁路网关的说法都不正确,首先要搞清除什么是路由?什么是网关?什么叫转发?

  • 路由:现在的路由器基本都同时扮演着 路由、DHCP、DNS、网关 的角色,甚至交换机都具有了路由器功能(三层交换机)。路由器最主要的功能就是路由、转发、隔离广播域,路由是根据一些算法(静态路由算法、距离-向量算法、链路状态算法…)从路由表中找到从源设备达目标设备的最佳路径;
  • 转发:根据路由找到的最佳路径进行实际的传递数据包动作;
  • 网关:网关是一个网段数据的入口和出口,用于连接两个不同的网段从而实现不同网段间的设备通信,同一个网段的两个设备间是直接通信的,这种情况数据不经过网关。

为了方便解释,下面统一叫旁路网关,下图是一个含有旁路网关(旁路由)网络架构示例(图片来源于上面文章):

由上图可知,旁路网关就是主路由所分配子网中的一个设备,它虽然参与了流量的转发但并不是这个网段出口,实际连接外部网络的还是主路由,设置旁路网关的优点是减少了一层 NAT,由于数据需要经过旁路网关,所以连接主路由的下级设备也可以使用旁路网关所提供的功能,比如下载机、NAS、多媒体中心、内网穿透、科学上网。

简单来说,旁路网关是一个通过 LAN 口与主路由连接的一个客户端设备,主路由主要负责流量的转发,而将网关等任务交给旁路网关,减轻主路由负担。

下面是详细步骤

2.1 旁路设备部份接管

  1. 进入旁路设备 OpenWrt 配置界面,定位到网络->接口,找到当前连接的 LAN 口,将传输协议改为「静态地址」,Ipv4 地址改为当前子网内 IP(不能和其他设备冲突,具体哪些 IP 不能用可以在主路由 DHCP 设置中查看)。

  2. Ipv4 网关改为主路由 LAN 口地址,DNS 服务器可自定义;

  3. 关闭 DHCP 功能,在 OpenWrt 中是「忽略此接口」;

  4. 将旁路设备拔出接在主路由的 LAN 口,使用新设置的地址查看是否可以访问;

  5. 需要使用旁路设备提供功能的设备将网关改为旁路设备 IP。

2.2 旁路设备全面接管

这种方式不需要其他设备手动指定网关,缺点就是如果旁路设备宕机,那么这个网段内的所有设备都无法上网。

  1. 在上面配置的基础上做如下配置;

  2. 进入主路由后台,将DHCP 服务器的网关改为旁路设备的 IP 地址,DNS 最好自定义,比如:223.6.6.6,8.8.8.8;

3. Docker 安装OpenWrt 做二级路由

参考文章:https://www.treesir.pub/post/openwrt-docker-multi-net/

WARING:以下操作并未成功,仅为后面补坑提供一个思路

TODO:双网口,使用 macvlan 虚拟出 WAN 口和 LAN 口为 openwrt 容器内部使用

设备:双网口 + 一张无线网卡 RTL8188

说明:由于 Docker 启动后,终端命令行会出现紊乱,一直提示登录 Openwrt 容器内部,导致命令行完全无法使用,原因未知,所以只能使用如下方式来进行操作。

  1. 设备先连接主路由 LAN 口后获取到 IP 地址;
  2. 查看设备该网卡获取到的 IP 地址,进入/etc/sysconfig/network-scripts/,将 IP 设置为静态地址,方便后面登录。
  3. 电脑连接主路由无线局域网,使用 SSH 通过该 IP 连接,进行后面的操作。

想实现效果:enp2s0 将用于 WAN 口,enp3s0 将用于 LAN 口,无线网卡暂时搁置

  1. 开启网卡的混杂模式;

    1
    2
    ifconfig enp2s0 promisc
    ifconfig enp3s0 promisc

    防止启动失效,加入开机自启动

    1
    2
    3
    4
    echo \
    """ip link set enp2s0 promisc on
    ip link set enp3s0 promisc on""" \
    >> /etc/rc.local
    1
    chmod a+x /etc/rc.local
  2. 宿主机开启 ipv4 转发(开启 NAT 功能);

    如果是裸装 OpenWrt 不需要开启此功能。出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的 ip 地址将数据包发往本机另一块网卡。

    • 查看系统是否开启 ipv4 转发;

      1
      sysctl net.ipv4.ip_forward # 值为 1 代表已开启
    • 开启 ipv4 转发;

      1
      vim /etc/sysctl.conf

      修改或添加以下值

      1
      net.ipv4.ip_forward = 1
    • 配置立即生效;

      1
      sysctl -p

    新发现:主机和 OpenWrt 可能需要配置 iptables 的转发规则,先弄清楚 iptables 的 4表,5 链。

    1
    >iptables -P FORWARD ACCEPT
  3. 创建 WAN 口,LAN 口 的 macvlan;

    1
    2
    docker network create -d macvlan -o parent=enp2s0 --subnet=192.168.10.0/24 --gateway=192.168.10.1 macwan
    docker network create -d macvlan -o parent=enp3s0 maclan

    enp2s0 目前连接主路由,所以用于创建 macwan;enp3s0 暂未连接,用于虚拟出 LAN 口。

  4. 启动容器并指定网络为 maclan;

    1
    2
    3
    4
    docker run --name openwrt \
    --network maclan \
    -d --privileged=true \
    registry.cn-shanghai.aliyuncs.com/suling/openwrt:x86_64 /sbin/init
  5. openwrt 容器连接 macwan;

    1
    2
    3
    4
    5
    6
    7
       docker network connect macwan openwrt

    6. 进入容器内,编写网络配置文件;

    ```bash
    docker exec -it openwrt bash
    vim /etc/config/network

    修改其中 lan 口的配置:

    1
    2
    3
    4
    5
    6
    7
    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.10.2'
  6. 重启容器网络;

    1
    /etc/init.d/network restart
  7. 电脑连接设备 LAN 口(enp3s0),因为此 LAN 口并未开启 DHCP,所以需要手动配置电脑 IP(192.168.10.0/24 网段)和网关(192.168.10.1),然后进入OpenWrt 控制台;

  8. 控制台网络->接口中添加接口,选择eth1,设置 DHCP 自动获取 IP,然后在网络->诊断测试容器是否可以连通外网。

  9. 测试设备能否连通外网,如果不行,可尝试添加如下防火墙规则并重启防火墙;

    1
    iptables -t nat -I POSTROUTING -s 192.168.10.0/24  -j MASQUERADE

目前的问题:Docker 内部可以连通外网(也就是说 macwan 的配置是成功的),但是连接 LAN 的设备无法连通外网(LAN 口配置失败)

可能的原因:

  • 找不到网关(192.168.10.1 并没有指定给哪个设备,理论来说应该配置给 enp3s0,且虚拟 lan 口的网关也应该是 192.168.10.1);
  • OpenWrt 转发失败;
  • 其他…

参考文章: