Dual network port host installs openwrt through docker to implement routing

Since I have been using docker for a long time to install some services, and pve, which is a virtualization solution with qemu as the bottom layer, I felt that I couldn’t bear it, so I spent 2 days and fiddled with a lot of things, and finally got it done. Share it to prevent others from stepping into the trap.

Let’s start with a picture:

Run Interface

Precondition

You probably need to understand some of the following:

  • Use of Linux
  • docker use
  • docker network mode, including macvlan
  • openwrt configuration and usage

If you don’t understand, can you search for the specific steps on your own?

Method

I have studied the methods of several experts on the Internet, among which the dual network port solution of Luoshui Fushen is mainly used, but its method seems to be unable to succeed on my little chicken. The main reason is the campus network login. question. So just use the docker bridge directly, use it as a NAT to distribute an address, and then open the route from the docker0 bridge to the external network. See my network topology diagram below.

Network Topology
Among them, there are two physical network ports, namely enp1s0 and enp2s0. enp1s0 is connected to the campus network, but it can only authenticate login and be assigned an IP address. It is not possible to obtain another IP address through macvlan virtualization of enp1s0. Maybe it will work. , but I didn’t figure it out. enp2s0 is another network port. I connected it to my desktop computer and used it as a lan port later.

Looking inside the host, the main parts related to the network, I used two containers, one is used to log in to the campus network, and a script is run inside to log in to the campus network to ensure that Xiaojizi is always online, because it needs to ensure that The enp1s0 port has a network, so let it use the host mode in the docker network, use the host network directly, and then log in to the authentication page to get the upper routing address. Another container is OpenWRT, which virtualizes two network ports, namely the WAN port and the LAN port. The WAN port uses docker’s bridge network and docker’s NAT function to get an IP address in docker0; the other LAN The port uses macvlan mode, defines a network segment by itself, and then lets enp2s0 virtualize the macvlan to communicate with windows.

Steps

Each step is reproduced below. The environment is:

  • Ubuntu 20.04 LTS
  • docker
  • J4125 dual network port machine

Step 1 Turn on the network card promiscuous mode

View network card

ip addr

PROMISC
If there is no PROMISC field, use the following command to start:

 ip link set enp1s0 promisc on
ip link set enp2s0 promisc on

For persistence, since the network management method adopted by Ubuntu is different from previous versions, I wrote a simple script.

 vim /etc/network/if-up.d/promisc

Then fill in the following content, which is equivalent to automatically turning the network card into promiscuous mode every time it is started.

#!/bin/bash

/sbin/ip link set enp1s0 promisc on
/sbin/ip link set enp2s0 promisc on

Then add execution permissions

 chmod + x /etc/network/if-up.d/promisc

Step 2 Enable IPv4 forwarding

Enable the IPv4 forwarding function on the host, which is Xiaojizi’s Ubuntu:

vi /etc/sysctl.conf

# Uncomment net.ipv4.ip_forward = 1
# Or add net.ipv4.ip_forward = 1

# Reload configuration
sysctl -p /etc/sysctl.conf

Step 3 Configure LAN port

First write a template file as a persistent file for the /etc/config/network network configuration when docker starts:

 vim /home/[UbuntuUser]/openwrt/network

The content is as follows. This is actually based on the network configuration file of openwrt. Different versions may be different, but they are similar:

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option packet_steering '1'

config device
        option name 'br-lan'
        option type 'bridge'
        list ports 'eth0'

config interface 'lan'
        option ifname 'br-lan'
        option proto 'static'
        option ipaddr '192.168.10.2'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option ifname 'eth1'
        option proto 'dhcp'
        option gateway '172.17.0.1'
        option dns '8.8.8.8 8.8.4.4'

Configure LAN port macvlan: Create a virtual network card named maclan, and then fix the IP address:

 docker network create -d macvlan --subnet=192.168.10.0/24 --gateway=192.168.10.1 -o parent=enp2s0 maclan
docker network ls

maclan

Step 4 Create openwrt container

Use the image to create a docker container. The openwrt container image I used is: sulinggg/openwrt:x86_64. We first create the container and connect the lan port.

 sudo docker run --restart always --name openwrt -d --network maclan --privileged --ip 192.168.10.2 -v /home/bencorn/openwrt/network:/etc/config/network sulinggg/openwrt: x86_64 /sbin/init

Then enter docker to configure the password:

 docker exec -it openwrt /bin/sh
passwd

Then configure a static IP on the windows connected to enp2s0 so that you can connect to the LAN port and configure OpenWRT

windows configuration

Browser input: 192.168.10.2, hit Enter, if nothing goes wrong you should be able to log in to openwrt

First login

Step 5 Configure WAN port

Connect the openwrt container to the bridge

 docker network connect bridge openwrt

WAN port

Step 6 Configure each port

First configure the LAN port in the web interface and select a physical interface eth0:

Select eth0 for the LAN port

Step7 Configure routing

This is also a relatively dangerous operation. You may be attacked by the Internet, but it doesn’t matter. Let’s do it.
Enter the openwrt container and check the network situation:

 docker exec -it openwrt /bin/sh
ping 8.8.8.8
ping www.baidu.com

query
If ping 8.8.8.8 can be queried, it means that the network is connected; if ping www.baidu.com cannot be connected, it means that the dns query needs to be configured and run directly in the container.

 echo "nameserver 8.8.8.8" > /etc/resolv.conf

If you still cannot connect to the Internet, check and configure the host routing to ensure that you can connect to the Internet:

 iptables -t nat -L -n -v
iptables -A FORWARD -i docker0 -o [your external network interface] -j ACCEPT
iptables -A FORWARD -i [your external network interface] -o docker0 -j ACCEPT

Query routing and configuration

Others

I should be done here, but I am done anyway.

  • If that still doesn’t work, you can try setting the backup DNS to 1.1.1.1 or 8.8.8.8 on the statically configured Windows network.
  • If that doesn’t work, you can GPT-4
  • If it still doesn’t work, you can leave a message in the comment area