FWIW, here's the approach I have taken. Feel free to ignore it or take bits from it that you like.
Some background...
In order to reduce writes to /etc/ethers
on each AP, I symlink /etc/ethers
(on each AP) to a location, /tmp/etc/ethers
:
root@AP-Office:~# ls -la /etc/ethers
lrwxrwxrwx 1 root root 15 Apr 22 15:40 /etc/ethers -> /tmp/etc/ethers
I add the following to my /etc/rc.local
file on each AP:
if [ ! -f /tmp/etc/ethers ]; then touch /tmp/etc/ethers; fi
ln -sf /tmp/etc/ethers /etc/ethers
So when I copy 'ethers' from my router to my APs, I write to /tmp/etc/ethers
for each update on the AP.
The script below is an adaptation of several other ideas from the community. Basically, I keep a previous copy of 'ethers' so that I can compare (via hash) if the newly generated ethers file is the same as what was previously sent to the APs. In this way, I don't re-send duplicate updates. Reduces overhead/noise.
But if the newly generated ethers file is different than what was previously sent, I do the scp
in BatchMode
and background the process (note the trailing ampersand at the end of the scp
line). This allows for the push of the ethers file to go out to all the APs very quickly. If any AP is unreachable or the key for some reason doesn't work, it will not delay/block the push of the file to the other APs. The final wait
is to await the exit of the backgrounded processes.
#!/bin/sh
lease_file="/tmp/dhcp.leases"
ethers_file="/tmp/ethers"
ethers_file_prev="/tmp/ethers.prev"
ethers_log="/tmp/ethers-copy.log"
wap_hosts="AP-1.your.domain AP-2.your.domain AP-3.your.domain"
[ -f $ethers_file ] && cp "$ethers_file" "$ethers_file_prev"
cat "$lease_file" | awk '{print $2" "$4}' > "$ethers_file"
new_hash=$(md5sum "$ethers_file" | awk '{print $1}')
prev_hash=$(md5sum "$ethers_file_prev" | awk '{print $1}')
if [ "$new_hash" == "$prev_hash" ]; then
echo "$(date "+%F %H:%M:%S"): No ethers changes detected. Skipping push to WAPs." | tee -a "$ethers_log"
exit 0
fi
logger -t hotplug "Ethers file changes detected. Transferring update to WAPs."
for wap_host in ${wap_hosts}; do
echo "$(date "+%F %H:%M:%S"): Sending updated ethers to ${wap_host}" | tee -a "$ethers_log"
scp -o ConnectTimeout=10 -o BatchMode=yes -O "$ethers_file" "root@${wap_host}:/tmp/etc/ethers" 1>>"$ethers_log" 2>&1 &
done
wait
The above script is fired based on a hotplug event I set up:
root@OpenWrt:~# cat /etc/hotplug.d/dhcp/00-update-ethers
#!/bin/sh
HOME=/root
USER=root
/root/wap/update_ethers.sh
So only when DHCP related hotplug events occur (via dnsmasq), the script will fire. This allows for more real-time updating of the ethers on the APs.