Sshecret - Simple Secret management using SSH and RSA Keys
Managing secrets within a container environment or homelab can be quite complex.
As with container orchestration in general, many of the available tools are targetted large enterprise installations and add significant complexity to both the management of secrets themselves, and to the consumers.
For enthusiasts or homelabbers solutions like Hashicorp Vault become overkill quickly, and end up consuming a lot more time and energy than what feels justified.
This system has been created to provide a centralized solution that works well-enough.
Sshecret provides a simple, centralized solution for secret storage, and requires only tools that are commonly pre-installed on most linux system.
Concept
The system uses RSA keys, as generated by openssh, to encrypt secrets for each client.
It uses RSA keys as it is possible to do encryption using only the public key.
By using a custom SSH server, the consuming servers can fetch a version of a secret encrypted specifically for them.
As the secret is encrypted with RSA keys, it can be decrypted using the openssl command which is commonly available.
This means that while the backend interface can be complex, the to access and decrypt a secret, you can use ssh, and a simple bash script.
Components
There are three components to Sshecret:
- Password database and admin interface
- Client secret storage backend
- Ssh server for clients to access
The three systems should be deployed separately for security, with the backend system as the only central component.
The ssh server that the clients connect to, only has access to encrypted versions of the secrets.
If it or the backend should be compromised, it wouldn't be possible to extract any clear-text secrets, since only encrypted values are stored, and each encrypted with RSA public key encryption.
Backend
The backend system stores the definition of each client, including their public key, and the IP addresses/networks they are allowed to connect from. It also stores a version of each secret that the client has access to, encrypted with the public key. It has no knowledge of the unencrypted secrets.
Both the admin interface and the ssh server access this system over a REST API using a token-based authentication method.
Password database and admin interface
The sshecret password database is based on keepass, and the admin interface is available as a simple web interface as well as a REST API.
This component is primarily responsible for storing the secrets in a keepass database and populating the backend with client-specific encrypted versions.
The admin interface must be secured. It currently supports local user accounts, but will be expanded with OIDC support in the near future.
Custom SSH server
To make it easy to fetch secrets sshecret includes a SSH server.
To fetch a secret, simply ssh to it using the client name as username and the registered RSA key as authorization.
Send the command get_secret followed by the name of the secret. The ssh server
will check the client's public key against permitted keys, and check if the
client is allowed to connect and if the secret is available to it.
The server will answer with a base64 encoded version of the secret.
See examples/sshecret-client.bash for an example of a bash script that can be
used to fetch and decrypt a secret.
Out of the box, only the get_secret command is available, however an optional
command register can be enabled to allow registration of a client using the
SSH interface to make it easy to onboard new clients automatically.
Configuration
Each subsystem is set up using environment variables.
Backend
The location and type of database may be configured. For now, only sqlite is officially supported.
The value shown below is the default value. In a docker setup, you may want to create a volume and configure this to a path within the volume to be able to perform backups.
SSHECRET_BACKEND_DATABASE=/path/to/sshecret.db
While the backend can be placed behind reverse proxy and served with HTTPS, it's probably better to have keep it inside an internal container network.
Admin
The backend must be generated on the backend before setting up the admin.
SSHECRET_BACKEND_URL=http://backend:8022
SSHECRET_ADMIN_BACKEND_TOKEN: mySuperSecretBackendToken
Deployment
The system can be deplyed using docker or any other container runtime.
See the examples in the docker/ folder.
FAQ
Why not use Age?
I like age a lot, and it's ability to use more ssh key types is certainly a winner feature. However, a clear goal of this project is to be able to construct a client with minimal dependencies.
Using just RSA keys, you can construct a client using only the following tools:
- base64
- openssl
- ssh
This means that you can create a client using just a shell script.
If age were to be used, the age tool would have to be installed on each client sytem.