What's new

SSH Key Setup: ASUS-Merlin Router to AIMesh Nodes - Password(Post#19)-Passwordless(Post#16)

THANKS to all that helped me. i now have a UI script that compares router/node wireless stats with sortable columns, clickable refresh on demand button, clickable show wired button, highlights new device connection. Im sure i'll add/delete columns as I tinker about.
 
Last edited:
I am assuming you tried this and it worked for you?

Edit: sorry, grumpy today. Looks like it does!
Yup sure did.

TBH it took a while to get the final version as posted, I keep catching AI out telling little porkies, but got there eventually. Not at all ungrateful for your posts with your posted commands, just wasn’t confident in myself to do it that way.

So I thought I’d take a stab at it myself and post to help others out like me, who might need a few more details and steps.

The comment about “better AI” was very much tongue in cheek.
 
Yup sure did.

TBH it took a while to get the final version as posted, I keep catching AI out telling little porkies, but got there eventually. Not at all ungrateful for your posts with your posted commands, just wasn’t confident in myself to do it that way.

So I thought I’d take a stab at it myself and post to help others out like me, who might need a few more details and steps.

The comment about “better AI” was very much tongue in cheek.
Yes, lots of ways to skin that cat. However, sometimes AI skins the furniture and confidently claims it was a cat. Saw that extra step to create the public key file and got confused. Sorry again!
 
Yes, lots of ways to skin that cat. However, sometimes AI skins the furniture and confidently claims it was a cat. Saw that extra step to create the public key file and got confused. Sorry again!
I’m not sure I follow sorry, is that step not needed?
 
I’m not sure what the query is here sorry, is that step not needed?
your instruction was perfect, worked first time for me, thank you again, i even learned gemini for the next person who asks.
 
I’m not sure I follow sorry, is that step not needed?
I think the keygen step creates both the private and public files. At least it did when I tried it last.
 
I think the keygen step creates both the private and public files. At least it did when I tried it last.
TBH I didn’t check for that rigorously on the way through, so I cannot say whether I saw both public and private keys being generated and both actively saved in the folder, on issuing the first line in Step 1.

I might go and check later for completeness, but I’m a wee bit wary of stuffing up my now working system.
 
I realize this thread has found it's answer, and has gone over 2 different methods (with SSH keys and an opkg package installation)

But for completeness in case someone else finds this thread some day, I'll mention a 3rd way to pull node data from the primary router.
(Which doesn't require installing entware / special opkg packages, and doesn't require any SSH keys to do SSH connections.)

Instead, the 3rd method is by using curl from the primary router to login to the WebUI of the node (which shares the same password as the primary) and sending web requests to the nodes web interface to pull nvram data or trigger actions.
For example:
Code:
    htmlContent="$(curl -s -k "${nodeURL}/appGet.cgi?hook=nvram_get(productid)%3bnvram_get(firmver)%3bnvram_get(buildno)%3bnvram_get(extendno)%3bnvram_get(webs_state_flag)%3bnvram_get(lan_hostname)%3bnvram_get(webs_state_info)%3bnvram_get(label_mac)" \
    -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' \
    -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
    -H 'Accept-Language: en-US,en;q=0.5' \
    -H 'Accept-Encoding: gzip, deflate' \
    -H 'Connection: keep-alive' \
    -H "Referer: ${nodeURL}/index.asp" \
    -H 'Upgrade-Insecure-Requests: 0' \
    --cookie "$cookieFile" \
    --max-time 2 2>/dev/null)"
    curlCode="$?"

Doing it this way is probably one of the least utilized methods I've seen (other than within MerlinAU).
I'll admit doing it by web request is more restrictive in it's scope and ability, especially when compared to methods like SSH for obvious reasons..

But doing it by web request also has its benefits, such as more simplistic setup than SSH keys and less dependencies than entware packages, and instead just leverages functions the node already has built in. (Such as nvram_get as seen in the example above)
So far doing it this way has been reliable enough for MerlinAU without having to do a single change to the web requests over "years" of different firmware releases.
 
Last edited:
I realize this thread has found it's answer, and has gone over 2 different methods (with SSH keys and an opkg package installation)

But for completeness in case someone else finds this thread some day, I'll mention a 3rd way to pull node data from the primary router.
(Which doesn't require installing entware / special opkg packages, and doesn't require any SSH keys to do SSH connections.)

