Hi y'all,
I am in the process of creating a preconfigured OpenWrt image to supply to a couple of sites.
To make life easy, I'd like to set them up as a DHCP-Client device to hook them into existing networks. But if the device is not hooked into an existing network, the device should automatically assume a static IP and start distributing DHCP-leases to clients.
In theory, this SHOULD work: Just add a 2nd Interface aliasing the 1st Interface with static IP and a non authorative dhcp-server.
But somehow I am always running into an issue.
-
1st IF: DHCP on br-lan, 2nd IF static on br-lan
Internet works, but no local network access and no DNS after reboot. Restarting the 2nd IF brings local addresses and dns back online.
-
1st IF: DHCP on br-lan, 2nd IF static on alias @1st-lan
DHCP Interface works, but static interface does only work when 1st interface has received a dhcp-adress, which is useless.
-
1st IF: DHCP on alias @2nd-lan, 2nd IF static on br-lan
Internet works, but no local network access and no DNS. restarting interfaces does not help.
Does anyone know about this and knows how to fix this?
For my testing I used a Raspberry Pi 4 + an amd64 VM in Proxmox, both Squashfs, compiled and heavily preconfigred by myself.
at the moment i think the best solution would be to just add an ifup lan2 to the startup routine, but this seems very hacky.
What are the devices in question?
What is the purpose of these devices on the networks when deployed? (Router, AP, some other purpose/service)?
Raspberry Pi 4 + an amd64 VM in Proxmox. Also Nanopi R3S LTS but I haven't tested these yet.
The use case is pretty wide but in a nutshell, it is a cloud solution, but at home: This is the software we're running on top of it: https://cosmos-cloud.io/
It's a web based server / app management including remote access, storage and backup, reverse proxy, auth via proxy or openid, monitoring and more.
The only things missing is routing/firewall and os package / update management, which is why I am using OpenWrt for this.
after a lot of testing and researching, I figured OpenWrt is simply not capable of doing this on its own. I created a script which does what I want. Two issues arised while trying to achieve this:
- OpenWrt does NOT support having 2x IP's on the same NIC, even not with aliases due to the described issues.
- Additionally, OpenWrt fails to detect a hotplug event when you plug in an ethernet-cable. It's simply ignored by hotplug. There are several threads about this as old as +10yrs out there.
My solution is a routine listening to logread about a cable plugged into eth0. The routine expects br-lan with eth0 as device and 2x Interfaces lan or dhcp and lan11 for static.
required packages: bash procps-ng-pkill
/etc/init.d/staticFallback
#!/bin/sh /etc/rc.common
# description: Fallback to static IP if dhcp-client does not get an IP after 30s
# processname: /bin/staticFallback
START=99
STOP=01
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /bin/bash "/bin/staticFallback"
procd_append_param command daemon
procd_set_param pidfile /var/run/staticFallback.pid
procd_set_param term_timeout 60
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn 150 10 10
procd_close_instance
}
stop_service() {
/usr/bin/pkill -f --signal SIGTERM staticFallback
}
/bin/staticFallback
#!/bin/bash
# description: Fallback to static IP if dhcp-client does not get an IP after 30s
# processname: /bin/staticFallback
loglevel="DEBUG" #INFO is default, DEBUG for more infos
nic="eth0" #Device to listen to hotplug events (should be the physical nic, like eth0)
bridge="br-lan" #bridge-device that is used as lan-bridge, default is br-lan
dhcp="lan" #Interface with dhcp-client IP configuration
static="lan11" #Interface with static IP configuration
delay=30 #how may seconds to wait for a dhcp-address before configuring the static IP
log() {
[ "${loglevel}" == "DEBUG" ] && logger -t staticFallback "${1}"
}
while :; do
#wait until network device is up
(logread -f & ) | grep -q "Network device '${nic}' link is up"
#only do something if config is as expected (dhcp-nic is dhcp-client and static-nic is static)
if [ "$(uci get network.lan.proto)" == "dhcp" -a "$(uci get network.lan11.proto)" == "static" ]; then
#make sure of nic state ( set dhcp-client up and static down )
log "bring nics into default state (${dhcp} up and ${static} down)"
ifup "${dhcp}" && ifdown "${static}"
#check the local IP of the nic the script listens to
log "check the local IP of the nic the script listens to"
localIP="" && count=0
while [[ -z "${localIP}" && ${count} -le ${delay} ]]; do
localIP=$(ip -4 addr show "${bridge}" | grep -oP "(?<=inet ).*(?=/)")
sleep 1
((count++))
log "#${count}: localIP is: ${localIP}"
done
#check if the Interface did not receive an IP
( [ -n "${localIP}" ] && log "found dhcp-client IP: ${localIP}" ) || ( log "found no IP, start static nic" && ifdown "${dhcp}" && ifup "${static}" && service dnsmasq reload )
count=0
while [[ -z "${localIP}" && ${count} -le ${delay} ]]; do
localIP=$(ip -4 addr show "${bridge}" | grep -oP "(?<=inet ).*(?=/)")
sleep 1
((count++))
done
logger -t staticFallback "staticFallback-routine completed, current LAN-IP is: ${localIP}"
else
log "${dhcp} and ${static} are not setup as expected, do nothing"
fi
done