Add a README
This commit is contained in:
95
README.md
Normal file
95
README.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# `web-pinentry`: decrypt server keys from your phone
|
||||
|
||||
`web-pinentry` is a [pinentry](https://github.com/gpg/pinentry) program for
|
||||
Linux servers, allowing you to decrypt keys on your server remotely via your
|
||||
phone. It relies on HTTP and the Matrix protocol. This is a modern approach to
|
||||
tasks often faced during server boot up, when things like SQL passwords and API
|
||||
tokens need to be ascertained before services can begin.
|
||||
|
||||
Sensitive server credentials are historically stored in environment variable
|
||||
files. Though this legacy approach eases automated server startup, it carries a
|
||||
huge cost in terms of security. If the server becomes compromised, passwords
|
||||
and other sensitive information within environment variables and plaintext
|
||||
config files poses a security threat. Server admins may ultimately
|
||||
feel compelled to reject server access to engineers or technicians lest they
|
||||
gain knowledge of crucial passwords in config files.
|
||||
|
||||
To solve this headache, passwords can be encrypted with a GPG wrapper tool such
|
||||
as `pass`. Rather than pulling passwords from a file, they are obtained through
|
||||
subprocess calls, e.g.
|
||||
|
||||
`pass sql-root-password`
|
||||
`pass github-token`
|
||||
|
||||
This is standard practice on desktops, but not yet on servers.
|
||||
|
||||
`web-pinentry` attempts to make this workflow more feasible on servers. Programs
|
||||
typically pause for user authentication when executing GPG or `pass` commands. On desktop,
|
||||
a user may types a password or inserts a Yubi key before things can resume. `web-pinentry`
|
||||
does not assume the user has physical access to the computer, taking a radically
|
||||
different yet somewhat simple approach.
|
||||
|
||||
## How `web-pinentry` works
|
||||
|
||||
`web-pinentry` is designed to override the builtin GPG `pinentry` program:
|
||||
Rather than waiting for a password to be typed in the same terminal as the
|
||||
current process, `web-pinentry` awaits a user password over the network
|
||||
via a temporary login link. Here is an example of this altered workflow:
|
||||
|
||||
- An engineer reboots a server.
|
||||
- The init system (systemd or otherwise) starts up the various services.
|
||||
- Among these is a Scala REST API that attempts to reach a remote DB.
|
||||
- In the Scala code, a subprocess is used to configure the SQL password:
|
||||
- I.e. `pass sql-root-password` is executed as the REST API spins up.
|
||||
- Under the hood, GNU `pass` attempts to decrypt a master-password-protected
|
||||
file containing the SQL login details.
|
||||
- This triggers a pinentry program which seeks the master password.
|
||||
|
||||
Usually this is the point at which most naively configured systems would
|
||||
hang or timeout. However, with `web-pinentry` as your default pinentry program,
|
||||
the workflow continues unininterupted:
|
||||
|
||||
- GPG communicates with `web-pinentry`, and the latter spins up a temporary
|
||||
HTTP server.
|
||||
- On this HTTP server, there is exactly one randomly generated path.
|
||||
- This path is sent as a URL to a Matrix channel, where the system admin
|
||||
can then enter the GPG master password.
|
||||
- Passwords and API keys are then momentarily available for the server's
|
||||
startup procedure.
|
||||
|
||||
## Security Details
|
||||
|
||||
- Login paths only live for two GET requests, and the pinentry program must
|
||||
therefore try again with a new link if you type your password wrong.
|
||||
- `web-pinentry`'s HTTP server only responds to requests made via docker
|
||||
network IPs or localhost.
|
||||
- It's imperative to run web-pinentry behind a HTTPS proxy (recommendation: `caddy`).
|
||||
- All paths that are not the login path are restricted.
|
||||
- The login link is sent to Matrix via `matrix-commander-rs`, which needs to be
|
||||
configured in advance.
|
||||
- The login link is randomly generated anew on each invocation.
|
||||
- Once a password is entered correctly, the HTTP server is torn down.
|
||||
|
||||
**WARNING**: It is highly recommended to use a GPG master password that is randomly generated
|
||||
and stored within a password manager. This protects you from phishing attacks
|
||||
and can further automate the pinentry workflow. Without this protection, a bad
|
||||
actor could create a visually similar website to the `web-pinentry` default
|
||||
login, and attempt to prompt you for your password.
|
||||
|
||||
## Requirements
|
||||
|
||||
- [`matrix-commander-rs`](https://github.com/8go/matrix-commander-rs)
|
||||
- [Matrix](https://matrix.org/)
|
||||
- Your Matrix user
|
||||
- A Matrix bot user (just a normal user with a noticeable username like `notification-bot`)
|
||||
- A private Matrix channel between you and the bot (preferably encrypted).
|
||||
- A proxy server with HTTPS support (E.g. [`caddy`](https://caddyserver.com/))
|
||||
- A DNS subdomain/domain you control.
|
||||
For development contributors only:
|
||||
- [`rust`](https://rust-lang.org/)
|
||||
|
||||
## Installation instructions
|
||||
|
||||
```{sh}
|
||||
cargo build
|
||||
```
|
||||
Reference in New Issue
Block a user