Instead, the 3rd method is by using curl from the primary router to login to the WebUI of the node (which shares the same password as the primary) and sending web requests to the nodes web interface to pull nvram data or trigger actions.
For example:
Code:
    htmlContent="$(curl -s -k "${nodeURL}/appGet.cgi?hook=nvram_get(productid)%3bnvram_get(firmver)%3bnvram_get(buildno)%3bnvram_get(extendno)%3bnvram_get(webs_state_flag)%3bnvram_get(lan_hostname)%3bnvram_get(webs_state_info)%3bnvram_get(label_mac)" \
    -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/115.0' \
    -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8' \
    -H 'Accept-Language: en-US,en;q=0.5' \
    -H 'Accept-Encoding: gzip, deflate' \
    -H 'Connection: keep-alive' \
    -H "Referer: ${nodeURL}/index.asp" \
    -H 'Upgrade-Insecure-Requests: 0' \
    --cookie "$cookieFile" \
    --max-time 2 2>/dev/null)"
    curlCode="$?"

Doing it this way is probably one of the least utilized methods I've seen (other than within MerlinAU).
I'll admit doing it by web request is more restrictive in it's scope and ability, especially when compared to methods like SSH for obvious reasons..

But doing it by web request also has its benefits, such as more simplistic setup than SSH keys and less dependencies than entware packages, and instead just leverages functions the node already has built in. (Such as nvram_get as seen in the example above)
So far doing it this way has been reliable enough for MerlinAU without having to do a single change to the web requests over "years" of different firmware releases.
Thanks @ExtremeFiretop that looks pretty good.

It does though (with all due respect) bring me back to the early Unix days and the Obfuscated C Code Contest. One line of C code.


At least you put that code on multiple lines ;-)
 
Thanks @ExtremeFiretop that looks pretty good.

It does though (with all due respect) bring me back to the early Unix days and the Obfuscated C Code Contest. One line of C code.


At least you put that code on multiple lines ;-)

😄 Guilty as charged.
I actually tried pasting the real, working helper functions here, but the forum kept throwing: (“Oops! We ran into some problems…”) even when wrapping everything in "[.CODE]…[./CODE]"

1772420166348.png


So the snippet I posted is the “essentials only” version without the forum thinking I'm trying to hack/spam something and throw a fit.
And let’s be honest… curl posts almost always look like an IOCCC entry once the headers and URL encoding pile up 😅

If you want the complete implementation, MerlinAU has the full working functions starting here:
https://github.com/ExtremeFiretop/M...f30001a50eaf005fc2f1b4e48ff/MerlinAU.sh#L4960
 
Last edited:
TBH I didn’t check for that rigorously on the way through, so I cannot say whether I saw both public and private keys being generated and both actively saved in the folder, on issuing the first line in Step 1.

I might go and check later for completeness, but I’m a wee bit wary of stuffing up my now working system.

OK, I just wanted to ensure the mechanism I posted above was sound and whether both lines were needed. On my second (independent) and local network, which did not have any keys in the /jffs/.ssh dir, running the first line (only) creates both id_dropbear AND id_dropbear.pub. @rung was correct to query this. Immediately after I ran the first line I rebooted the router and the two files were persistent; the same key was still in the .pub file. Note that the first line also prints out the key on the SSH terminal (Putty) screen, along with a Fingerprint line (which is NOT part of the key).

It seems the AI I used may have harvested the original details from (inter-alia) a snbforums post started in 2014, with a relevant update in 2016 which notes "1. dropbear never generates id_rsa.pub file, hence, never saves it anywhere. 2) whatever ssh authorisations were done, to the or from the router, all is gone after a reboot".

However a limited check of https://github.com/mkj/dropbear/releases shows that as of dropbear 2024.84 (if not earlier) issuing the first line automatically also saves the id_dropbear.pub file when generating the id_dropbear file. Merlin FW 3006.102.7 ships with (I believe) dropbear 2025.89, so @rung is correct - one line creates both keys.

I have amended the original how-to post above with a version note: For FW with dropbear 2024.84 and later - one line creates both keys (Merlin FW 3006.102.7 e.g. has dropbear 2025.89).
Much older FW versions (with corresponding older dropbear versions) may require the second line; but are unlikely to.
 
OK, I just wanted to ensure the mechanism I posted above was sound

Excellent job! - particularly isolating exactly where the megacorps scraped our user's valuable advice and injested it blindly into their stolen data blobs.

However, since your instructions are so detailed and clear, you may consider augmenting them again to add save and restore steps of the critical files in ~/.ssh, "id_dropbear" and "known_hosts" during reboot. Otherwise, the user will have to manually recopy the key file and redo the "one at a time" step to regain the known_hosts info. Should be straight forward thing to add the steps to the services-start file. I save mine in usb, so my copies would have to be in the post-mount file if I needed this functionality.

Rung
 
However, since your instructions are so detailed and clear, you may consider augmenting them again
Ouch. Look, I don't think that's particularly fair.

I never claimed to be an expert on this. I wanted to set this up this for a while, I found a (methodical) way to do it that I personally felt comfortable with and (rightly or wrongly) posted what worked for me, hoping it might help someone else; which it did.

There was never any intent to undermine your input and I sincerely apologise if you feel I have done that.

