dropbearkey ssh-keygen -t rsa -f ~/.ssh/id_dropbear`
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
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.
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
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
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
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.
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.
To be honest, I don't like any of the solutions for this problem. I was thinking, maybe a simple server/client pair written in C.
- Main router monitors new clients entering and leaving the network (server mode).
- Dumb AP establishes an unicast (avoid generating extra multicast noise) connection with the main router server (client mode).
- Main router sends all current info to dumb AP.
- Main router keeps updating the dumb AP with new info until the connection is closed.
Here is an idea that I may play with once I've some free time:
(this will only need to be run within the dumb AP, with minimal CPU overhead)
- C program takes a list of wlan interfaces to listen to via its argument list.
- Create a socket(AF_PACKET, SOCK_RAW | SOCK_NONBLOCK, htons(ETH_P_ARP)) for each interface.
- bind() each socket to their interfaces.
- Create a pipe to handle signals through pipe2(pipe, O_NONBLOCK)
- Set up signal handlers through sigaction() for SIGINT, SIGTERM and SIGHUP. Signal handlers write to pipe[1] once a signal is caught.
- Set up an epoll through epoll_create() and add each socket fd plus pipe[0] through epoll_ctl(), listening to the EPOLLIN event.
- epoll_wait() with a -1 timeout value (infinite).
- If EPOLLIN was triggered on any of the interfaces, read from their sockets, create a local heap-stored entry (MAC + IPv4 address) and add this entry to the system's ARP table through ioctl() with SIOCSARP. If the entry already exists and the IPv4 address is the same, we skip this, saving some syscalls in the process. If the entry already exists but the IPv4 address differs, delete the current entry from the system's ARP table through ioctl() with SIOCDARP, and add the new one.
- If EPOLLIN was triggered on pipe[0], delete all added entries from the system's ARP table and shutdown the program.
This should work correctly because we SHOULD be able to sniff on wlan frames before they are bridged.
Can you please tell us clearly where each script needs to be placed?
Maybe it'll work, but we will never know unless you or someone provides a working script
@pkmann This doesn't seem to be working on 23.5.05. Any way to fix?
Unfortunately i'm not too sure, I haven't moved to 23.05 yet.