Implement sshs config generator from known_hosts files
Relates to #6.
@jarrodCoombes this is the maximum I can do with known_hosts, using sshs generate --known-hosts it will generate Host, Hostname and Port for each entry.
--known-hosts is required because I though about doing the same thing but for bash/zsh history - not sure yet.
Do you see further improvements that can be made?
Ooh! I'll give it a go in a bit, but that sounds exactly like I was thinking and it'll be a great shortcut for getting the list populated.
I do like the idea of getting the info from the bash/zsh history, anything that allows semi-automated generation of the menu is a plus IMO.
Are the changes reflected in the pre-build binaries in the releases?
Are the changes reflected in the pre-build binaries in the releases?
Sadly no, you need to build it yourself. But it's just calling `makeˋ.
So I pulled down the source, installed Go, installed the other needed things it called for and compiled it. Running ssh generate --known-hosts spits out an error of unknown flag
sshs -v returns sshs version 1.5.0-2-g38cc2c9
What did I do wrong here?
Did you checkout to branch feature/generator-known-hosts?
@jarrodCoombes you can find a built version in the artifacts: https://github.com/quantumsheep/sshs/actions/runs/1828649999
I am new to github, so only know how to checkout the master branch, and did not know there was a feature branch. I'll need to look up how to do that. In the meantime, I grabbed the binary and tested it. It works well, but there are some issues.
In the known_hosts file you can actually have a single signature tied to multiple host names/ips.
My entry that looks like this:
[server.domain.tld]:222,[xx.xx.xx.xx]:222 ecdsa-sha2-nistp256 <key>
Gets parsed like this:
Host server.domain.tld]:222,[xx.xx.xx.xx
Hostname server.domain.tld]:222,[xx.xx.xx.xx
Port 222
Also this:
server2.domain.tld,server2,yy.yy.yy.yy ecdsa-sha2-nistp256 key
Parses to this:
Host server2.domain.tld
Hostname server2.domain.tld,yy.yy.yy.yy
Port 22
Other than that, it actually did a great job.
With your example, for instance:
[server.domain.tld]:222,[xx.xx.xx.xx]:222 ecdsa-sha2-nistp256 <key>
server2.domain.tld,server2,yy.yy.yy.yy ecdsa-sha2-nistp256 <key>
It gives this output in the last commit:
Host server.domain.tld:222
Hostname server.domain.tld
Port 222
Host xx.xx.xx.xx:222
Hostname xx.xx.xx.xx
Port 222
Host server2.domain.tld
Hostname server2.domain.tld
Port 22
Host server2
Hostname server2
Port 22
Host yy.yy.yy.yy
Hostname yy.yy.yy.yy
Port 22
What do you think ?
I think that leads to quite a bit of redundancy and clutter.
When given:
[server.domain.tld]:222,[xx.xx.xx.xx]:222 ecdsa-sha2-nistp256 <key>
server2.domain.tld,server2,yy.yy.yy.yy ecdsa-sha2-nistp256 <key>
It should return:
Host "server.domain.tld"
Hostname server.domain.tld
User <local signed in user>
Port 222
Host "server2.domain.tld"
Hostname server2.domain.tld
User <local signed in user>
Port 22
Basically your host and hostname should be everything up to the first comma (minus any port info). The bits in the known_hosts file that are separated by commas are going to almost always be either DNS host names or alternative IPs on that same server, so generating multiple entries based on each line would make the menu really redundant.
I suggest the quotes for the host because it looks like sshs uses that field as the target unless it is in quotes. Not sure if this is deliberate or not, but something I noted when testing this.
I think that leads to quite a bit of redundancy and clutter.
But what do you do for this:
[server.domain.tld]:222,[xx.xx.xx.xx]:222,[server2.domain.tld]:222 ecdsa-sha2-nistp256 <key>
Or even:
[server.domain.tld]:222,[xx.xx.xx.xx]:222,[server.domain.tld]:333 ecdsa-sha2-nistp256 <key>
I would assume that if they share a <key>, then they are the same server. I cannot for the life of me think of a situation where you would have the same <key> on different servers, especially since that <key> is generated randomly by sshd when it's installed and is only used to unique identify that system for security reasons. Nor can I think of a reason you'd have sshd responding on multiple ports.
At the very least this would be such a rare edge case, that I am not sure it's reasonably to account for it. I also see this generate option as a kick-start type thing. It'll get you mostly there, but you'll still need to edit the config file to account for your specific need, and anyone who has gone through the trouble of manually setting the <key> for their server is going to be very much aware of their special setup and probably won't use the generate option anyway.
Also, remember that sshd adds all new connections on their own lines, you have to manually edit known-hosts to make entries with commas in them, which is what I did in mine in order to clean it up and shorten it, I don't think most people would be doing this.
Should be better in the last commit (check artifacts at https://github.com/quantumsheep/sshs/actions/runs/1849655613).
I added --known-hosts-allow-single-ip option to allow lines without a valid domain name.
Should be better in the last commit (check artifacts at https://github.com/quantumsheep/sshs/actions/runs/1849655613).
I added
--known-hosts-allow-single-ipoption to allow lines without a valid domain name.
Interesting, not too sure that is really all that necessary. I think this:
1.2.3.4 ecdsa-sha2-nistp256 <key>
5.6.7.8:333 ecdsa-sha2-nistp256 <key>
Should return
Host "1.2.3.4"
Hostname 1.2.3.4
User <local signed in user>
Port 22
Host "5.6.7.8"
Hostname 5.6.7.8
User <local signed in user>
Port 333
This will almost certainly be the majority of all cases that you'll find the known-hosts file, and it makes editing the config file to adjust entries to meaningful names (ie `Host "Name of Server") much quicker and easier.
My use is a little bit of an edge case I think, or at least a power user case, the vast majority of people probably won't have such a neat and organized known-hosts file.
I think this:
5.6.7.8:333 ecdsa-sha2-nistp256 <key>Should return
Host "5.6.7.8" Hostname 5.6.7.8 User <local signed in user> Port 333
We can't set Host to 5.6.7.8 because that would break when having the same IP using the different ports for different servers (that's my case). That's where I'm blocking.
We can't set
Hostto5.6.7.8because that would break when having the same IP using the different ports for different servers (that's my case). That's where I'm blocking.
So this config would be considered invalid?
Host "5.6.7.8"
Hostname 5.6.7.8
User <local signed in user>
Port 333
Host "5.6.7.8"
Hostname 5.6.7.8
User <local signed in user>
Port 222
Host "5.6.7.8"
Hostname 5.6.7.8
User <local signed in user>
Port 111
What about this:
Host 5.6.7.8
Hostname 5.6.7.8
User <local signed in user>
Port 333
Host 5.6.7.8
Hostname 5.6.7.8
User <local signed in user>
Port 222
Host 5.6.7.8
Hostname 5.6.7.8
User <local signed in user>
Port 111
This makes me wonder what the difference between host and hostname is for sshs. IMO host should just be the name of the connection, and hostname should be the server IP/DNS name. And duplicate host and hostname entries should be allowed so long as they have different ports.
What about this:
Host 5.6.7.8 Hostname 5.6.7.8 User <local signed in user> Port 333 Host 5.6.7.8 Hostname 5.6.7.8 User <local signed in user> Port 222 Host 5.6.7.8 Hostname 5.6.7.8 User <local signed in user> Port 111
sshs works by calling ssh over an host (E.g. calling ssh "example host"). Multiple SSH hosts with the same name would be handled by ssh but it doesn't make sense in sshs. However if we name them by host:port it's fine for when calling ssh.
sshs works by calling ssh over an host (E.g. calling
ssh "example host"). Multiple SSH hosts with the same name would be handled by ssh but it doesn't make sense in sshs. However if we name them byhost:portit's fine for when calling ssh.
I get that, but from my testing sshs seems to try ssh user@host:port unless host is in quotes, then it appears to use ssh user@hostname:port Hence my confusion/questions. I am not sure if this is by design or not.
Host "My Host 1"
Hostname 1.2.0.2
Port 22
Host My Host 2
Hostname 1.2.0.2
Port 22
If I select My Host 1 from the list, SSH connects to 1.2.0.2 just fine. If, however, I select My Host 2 I get:
ssh: Could not resolve hostname My Host 2: nodename nor servname provided, or not known
I think that sshs should always use hostname as the server name/ip and host should only be used to name it. And then when SSH is called it would always be called by ssh hostname:port and then multiple entries in the config would not be an issue, though I do note that sshs just ignore subsequent entries with the same Host set, which it probably should not do.
I think that sshs should always use
hostnameas the server name/ip andhostshould only be used to name it
There are cases when a host doesn't have an hostname (E.g. ProxyCommand). That's why I rely on Host. Also I believe that Host My Host 2 is invalid.
I think that sshs should always use
hostnameas the server name/ip andhostshould only be used to name itThere are cases when a host doesn't have an hostname (E.g. ProxyCommand). That's why I rely on
Host. Also I believe thatHost My Host 2is invalid.
I feel like I am missing something here. You say you rely on the host field, but then why does sshs skip it if it is in quotes and move onto the hostname instead? This strikes me as unexpected and confusing.
Also Host My Host 2 is invalid in what sense? It appears to be invalid if you use the command ssh My Host 2, but sshs puts it in the menu just fine, and it is selectable, it just hands the wrong thing over to the ssh command.
I am completely confused by why there is a host and a hostname in the config, and that is then compounded by the way sshs treats host different when it has and does not have quotes.
As for cases where a host doesn't have a hostname, how does sshs handle that?
I feel like I am missing something here.
Yes I was, and I apologize for this. I did not realize that the config file was actually a feature of openSSH, and designed to make using ssh easier to use. I understand the issue now.
With my newly acquired knowledge I think I can say that this feature is about as good as it can probably get, but I will do some testing on it.
I did not realize that the
configfile was actually a feature of openSSH
Sorry I didn't realized, I would have told you :/
but I will do some testing on it
Ok, I'm waiting for your return to decide if we merge it like that or change it.
Looks like it's ignoring all my entries in known-hosts that do not have host names (ie are just IPs, I have a mix of both). But the ones it does return all look good.
[server-02.domain.tld]:222,[10.11.12.13]:222 ecdsa-sha2-nistp256 <key>
server-01,server-01.doman.tld,1.2.3.4 ecdsa-sha2-nistp256 <key>
5.6.7.8 ssh-rsa <key>
Returns:
Host server-02.domain.tld:222
Hostname server-02.domain.tld
Port 222
Host server-01
Hostname server-01
Port 22
[server-02.domain.tld]:222,[10.11.12.13]:222 ecdsa-sha2-nistp256 <key> server-01,server-01.doman.tld,1.2.3.4 ecdsa-sha2-nistp256 <key> 5.6.7.8 ssh-rsa <key>Returns:
Host server-02.domain.tld:222 Hostname server-02.domain.tld Port 222 Host server-01 Hostname server-01 Port 22
Should we add an a 5.6.7.8 entry ?
I think so, to me it makes sense to treat each line in the known_hosts file as a separate host for the config file.
I think so, to me it makes sense to treat each line in the
known_hostsfile as a separate host for theconfigfile.
It should be good in https://github.com/quantumsheep/sshs/actions/runs/1953959990