I made this script to regain DHCP lease after a static profile has been chosen. Use a cronjob or systemd time to execute periodically. I prefer the systemd timer because i like to gather my logs with journalctl. It seems to be working nicely... I've checked reboots, unlinking and router reset. When the router resets, i get a static fallback ip, two minutes later, my Pi is back online by DHCP. You need nmap installed to detect the DHCP server (in a different subnet).
/sbin/dhcp-recheck.sh
Code: Select all
#!/bin/bash
UPSTREAM=""
function get_upstream() {
# Look for a default gateway
UPSTREAM=$(ip r | grep default | cut -d ' ' -f 3)
}
function reach_upstream() {
# exit code 0 = reachable, 1 = unreachable
return $(ping -q -w 1 -c 1 ${UPSTREAM} > /dev/null)
}
NIC=""
function reach_dhcp_server() {
# Find nics by ifconfig
nics=($(ifconfig | egrep -ow 'eth[0-9]{1,2}'))
for nic in ${nics}; do
# If a DHCP server is found, set it on $NIC and break
reach_dhcp_server_on_interface ${nic} && { NIC=${nic}; return 0; }
done;
}
function reach_dhcp_server_on_interface() {
local interface=${1}
# nmap command to find a DHCP server on an interface
local nmap_command="sudo nmap --script broadcast-dhcp-discover -e ${interface}"
# exit code 0 = router, 1 = no router
return $(${nmap_command} 2>/dev/null | grep Router | egrep -wo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' > /dev/null)
}
function reset_ip() {
# Tell dhcpcd to rebind $NIC
dhcpcd -n ${NIC}
}
# Detect if there's an upstream and if it's reachable. If so, exit
get_upstream
if ! [ -z ${UPSTREAM} ]; then
echo "Trying to ping ${UPSTREAM}"; reach_upstream && echo "Ping succeeded, keeping IP"; exit 0 || echo "Ping failed..."
fi
# Check for a DHCP server. If not found, exit
echo "No upstream, checking for DHCP server"; reach_dhcp_server || { echo "DHCP server not found"; exit 0; }
# Lets go
echo "DHCP server found, resetting IP"; reset_ip
----------------
Here's the systemd stuff
/lib/systemd/system/dhcp-recheck.service
Code: Select all
[Unit]
Description=Restarts dhcpcd if there's no internet but a DHCP server is found
[Service]
Type=oneshot
ExecStart=/sbin/dhcp-recheck.sh
/lib/systemd/system/dhcp-recheck.timer
Code: Select all
[Unit]
Description=Run dhcp-recheck every 2 minutes
[Timer]
OnCalendar=*:0/2
#When missed a cycle, do not rechedule on reboot
Persistent=False
[Install]
WantedBy=timers.target
To start running:
Code: Select all
systemctl enable dhcp-recheck.timer && systemctl start dhcp-recheck.timer
Last but not least i'll include my dhcpcd.conf bc with this configuration you can add additional NIC to the Pi and it doesn't matter which end you connect... One side works by DHCP and the other end is still available on 192.168.0.1... switching cables ends up the same
Code: Select all
profile static_eth
static ip_address=192.168.0.1
dhcp
# Try DHCP first, else fall back to static
interface eth0
fallback static_eth
# Try DHCP first, else fall back to static
# This enables us to plug in an additional ethernet adapter;
# one of them will be accessible for internet, the other one for a direct connection
interface eth1
fallback static_eth
Use nmap to find your pi (look for port 22). This is in my routers subnet 192.168.1.x/24
nmap 192.168.1.1/24
Or just connect on the local domain if your network services allow.
ssh
pi@pi0008.local