Otherwise, the user will have to manually recopy the key file
I thought that was what (the existing) Step 2 (which is saved) and 3 (which is persistent at reboot) does?
Sorry, not being obtuse, but I genuinely thought this was covered in the steps in the post.

Add public key to Main GUI​

Go to Main GUI, Administration, System, Authorized Keys field. Paste the key and click Apply.

Add persistence to Main services-start​

Add this line to /jffs/scripts/services-start on Main:

cp /jffs/.ssh/id_dropbear /tmp/home/root/.ssh/id_dropbear
 
Last edited:
Ouch. Look, I don't think that's particularly fair.

Oh no! I totally meant that as a compliment. It was clear and step by step! You even had feedback that it worked for someone. Sorry if I didn't say that properly.
 
Oh no! I totally meant that as a compliment. It was clear and step by step! You even had feedback that it worked for someone. Sorry if I didn't say that properly.
I'm really sorry, seems it was my turn to be tired and grizzly :) !

I think a lot of folks are rightly sceptical of anyone using AI to help (and I acknowledge I do use it as a tool from time to time but am of the opinion you actually have to know or have a feeling for the right answer, interrogate it for any BS and test it yourself), so I thought in the first instance you found me to be lazy and somewhat circumspect, then I took umbrage with your subsequent note as if my instructions "are so detailed and clear "... why would they need augmenting (especially if I thought the persistence on reboot was already there) .... actually is it (genuine question!?)

No harm done, I think we've come at it from two sides and got a result, your comments made me check it out properly and improve the initial stab at it, so overall a good outcome for the community. Cheers, k.
 
I'm really sorry, seems it was my turn to be tired and grizzly :) !

I think a lot of folks are rightly sceptical of anyone using AI to help (and I acknowledge I do use it as a tool from time to time but am of the opinion you actually have to know or have a feeling for the right the answer, interrogate it for any BS and test it yourself), so I thought in the first instance you found me to be lazy and somewhat circumspect, then I took umbrage with your subsequent note as if my instructions "are so detailed and clear "... why would they need augmenting (especially if I thought the persistence on reboot was already there) .... actually is it (genuine question!?)

No harm done, I think we've come at it from two sides and got a result, your comments made me check it out properly and improve the initial stab at it, so overall a good outcome for the community. Cheers, k.
So glad you are not offended anymore! The dangers of text communication. I did totally miss the persistence section (if my own defense, it was not in the post, but in the attachment. Still no excuse). However, shouldn't we also have them save and restore the knownhosts file? Reason is, the automated tools may not expect the warning on first run.
 
So glad you are not offended anymore! The dangers of text communication. I did totally miss the persistence section (if my own defense, it was not in the post, but in the attachment. Still no excuse). However, shouldn't we also have them save and restore the knownhosts file? Reason is, the automated tools may not expect the warning on first run.
OK, I'm hanging on by a fine thread here because I am waaaaaaaaay out of my depth :-).

My vibe coding of several scripts resulted in
Code:
-o StrictHostKeyChecking=no
in those scripts, which (apparently) meant I did (do) not need to worry about known_hosts being persistent (and why I thought we were done).

HOWEVER I agree, I think we need to ensure it is persistent, in case folks do NOT add that switch to their scripts.
I propose this, at the end of step 5.

===================================================================
Once all nodes have been accepted, save known_hosts to jffs for persistence:

Code:
cp /tmp/home/root/.ssh/known_hosts /jffs/.ssh/known_hosts

Then add this line to /jffs/scripts/services-start on Main (below the id_dropbear line you added in step 3):
Code:
cp /jffs/.ssh/known_hosts /tmp/home/root/.ssh/known_hosts
You will never be prompted again after this — even across reboots.
====================================================================
[EDIT] How to post updated.
 
Last edited:
OK, I'm hanging on by a fine thread here because I am waaaaaaaaay out of my depth :-).

My vibe coding of several scripts resulted in
Code:
-o StrictHostKeyChecking=no
in those scripts, which (apparently) meant I did (do) not need to worry about known_hosts being persistent (and why I thought we were done).

HOWEVER I agree, I think we need to ensure it is persistent, in case folks do NOT add that switch to their scripts.
I propose this, at the end of step 5.

===================================================================
Once all nodes have been accepted, save known_hosts to jffs for persistence:

Code:
cp /tmp/home/root/.ssh/known_hosts /jffs/.ssh/known_hosts

Then add this line to /jffs/scripts/services-start on Main (below the id_dropbear line you added in step 3):
Code:
cp /jffs/.ssh/known_hosts /tmp/home/root/.ssh/known_hosts
You will never be prompted again after this — even across reboots.
====================================================================
[EDIT] How to post updated.
interesting, it worked for me first go around, yes you had to read attachments. Gemini had added -o StrictHostKeyChecking=no in my script, so i didnt need known_hosts. thank you so much!
 

Latest threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Back
Top