A simple and powerful SSH keys manager

MIT licensed LICENSE Build Status Go Report Card GoCover.io GoDoc

SKM is a simple and powerful SSH Keys Manager. It helps you to manage your multiple SSH keys easily!

Features

  • Create, List, Delete your SSH key(s)
  • Manage all your SSH keys by alias names
  • Choose and set a default SSH key
  • Display public key via alias name
  • Copy default SSH key to a remote host
  • Rename SSH key alias name
  • Backup and restore all your SSH keys
  • Prompt UI for SSH key selection
  • Customized SSH key store path

Installation

Homebrew

brew tap timothyye/tap
brew install timothyye/tap/skm

Using Go

go get github.com/TimothyYe/skm/cmd/skm

Manual Installation

Download it from releases and extact it to /usr/bin or your PATH directory.

Usage

% skm

SKM V0.8.1
https://github.com/TimothyYe/skm

NAME:
   SKM - Manage your multiple SSH keys easily

USAGE:
   skm [global options] command [command options] [arguments...]

VERSION:
   0.8.1

COMMANDS:
     init, i      Initialize SSH keys store for the first time usage.
     create, c    Create a new SSH key.
     ls, l        List all the available SSH keys.
     use, u       Set specific SSH key as default by its alias name.
     delete, d    Delete specific SSH key by alias name.
     rename, rn   Rename SSH key alias name to a new one.
     copy, cp     Copy current SSH public key to a remote host.
     display, dp  Display the current SSH public key or specific SSH public key by alias name.
     backup, b    Backup all SSH keys to an archive file.
     restore, r   Restore SSH keys from an existing archive file.
     cache        Add your SSH to SSH agent cache via alias name.
     help, h      Shows a list of commands or help for one command.

GLOBAL OPTIONS:
   --store-path value   Path where SKM should store its profiles (default: "/Users/timothy/.skm")
   --ssh-path value     Path to a .ssh folder (default: "/Users/timothy/.ssh")
   --restic-path value  Path to the restic binary
   --help, -h           show help
   --version, -v        print the version

For the first time use

You should initialize the SSH key store for the first time use:

% skm init

✔ SSH key store initialized!

So, where are my SSH keys? SKM will create SSH key store at $HOME/.skm and put all the SSH keys in it.

NOTE: If you already have id_rsa & id_rsa.pub key pairs in $HOME/.ssh, SKM will move them to $HOME/.skm/default

Create a new SSH key

NOTE: Currently ONLY RSA and ED25519 keys are supported!

skm create prod -C "[email protected]"

Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /Users/timothy/.skm/prod/id_rsa.
Your public key has been saved in /Users/timothy/.skm/prod/id_rsa.pub.
...
✔ SSH key [prod] created!

List SSH keys

% skm ls

✔ Found 3 SSH key(s)!

->      default
        dev
        prod

Set default SSH key

% skm use dev
Now using SSH key: dev

Prompt UI for key selection

You can just type skm use, then a prompt UI will help you to choose the right SSH key:

Display public key

% skm display

Or display specific SSH public key by alias name:

% skm display prod

Delete a SSH key

% skm delete prod

Please confirm to delete SSH key [prod] [y/n]: y
✔ SSH key [prod] deleted!

Copy SSH public key to a remote host

% skm cp [email protected]

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/Users/timothy/.skm/default/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:

Number of key(s) added:        1

Now try logging into the machine, with:   "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.

✔  Current SSH key already copied to remote host

Rename a SSH key with a new alias name

% skm rn test tmp
✔  SSH key [test] renamed to [tmp]

Backup SSH keys

Backup all your SSH keys to $HOME directory by default.

% skm backup

a .
a ./test
a ./default
a ./dev
a ./dev/id_rsa
a ./dev/id_rsa.pub
a ./default/id_rsa
a ./default/id_rsa.pub
a ./test/id_rsa
a ./test/id_rsa.pub

✔  All SSH keys backup to: /Users/timothy/skm-20171016170707.tar

If you have restic installed then you can also use that to create backups of your SKM store:

# First, you need a password for your repository
% if [[ ! -f ~/.skm-backups.passwd ]]; then
%     openssl rand -hex 64 > ~/.skm-backups.passwd
% fi

% skm backup --restic
repository ... opened successfully, password is correct

Files:           0 new,     1 changed,     4 unmodified
Dirs:            0 new,     0 changed,     0 unmodified
Added to the repo: 1.179 KiB

processed 5 files, 2.593 KiB in 0:00
snapshot $SNAPSHOT saved
✔  Backup to /Users/$USER/.skm-backups complete

Restore SSH keys

