Associated stations - making hostnames visible across multiple APs

dropbearkey ssh-keygen -t rsa -f ~/.ssh/id_dropbear`

1 Like
root@OpenWrt:~# ssh-keygen -t rsa -f ~/.ssh/id_dropbear
-ash: ssh-keygen: not found

I think you don't understand my question.

I want to paste SSH key using command line and not in Luci.

Yep. You need to add it. Or just use the dropbearkey stanza if you want to replicate the OP’s method. Generating public and private keys

1 Like

can you show me?

From your animation, yes you should be able to use a dropbearkey to copy the public key to LuCI/Administration/SSH-Keys. I believe it is OpenSSH compatible, but if you want to replicate the OP’s post, the dropbearkey` is required because Dropbear needs the keys in a different format to OpenSSH. Reread the wiki link.

1 Like

When you add SSH keys via the UI it saves them to /etc/dropbear/authorized_keys
I haven't tested this, but in theory that means you could just append them to that file via the cli. Eg: echo "ssh-rsa abcd123 etc" >> /etc/dropbear/authorized_keys

2 Likes

Exactly what I needed! Your solution worked perfectly. Thanks a lot!

If your problem is solved, please consider marking this topic as [Solved]. See How to mark a topic as [Solved] for a short how-to.

Just a word of warning: before you start to use the newly created keys for scheduled jobs, it would be a good idea to run the same command from a prompt, so you can answer "yes" to the fundamental question:

Host 'your.access.point.local' is not in the trusted hosts file.
(ssh-ed25519 fingerprint SHA256:<gibberish>)
Do you want to continue connecting? (y/n)

Otherwise, a regular ssh from your router to the AP (using the key for authenthication) would be enough.

Also: thanks for the tutorial above!

Thank you for the idea and the tutorial! I decided that I would prefer the DHCP not to show up on the APs' status pages, so I decide to populate the /etc/ethers instead, as suggested on the wiki page. Combined with your script, my solutions looks like this, in case anyone else wants to do this:

#!/bin/sh

# List of access points to sync with
access_points="10.98.0.10 10.98.0.11"

# Path to the dhcp.leases file on the main router
dhcp_leases_file="/tmp/dhcp.leases"

# Destination on the access points
destination="/etc/ethers"

# Path to the SSH private key
ssh_private_key="/etc/dropbear/private_key"

# Path where to store the generated ethers file
temp_file="/tmp/sync_dhcp_ethers"

(
echo "## This file has been autogenerated by $0 on $(uname -n)"
cat /etc/ethers
echo ""
echo "## Ethers generated from $dhcp_leases_file"
awk '{print $2" "$4}' "$dhcp_leases_file"
) > "$temp_file"

# Loop through each access point and copy the dhcp.leases file
for access_point in $access_points; do
    scp -q -i "$ssh_private_key" "$temp_file" "root@$access_point:$destination"
done

EDIT: Also, don't forget to add the path to your script to /etc/sysupgrade.conf to keep it during updates

1 Like

This is much cleaner for dumb APs. One additional note, this method was not showing IPs next to the hostnames for me. To address that, I'm using it in conjunction with the fping method to get those IPS intermittently.
Install fping on the dumb AP and add this to the scheduled tasks (adjust for your subnet):

*/15 * * * * fping -g 192.168.1.0/24

drove me crazy but I had to remove openssh-client first to be able to follow your instructions

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. 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.

#!/bin/sh

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 /etc/dhcp.leases | 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.

1 Like

Nice! Had to make some adaptations for the default lease file location (uci get dhcp.@dnsmasq[0].leasefile) and to strip the O options for dropbear scp.