The idea here is to control SSH access to servers (without needing to install anything on them) based simply on cryptographically provable membership in Keybase teams.
SSH supports a concept of certificate authorities (CAs) where you can place a single public key on the server, and the SSH server will allow any connections with keys signed by the CA cert. This is how a lot of large companies manage SSH access securely; users can be granted SSH access to servers without having to change the keys that are deployed on the server.
This repo provides the pieces for anyone to build this workflow:
- generation scripts and a guide to set up the Keybase team and server ssh configuration
- a wrapper around ssh (
kssh) for any end user to get authenticated using the certificate authority - a chatbot (
keybaseca) which listens in a Keybase team forksshrequests. If the requester is in the team, the bot will sign the request with an expiring signature (e.g. 1 hour), and then the provisioned server should authenticate as usual.
Removing a user's ability to access a server is as simple as removing them from the Keybase team.
This code is currently a work in progress and this project is not yet complete and is not ready to be used.
There are two binaries contained in this project in the cmd/ folder. shared/ is go code that is shared between the
binaries.
keybaseca is the CA server that exposes an interface through Keybase chat. Generate a new CA key by running
keybaseca generate. This will output the CA public key. It also writes a kssh (see below) config file to
/keybase/team/teamname.ssh/kssh-client.config such that kssh can automatically detect the config file.
keybaseca service starts the CA chatbot service. See keybaseca/config.go for a description of the config file.
kssh is the replacement SSH binary. It automatically pulls config files from KBFS.
This project contains integration tests that can be run via ./integrationTest.sh.
kssh allows you to define realms of servers where access is granted based off of membership in different teams. Imagine that you have a staging environment that everyone should be granted access to and a production environment that you want to restrict access to a smaller group of people. For this exercise we'll also set up a third realm that grants root access to all machines. To configure kssh to work with this setup:
- Create three subteams:
{TEAM}.ssh.staging,{TEAM}.ssh.production,{TEAM}.ssh.root_everywhere - Add users to those three teams based off of the permissions you want to grant different users
cd docker/
cp env.sh.example env.sh
keybase signup # Follow the prompts to create a new Keybase users to use for the SSH CA bot
keybase paperkey # Generate a new paper key
# Create `{TEAM}.ssh.staging`, `{TEAM}.ssh.production`, `{TEAM}.ssh.root_everywhere` as new Keybase subteams
# and add the bot to those subteams. Add users to those subteams based off of the permissions you wish to grant
# different users
nano env.sh # Fill in the values including the previously generated paper key
make generateThis will output the public key for the CA.
For each server in staging:
- Place the public key in
/etc/ssh/ca.pub - Add the line
TrustedUserCAKeys /etc/ssh/ca.pubto/etc/ssh/sshd_config - Add the line
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%uto/etc/ssh/sshd_config - Create the file
/etc/ssh/auth_principals/rootwith contentsroot_everywhere - Create the file
/etc/ssh/auth_principals/userwith contentsstaging - Restart ssh
service ssh restart
For each server in production:
- Place the public key in
/etc/ssh/ca.pub - Add the line
TrustedUserCAKeys /etc/ssh/ca.pubto/etc/ssh/sshd_config - Add the line
AuthorizedPrincipalsFile /etc/ssh/auth_principals/%uto/etc/ssh/sshd_config - Create the file
/etc/ssh/auth_principals/rootwith contentsroot_everywhere - Create the file
/etc/ssh/auth_principals/userwith contentsproduction - Restart ssh
service ssh restart
Now start the chatbot itself:
make serveNow build kssh and start SSHing!
go build -o bin/kssh cmd/kssh/kssh.go
sudo cp bin/kssh /usr/local/bin/ # Optional
bin/kssh user@staging-server-ip # If in {TEAM}.ssh.staging
bin/kssh user@production-server-ip # If in {TEAM}.ssh.production
bin/kssh root@server # If in {TEAM}.ssh.root_everywhereIt is recommended to run the server component of this bot on linux and running it in other environments is untested.
kssh is tested and works correctly on linux, macOS, and Windows. If running on windows, note that there is a dependency
on the ssh binary being in the path. This can be installed in a number of different ways including
Chocolatey or the
built in version on
modern versions of windows.