% skm restore ~/skm-20171016172828.tar.gz                                                                                           
x ./
x ./test/
x ./default/
x ./dev/
x ./dev/id_rsa
x ./dev/id_rsa.pub
x ./default/._id_rsa
x ./default/id_rsa
x ./default/._id_rsa.pub
x ./default/id_rsa.pub
x ./test/id_rsa
x ./test/id_rsa.pub

✔  All SSH keys restored to /Users/timothy/.skm

Again, SKM also supports restic to create and restore backups:

% skm restore --restic --restic-snapshot $SNAPSHOT
repository $REPO opened successfully, password is correct
restoring <Snapshot $SNAPSHOT of [/Users/$USER/.skm] at 2018-10-03 19:40:33.333130348 +0200 CEST by $USER@$HOST> to /Users/$USER/.skm
✔  Backup restored to /Users/$USER/.skm

Integrate with SSH agent

You can use cache command to cache your SSH key into SSH agent's cache via SSH alias name.

Cache your SSH key

λ tim [~/]
→ skm cache --add my                                                                                                                                                                                                                                                                     
Enter passphrase for /Users/timothy/.skm/my/id_rsa:
Identity added: /Users/timothy/.skm/my/id_rsa (/Users/timothy/.skm/my/id_rsa)
✔  SSH key [my] already added into cache

Remove your SSH key from cache

λ tim [~/]
→ ./skm cache --del my                                                                                                                                                                                                                                                                   
Identity removed: /Users/timothy/.skm/my/id_rsa (MyKEY)
✔  SSH key [my] removed from cache

List your cached SSH keys from SSH agent

λ tim [~/]
→ ./skm cache --list                                                                                                                                                                                                                                                                     
2048 SHA256:qAVcwc0tdUOCjH3sTskwxAmfMQiL2sKtfPBXFnUoZHQ /Users/timothy/.skm/my/id_rsa (RSA)

Customized SSH key store path

By default, SKM uses $HOME/.skm as the default path of SSH key store. You can define your customized in your ~/.bashrc or ~/.zshrc by adding:

SKM_STORE_PATH=/usr/local/.skm

Hook mechanism

Edit and place a executable file named hook at the specified key directory, for example:

~/.skm/prod/hook

This hook file can be both an executable binary file or an executable script file.

SKM will call this hook file after switching default SSH key to it, you can do some stuff in this hook file.

For example, if you want to use different git username & email after you switch to use a different SSH key, you can create one hook file, and put shell commands in it:

#!/bin/bash
git config --global user.name "YourNewName"
git config --global user.email "[email protected]"

Then make this hook file executable:

chmod +x hook

SKM will call this hook file and change git global settings for you!

Licence

MIT License
996ICU License

