Show HN: I built a simple, open-source tool to manage servers and SSH keys
github.com
github.com
1. Great job on shipping! Whether or not the people in this thread find this tool useful, I want to congratulate you on putting together something you're ready to share with the world.
2. I'd love to hear the story of what prompted you to create this tool. Was it an issue you had? Did you set out to make something easier?
3. Not everything has to be useful to everybody. It's OK if this is something you find useful and no one else does.
Cheers
The first is an increased fatigue caused by some poor quality posts OR posts presenting the same thing again and again just by opportunism (e.g. boilerplates where people just share their thing as an Ad). Therefore, the trust has decreased and people start asking themselves "what's hidden behind".
Another reason might be related to the surge of cyberattacks of all kinds. Lots of comments here are not super nice, but they are polite and ask good and legitimate questions, especially regarding cybersecurity.
As long as people are polite, argumented criticism should be appreciated.
... wth
Please add some use-cases to make it clear where exactly does it come in, because once I add a key in my ssh config, I'm pretty much there. For more complicated tasks I use ansible.
- No need to remember server IPs - Viking gives you an overview with simple machine ls and key ls commands - A more modern and intuitive API - Works consistently across all platforms - Close to the Docker API
Sure, it’s only the first release. It may not seem like much now, but with feedback, the project will move closer to the goal.
On your local machine under ~/.ssh/config you can add something like
#PERSONAL
Host vpn-us
HostName 1.2.3.4
User my_fun_username
Port 1212
now you can ssh usingssh vpn-us
(above is the same as the following command --> ssh my_fun_username@1.2.3.4 -p1212)
$ cat .ssh/config
# Fictitious example
Include work.config
Include personal.config
$
https://man7.org/linux/man-pages/man5/ssh_config.5.html $ grep '^Host' .ssh/<config file> | awk '{print $2}' | while read hst; do ssh $hst '<remote command>' 2> /dev/null < /dev/null; doneUmm, DNS?
> with feedback, the project will move closer to the goal
What goal? That was the question you replied to.
If I put my server's IP in my ~/.ssh/config, I don't need to remember it, and the autogenerated `~/.ssh/known_hosts` file will ensure that the IP doesn't change after my first time connecting. Is there some functionality beyond this in terms of remembering server IPs?
I would personally prefer using well-known tools over installing someone's latest project to handle something as sensitive as my SSH credentials.
Installing code instead of editing my .ssh/config seems like a gigantic risk.
I somewhat understand the desire for an SSH client that behaves like the Docker shell, but it needs some features that actually set it apart.
How about putting different hosts into groups, and then running a command on the group so that every machine in the group runs the same command?
How about managing both hosts and users so that I can easily log into a system as different users for different purposes?
How about adding some security features to make key management more secure than the standard "everything in the .ssh directory" strategy?
Maybe add some SCP/SFTP features so that moving files from host to host is easier. Maybe even have a package you can install on remote hosts so that they can transfer files directly between each other when asked to from an outside terminal.
That can be done with a simple awk/fzf script, which would even allow me to interactively chose the hosts from the ones configured in the ssh config.
> How about managing both hosts and users so that I can easily log into a system as different users for different purposes?
The ssh config already allows doing that:
Host prod-as-foo
HostName domain.of.prod.server
User foo
Identity File ~./ssh/foo.key
Host prod-as-bar
HostName domain.of.prod.server
User bar
Identity File ~./ssh/bar.key
> How about adding some security features to make key management more secure than the standard "everything in the .ssh directory" strategy?IdentityFile keys can be setup to be symmetrically encrypted, requiring a password on use.
The keyfiles can also be loaded via `ssh-agent(1)`, allowing to directly use non-local keyfiles (source: `man ssh`)
> Maybe add some SCP/SFTP features so that moving files from host to host is easier.
Both `scp` and `sftp` already use the ssh config file.
For example:
Specifying different keys different servers
Host github.com
User git
IdentityFile ~/.ssh/id_rsa_github
Host myserver User username
IdentityFile ~/.ssh/id_rsa_myserver
Reuse SSH connections for multiple sessionshttps://blog.scottlowe.org/2015/12/11/using-ssh-multiplexing...
https://blog.poespas.me/posts/2024/04/27-optimizing-ssh-conn...
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Other than that, you can also do ssh agent forwarding, port forwarding etc. These are all crucial functions that user like me need when we access remote machines.I hope you take this as constructive criticism and not a knockdown on your work. You've created and released something that's great but this site usually brings more advanced users.
$ viking machine add --name deathstar --key starkey 168.112.216.50
$ viking exec --tty deathstar /bin/bash
Over putting the following in my ~/.ssh/config Host deathstar
HostName 168.112.216.50
User my_user
IdentityFile ~/.ssh/starkey
And then just typing $ ssh deathstar
?you're in a nerd thread, and will be downvoted without comments by starting an unwillingness to deep knowledge for the sake of knowledge.
if this were a mba thread the opposite would happen.
that said, shame on you for wanting ignorance!
This tool has a config as well. From the repos readme:
Viking saves data locally. Set VIKING_CONFIG_DIR env variable for a custom directory. Use viking config to check the current config folder.
> hidden informationWhat exactly is "hidden" about ~/.ssh/config ? It's a plaintext file in a format that is the same across every single machine that uses openssh, which is pretty much every *nix box on the planet.
> commands stop being portable
How is using literal `ssh` not portable? If you're talking about the ssh config: That is a plaintext file that can be checked into a repo and simply downloaded to any machine I want. And again: viking too has a config.
> a modern cli
host=$(
awk '$1 == "Host" && $2 != "*" {print $2}' "$HOME/.ssh/config" |
fzf --reverse
)
[[ -n host ]] && ssh "$host"
There. I just built a modern, interactive tool to chose a server from my ssh config. It requires only fzf as a non-standard dependency, a tool that is present in pretty much every package repository.> allows me to manage my configurations
vim ~/.ssh/config
There. A powerful, searchable, portable way to manage my SSH configuration. I can even use comments, and have access to all ssh settings available. All dependencies come preinstalled on most *nix boxes.Create entry (using a template and exported variables):
$ envsubst < .ssh/template.config >> .ssh/config
Read entry (assuming the 4 line template): $ sed -n /<Host entry>/,+3p .ssh/config
Update entry: Delete and CreateDelete entry (assuming the 4 line template):
$ sed -i /<Host entry>/,+3d .ssh/configMany questions...
I could definitely see the use of a tool like this if it was fleshed out a bit more.
I've used linux since the 1990s. Was friends with the founders of LinuxCare, met Torvalds. blah blah blah...
Since semi-retire from ops... and basically using windows for a few years without need to manage a linux box, youd be FN surprised how quickly basic knowledge evaporate at my age when not in use. I had to fn lookup how to add my keys to a box again.
(After a 3-month long panel-interview with Google's Net Eng Team back in the day - my final panel question was:
"OK how do you do a global search and replace in VI?"
I *blanked* -- and I stated... "UH.... I'cant recall - id just google it"
They all laughed.
---
@OP -- look at the remote SSH extension in VSCode/Positron etc...
Its a really good little file/function/SSH manager.
Though Ill take a look at this.
There does seem to be a subset of questions that are really just "have you repeatedly used this tool in the last few months?". If you have, you'll probably be fast.
1. It links up addresses to host names so that you don’t have to remember ip addresses of servers. 2. It makes it easy to create keys and attach those keys to particular hosts, so reduces the effort required to separate keys depending on your host 3. It makes key rotation fairly easy 4. It replaces the ssh command syntax with a k8s or docker-like syntax for executing remote commands or entering a shell. So I suppose you don’t need to context switch?
Um.
But hostfile well if you have to share it with 2-3 other people might be a hassle?
You have no information about who you are or what you've done and you expect me to trust you with ssh keys and remotes?
The go.sum is concerning as well because now I need to trust all of those.
I would argue this should be 100% avoided in production environments at this time.
Before I provide any feedback, I’m curious…
Your GitHub account appears to be a fresh account, using a pseudonym and a DuckDuckGo email address. What’s the reason for all of that? Are you a new developer? Did you simply not have a GitHub account because you never needed it? Is it just some privacy-related reason? Some other reason(s)?
I’d love some clarification on that, if you don’t mind.
To be clear, it’s perfectly fine to not have had a GitHub account—it’s just a bit unsettling when the very first project from a new and pseudonymous account is one dealing with servers and SSH keys.
You are .pub is meant to be shared; even publicly. It's fine to have one ssh key for everything. It's also hard to think about a scenario where one ssh key in your machine is compromised, but not the others.
Identity protection perhaps. A public key could reveal that the same person is accesing two or more servers. Different keys per server hide that information.
ssh whoami.filippo.io
[1]: https://words.filippo.io/ssh-whoami-filippo-io/Maybe OP also moves private keys around and doesn't know private key ideally should never leave single machine and if you setup new laptop to connect to your servers one should generate new private key and upload new pub key and for backup ideally one should have spare laptop already set with keys.
I do have some use-cases where I use different ssh-keys per server/cluster:
- Setting up client's machines allow me to nuke the keypair when work is done and I no longer have access. Customers trust me to do this - they trusted me to set up their machines already.
- Belonging to different projects: so that when the project is finished, handed over or closed down, I can safely delete all keys associated with that, knowing for sure I'm not deleting keys that I did need after all.
- Having different levels - testing these levels. I set up servers in a way that there's sysadmins who have root/sudo, and `deploy` users that can only deploy apps (e.g. capistrano, ansible, k8s and so on) and maybe `sudo systemctl restart my-app` and/or read certain /var/log/some-log. I want to be sure that something does/does not work because of the correct keys, and not because one of the 12+ keys in my ssh-agent happens to be used instead.
So, in my case, I do have a lot of ssh-keys that I juggle with.
I wish there were just a version of ssh-agent/ssh-add though, with better UX. Looks like maybe viking is that?
People should generate at least a single ssh key per client device. (On Userify, rotating your key is just a matter of pasting the new public key into your keybox in your dashboard.) One per client device will let you revoke/rotate only that key when it's compromised. This also helps keep you from copying the private key somewhere else (which you should never do).
It does look like this wants to be a replacement for ssh-agent/ssh-add; also check out GNU keychain by Daniel Robbins, which is in most distro repos.
(blatant plug - we actually developed Userify for these three use cases, especially on cloud instances with constantly changing IP's)
I guess the point I'm making is more for making decent keys to create sensible separation points, rather than having one for each machine though. Allowing work vs home vs foo vs bar
My github-keygen tool allows to manage your ~/.ssh/config for those GitHub use cases.
My company currently uses YubiKeys to support hardware-based individual SSH keys. These SSH keys are distributed with Ansible. It works but is cumbersome and lacks a single pane of glass.
What we would like to have: a list of servers, a list of users, user roles (via sudoers), and a WebUI to manage all of it. And I don't know of any tool to do this. Of course, there are tools like Teleport or SSH CA instead of SSH keys, but they are for larger organizations and are overkill for my company.
theres already projects solving central ssh key management, for example:
https://github.com/ierror/ssh-permit-a38 (distributes via authorized keys)
https://github.com/netlore/OpenAKC
https://tenshidev.medium.com/centralized-ssh-authentication-...
and
https://docs.gitlab.com/ee/administration/operations/fast_ss...
https://developer.1password.com/docs/ssh/agent/security
https://developer.1password.com/docs/secrets-automation/#com...
https://1password.com/developer-security
https://1password.com/product/enterprise-password-manager
Or, depending on your use cases, check out Doppler:
https://docs.doppler.com/docs/workplace-team
https://community.doppler.com/t/generating-authorized-keys-f...
EDIT: I was wrong. See comments.
Does anyone have any suggestions?
KnownHostsCommand
Specifies a command to use to obtain a list of host keys, [...]So I understand the desire to manage both of those tasks, connecting and persisting, from one tool. I wrote a similar little utility that does this by adding a persist option to built-in ssh. https://github.com/emileindik/slosh
Seeing this passion is great! TBH, some of the negative comments here might be warranted: SSH is an especially important and tricky area to start in as your first Github project or for those inexperienced in security.
However, we're always looking for people at Userify to help us build the next wave of SSH UX and who aren't afraid to put something out there. It's a lot of work to get things built and it's very exciting to see some new ideas. Hit me up if you want to talk!
(obligatory disclaimer, I work at Userify and we have a server-side product that automates SSH key management and distribution. For example, the CA design doesn't kick someone out once their access is removed, but Userify's shim actually terminates all of sessions instantly, like screen or tmux, across all of the servers they're logged into and removes (but retains for historical record) their home directory.)
I was a bit confused at first, I thought you were saying ssh certificates couldn't be revoked - but I see you're talking about signing the user out from existing sessions.
That is a fair point. I guess removing/locking a local user (in /etc/passwd, /etc/shadow) would typically leave any console logins alone too - unless other action is taken.
Certificates can of course be revoked:
http://www.ixany.org/articles/key-revocation-lists-on-openss...
We've thought about porting Userify to work with CA's too but haven't had many requests for that for some reason, even though I'm sure many companies do have CA's set up alongside their other PKI for SSH.
With Userify, sessions (like tmux or screen) actually get terminated within seconds when the user's access is removed. That doesn't happen at all with certificates.
If someone's certificate expires, but they're still logged in, they'll stay logged in, because there is no mechanism to kill their session (and they can channel all kinds of things over their logged-in session).
That's an absolute nightmare for compliance.
Probably the best one could do out of the box is set an 8 hour session limit or so?
Include ~/.ssh/config.d/2024/*