# 新建 DOCKER-MAN 自定义链
iptables -N DOCKER-MAN
# 挟持 DOCKER-USER 转到 DOCKER-MAN 自定义链
iptables -I DOCKER-USER -j DOCKER-MAN
# 若流量来自 br-lan 放行,目的是 `LAN` 口可以访问容暴露的端口
iptables -A DOCKER-MAN -i br-lan -o docker0 -j RETURN
# 阻止所有新建以及无效的连接。
iptables -A DOCKER-MAN -m conntrack --ctstate NEW,INVALID -o docker0 -j DROP
# 接受容器主动访问的流量,目的是容器能够联网。
iptables -A DOCKER-MAN -m conntrack --ctstate ESTABLISHED,RELATED -o docker0 -j RETURN
iptables -A DOCKER-MAN -j RETURN
这样一来,LAN 口是可以访问容器暴露的端口,对与其他接口
,容器主动访问不受限制,而外面是无法直接访问容器的,做到了单项访问。
到这里,又有问题来了,如果我有一个容器比如 qBittorrent
,暴露的端口就是希望从外部(公司)等管理的,这样一来就无法访问了,当然也有解决方案:
# 在 DOCKER-MAN 自定义链接加入对 172.17.0.9 (需要放行的容器ip) 的放行
iptables -I DOCKER-MAN -d 172.17.0.9 -o docker0 -j RETURN
这样一来,这个容器就可以被正常访问了
最后一个问题,Bridge
网络下面的 ip
地址不是固定的,每次重启 Docker daemon
都有可能改变容器的 ip
这样手动操作起来就相对比较麻烦了,所以在 luci-app-dockerman中加入了访问控制
选项,可以轻松实现对容器的访问控制
Macvlan 网络
Macvlan 网络的真的是好处多多,有兴趣的同学自己翻阅资料查看,使用 macvlan
网络就基本和虚拟机的桥接模式类似,而且不存在 Bridge
网络的端口暴露的风险,在 Openwrt
下使用 macvlan
网络最大的问题就是无法上网的问题。
这里讲一个简单的方案,首先通过 Docker
新建 macvlan
网络
docker network create -d macvlan \
--subnet=192.168.3.0/24 --gateway=92.168.3.1 \
-o parent=br-lan \
-o macvlan_mode=bridge \
macnet
请注意这里的subnet
不要和其他接口冲突(若要使用同网段后面会讲),parent
使用br-lan
,然后在 Openwrt
上创建 macvlan
设备
ip link add link br-lan docker_mac0 type macvlan mode bridge
ip link set docker_mac0 up
接下来 Openwrt
中添加接口,你也可以在 luci
中添加
uci set network.docker_mac0=interface
uci set network.docker_mac0.ifname=docker_mac0
uci set network.docker_mac0.proto=static
uci set network.docker_mac0.ipaddr=192.168.3.1
uci set network.docker_mac0.netmask=255.255.255.0
uci commit network
将这个接口加入到防火墙中的 LAN zone
uci set firewall.@zone[0].network="br-lan docker_mac0"
uci commit firewall
至此,Docker macvlan
网络就可以正常使用了,这个步骤相对比较简单,但是网络重启或者 Openwrt
重启的时候就会失效,解决这个问题,已经在 luci-app-dockerman 实现,当创建 macvlan
网络时,dockerman 会自动做好这些工作,网络重启也会自动添加,删除网络,则会自动删除创建的 macvlan
网络。
Macvlan 进阶
有些老哥觉得用这个方案 macvlan
网络,使用的是与 LAN
不同的网段,访问容器会存在转发。
解决这个其实很简单,禁用 br-lan 的 DHCP, 同时开启 docker_mac0
的 DHCP
就可以,这样路由器下的所有主机和容器内的所有主机都在同一个网段之下了。
所以,如果你开始就想用这个进阶方案的话,从创建 macvlan
网络的时候就应该规划好自己偏好的网段。
好了,分享就这么多,感谢捧场
宿主 ip add 里没有新建的lan接口信息
然后我手动尝试了一下添加
ip link add link br-lan docker_mac0 type macvlan mode mac0
Error: argument of "mode" must be "private", "vepa", "bridge", "passthru" or "source", not "mac0"
/etc/config/dockerd
把 option iptables '0' 设置为 0
docker现在在未指定network_mode=bridge 的情况下默认使用自定义网桥而不是默认网桥,自定义网桥也许会和内网冲突,所以手动建立一个网桥(我是用docker-compose的)
networks:
docker1:
name: br-docker
ipam:
driver: default
config:
- subnet: 172.24.199.0/24
我没用过默认网桥,因为默认网桥真的问题很多,比如不能指定IP,容器间不能通信隔离等等,所以我也就没有测试默认网桥下的方案,不过现在openwrt的默认配置会给默认网桥docker0创建一个防火墙区域,直接手写防火墙规则也是可以的。
手动创建一个 docker bridge 指定桥接到 br-lan
docker network create -d bridge \
--subnet=192.168.5.0/24 --gateway=192.168.5.1 \
-o "com.docker.network.bridge.name"="br-lan" lanet
其中子网设置为 openwrt LAN 的子网,然后网关指定为 br-lan 网关,比如我的是 192.168.5.0/24
然后就可以在 dockerman 里面启动容器指定使用这个网桥,也支持指定 IP:
这样启动后,就可以正常使用了,能够达到预期目的:
与 LAN 处于相同子网
每个容器独立 IP,且能够指定 IP
与其他接入 openwrt 的设备保持一致,也就是可以按需去做端口映射来暴露公网
博主你好,我在使用dockerman创建macvlan给容器使用时遇到无法与宿主机通讯的问题。
具体步骤如下,我的家庭网络为192.168.5.*,openwrt为192.168.5.1,
我在网络界面创建macvlan接口,父网卡br-lan,模式桥接,创建macvlan接口打钩,子网192.168.5.0/24,网关192.168.5.9,ip范围和排除ip留空,创建
创建之后在openwrt网络接口能看到docker macvlan接口,防火墙里面能看到和br-lan一起绑定的,
但是就是无法与宿主机通讯,导致容器无网络。
设置步骤完全参考esir之前的视频完成,
https://youtu.be/jXMgAz_GQxI?si=gCoflU65Pd_CaQa6
有尝试过网管设置为其他地址,无用
手动创建一个 docker bridge 指定桥接到 br-lan
docker network create -d bridge \
--subnet=192.168.5.0/24 --gateway=192.168.5.1 \
-o "com.docker.network.bridge.name"="br-lan" lanet
其中子网设置为 openwrt LAN 的子网,然后网关指定为 br-lan 网关,比如我的是 192.168.5.0/24
然后就可以在 dockerman 里面启动容器指定使用这个网桥,也支持指定 IP:
这样启动后,就可以正常使用了,能够达到预期目的:
与 LAN 处于相同子网
每个容器独立 IP,且能够指定 IP
与其他接入 openwrt 的设备保持一致,也就是可以按需去做端口映射来暴露公网
按照你的方法搞定了 谢谢大佬
docker会将容器内的端口暴露给所有的网卡 而且op默认允许操作 iptables 建议直接关掉 然后用端口转发特定的服务 安全些 把 option iptables '1' 改成 0 再重启dockerd
config globals 'globals'
option alt_config_file '/etc/docker/daemon.json'
option data_root '/opt/docker/'
option log_level 'warn'
option iptables '1' # 改成0
手动创建一个 docker bridge 指定桥接到 br-lan
docker network create -d bridge \
--subnet=192.168.5.0/24 --gateway=192.168.5.1 \
-o "com.docker.network.bridge.name"="br-lan" lanet
其中子网设置为 openwrt LAN 的子网,然后网关指定为 br-lan 网关,比如我的是 192.168.5.0/24
然后就可以在 dockerman 里面启动容器指定使用这个网桥,也支持指定 IP:
这样启动后,就可以正常使用了,能够达到预期目的:
与 LAN 处于相同子网
每个容器独立 IP,且能够指定 IP
与其他接入 openwrt 的设备保持一致,也就是可以按需去做端口映射来暴露公网
整理了一篇文档:openwrt 自定义网桥