Owner
Timothy
A developer, a gopher, a Vimer, an Emacser, a mechanical keyboard enthusiast and a father.
Timothy
Comments
  • Hardcoded version

    Hardcoded version

    Hello!

    There is hardcoded version in help menu. It always shows 0.5 and confuses after updated.

    https://github.com/TimothyYe/skm/blob/f263af35fa2f84734419abdf9730c2627431b19b/cmd/skm/logo.go#L9

  • 无法自定义--store-path

    无法自定义--store-path

    skm init时指定非默认--store-path不生效

    1.我的环境 image 2.操作过程 2.1 删除/root/.skm 2.2 已确认--store-path不存在 image 3.默认--store-path正常 image 4.已确认使用centos出现同样问题 5.简单看了下main.go,没看出来...... image

    是我打开方式不对吗

  • id_rsa can't transfer to pem formate

    id_rsa can't transfer to pem formate

    Private key, which created by skm, can't be transferred to pem format, the error is below:

    140138626492304:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:707:Expecting: ANY PRIVATE KEY
    

    My command is openssl rsa -in ./id_rsa -out id_rsa.pem.

  • "display" use a relative path to default ssh path

    As title, when use "display" command, skm uses a relative path from default ssh path. It shows an error like:

     % skm dp
    Failed to read  ../.skm/github/id_rsa.pub
    
  • Restic integration

    Restic integration

    Hi :)

    First of all thank you very much for creating this! Finally an easy way for me to switch between multiple SSH keys without getting a headache 😄

    Would it perhaps make sense to use restic for creating and restoring backups as an alternative to the tgz approach? I've been doing that recently with https://github.com/zerok/clocked and it worked extremely well so far 😄

  • feat: allow different type keys to coexist

    feat: allow different type keys to coexist

    Now I have an RSA key and an ed25519 key, RSA for personal use, and ED25519 for work. I noticed that when I switch keys by skm, it just keeps one key pair in my ssh folder, I think there should have one way to keep different types of keys coexisting in the ssh folder, there's no conflict.

    In this PR I added a global flag --keep-type-keys and the associated environment variable is SKM_KEEP_TYPE_KEYS(let me know if you don't like this naming, I'm willing to change), and if you set it, skm will not affect other type keys.

    The result like,

    image
  • Allow symlinks from `.ssh` to `.skm`

    Allow symlinks from `.ssh` to `.skm`

    Very nice tool, thank you!

    I have a small suggestion for how I think the file handling around the keys should work I and I suppose most other people prefer not moving the ssh keys into .skm, but rather to have symbolic links to the ssh keys created in .skm. Right now, I have the original keys in .skm and symlink them to .ssh but prefer to have it the other way around.

    I tried to have the original files in .ssh and symlink them to .skm, but this resulted in the files not being readable:

    ✔ Found 2 SSH key(s)!
    
    Failed to read  /Users/[[redacted]]/.skm/[[redacted]]@[[redacted]].com/id_rsa.pub
    	[[redacted]]@[[redacted]].com	[]	[]
    Failed to read  /Users/[[redacted]]/.skm/[[redacted]]@[[redacted]].com/id_rsa.pub
    	[[redacted]]@[[redacted]].com []	[]
    

    I suppose currently symlinks are not resolved. By following symlinks, this should be possible to do if one would want to, without changing the default behavior of skm.

  • Interrupting the creation of a new key will break the creation of that key afterwards

    Interrupting the creation of a new key will break the creation of that key afterwards

    Steps to reproduce the problem:

    $> skm c my-key
    Generating public/private rsa key pair.
    Enter passphrase (empty for no passphrase): _
    <CTRL+C to interrupt process>
    $>
    $> skm c my-key
    Create SSH key failed!
    $>
    

    I would expect to be able to create the key again afterward.

  • name clash skm is an older ssh key manager too

    name clash skm is an older ssh key manager too

    Hi Timothy

    There is another older SSH Key manager which uses the name skm

    https://sites.google.com/site/jeromeboismartel/code-s-corner/ssh-key-management-with-skimp

    I wonder if it wouldn't be better to rename your project so it doesn't clash. Even sskm or mks or something similar?

    Michael

  • Call a hook after switching keys

    Call a hook after switching keys

    Hi,

    I switch between work key and private key. Besides the keys some other stuff ( mainly the git config in terms of mail ) has to be changed then as well.

    I see the following possible approaches:

    1. Adjusting the git config and thus becoming a git configuration manager
    2. Having a list of commands in a config file to be run after/before key change
    3. Having some kind of a hook ( an executable with predefined name lying side-by-side with the key )

    I decided to do number three and do a pull request, as this probable has the least impact on the work flow.

    Kind regards, Sascha

  • Add CLI Test

    Add CLI Test

    Hello. First of all, thanks for making a great tool. By the way, I want to add cli_test.go. Perhaps a different name might be better. This file actually execute main.go and tests its standard output.

    If you give permission I would like to write this test. How about?

    cli_test example

    package main
    
    import (
        "bytes"
        "fmt"
        "strings"
        "testing"
    )
    
    func TestRun_versionFlag(t *testing.T) {
        outStream, errStream := new(bytes.Buffer), new(bytes.Buffer)
        cli := &CLIoutStream: outStream, errStream: errStream
        args := strings.Split("skm -version", " ")
    
        status := cli.Run(args)
        if status != ExitCodeOK
            t.Errorf("ExitStatus=%d, want %d", status, ExitCodeOK)
        }
    
        expected := fmt.Sprintf("skm version %s", Version)
        if !strings.Contains(errStream.String(), expected)
            t.Errorf("Output=%q, want %q", errStream.String(), expected)
         }
    }
    
  • Destination constraints

    Destination constraints

    When connecting to a ssh server, by default, all available public keys are sent for it to choose one for authentication. This is a problem because any server you connect to now has a list of all your public keys. While this is not really a security issue for authentication, it allows servers to identify you if they have, for example, your github ssh key, or check other servers if they accept your public key (see, for example, https://github.com/benjojo/ssh-key-confirmer).

    OpenSSH 8.9 implemented detstination constraints, this allows ssh-agent to forwards public keys based on the destination server. The destination constraints can be added via the -h flag to ssh-add.

    It would be cool for skm to either support adding destination constraints for keys, or to add keys with destination constraints to .ssh/config

This is a SSH CA that allows you to retrieve a signed SSH certificate by authenticating to Duo.

github-duo-ssh-ca Authenticate to GitHub Enterprise in a secure way by requiring users to go through a Duo flow to get a short-lived SSH certificate t

Jan 7, 2022
Integrated ssh-agent for windows. (pageant compatible. openSSH ssh-agent etc ..)
Integrated ssh-agent for windows. (pageant compatible. openSSH ssh-agent etc ..)

OmniSSHAgent About The chaotic windows ssh-agent has been integrated into one program. Chaos Map of SSH-Agent on Windows There are several different c

Dec 19, 2022
Terraform Provider for Azure (Resource Manager)Terraform Provider for Azure (Resource Manager)
Terraform Provider for Azure (Resource Manager)Terraform Provider for Azure (Resource Manager)

Terraform Provider for Azure (Resource Manager) Version 2.x of the AzureRM Provider requires Terraform 0.12.x and later, but 1.0 is recommended. Terra

Oct 16, 2021
Cloversim - Simple and powerful tool for Clover simulation
Cloversim - Simple and powerful tool for Clover simulation

Clover sim Simple and powerful tool for Clover simulation How to setup mkdir clo

Jul 23, 2022
Gohalt 👮‍♀🛑: Fast; Simple; Powerful; Go Throttler library
Gohalt 👮‍♀🛑: Fast; Simple; Powerful; Go Throttler library

Gohalt ??‍♀ ?? : Fast; Simple; Powerful; Go Throttler library go get -u github.com/1pkg/gohalt Introduction Gohalt is simple and convenient yet powerf

Nov 27, 2022
easyssh-proxy provides a simple implementation of some SSH protocol features in Go

easyssh-proxy easyssh-proxy provides a simple implementation of some SSH protocol features in Go. Feature This project is forked from easyssh but add

Dec 30, 2022
kubectl-fzf provides a fast and powerful fzf autocompletion for kubectl
kubectl-fzf provides a fast and powerful fzf autocompletion for kubectl

Kubectl-fzf kubectl-fzf provides a fast and powerful fzf autocompletion for kubectl. Table of Contents Kubectl-fzf Table of Contents Features Requirem

Nov 3, 2021
Automatically capture all potentially useful information about each executed command (as well as its output) and get powerful querying mechanism
Automatically capture all potentially useful information about each executed command (as well as its output) and get powerful querying mechanism

nhi is a revolutionary tool which automatically captures all potentially useful information about each executed command and everything around, and delivers powerful querying mechanism.

Nov 29, 2022
Go version manager. Super simple tool to install and manage Go versions. Install go without root. Gobrew doesn't require shell rehash.

gobrew Go version manager Install or update With curl $ curl -sLk https://git.io/gobrew | sh - or with go $ go get -u github.com/kevincobain2000/gobre

Jan 5, 2023
A simple download file manager that sorts your files into your desired folders, This was meant to be a small project and nothing big.

GoDFM Simply go to the tags and download the .exe file (or compile it yourself by running go build). Add it to your environment paths by going to sett

Aug 9, 2022
Build powerful pipelines in any programming language.
Build powerful pipelines in any programming language.

Gaia is an open source automation platform which makes it easy and fun to build powerful pipelines in any programming language. Based on HashiCorp's g

Jan 3, 2023
Copy files and artifacts via SSH using a binary, docker or Drone CI.

drone-scp Copy files and artifacts via SSH using a binary, docker or Drone CI. Feature Support routines. Support wildcard pattern on source list. Supp

Dec 6, 2022
⚡️ A dev tool for microservice developers to run local applications and/or forward others from/to Kubernetes SSH or TCP
⚡️ A dev tool for microservice developers to run local applications and/or forward others from/to Kubernetes SSH or TCP

Your new microservice development environment friend. This CLI tool allows you to define a configuration to work with both local applications (Go, Nod

Jan 4, 2023
A Go based deployment tool that allows the users to deploy the web application on the server using SSH information and pem file.

A Go based deployment tool that allows the users to deploy the web application on the server using SSH information and pem file. This application is intend for non tecnhincal users they can just open the GUI and given the server details just deploy.

Oct 16, 2021
An experimental Go application that allows an SSH session to interact with the clipboard of the host machine and forward calls to open

Remote Development Manager An experimental Go application that allows an SSH session to interact with the clipboard of the host machine and forward ca

Dec 27, 2022
Composer is a simple process manager for dev environments.

Composer Composer is a simple service manager for dev environments. How to build/install it? To build composer under ./bin, run: make build To build

May 12, 2022
easy way to distribute commands over ssh.

grapes grapes is lightweight tool designed to distribute commands over ssh with ease. Update (25/04/2019) Handshake validation is now in place in orde

Dec 20, 2022
Manage your ssh alias configs easily.
Manage your ssh alias configs easily.

manssh manssh is a command line tool for managing your ssh alias config easily, inspired by storm project, powered by Go. Note: This project is actual

Nov 9, 2022