Giter Club home page Giter Club logo

unseal's Introduction

Unseal

Unseal is a small, simple go binary that takes a yaml config file and unseals vault servers.

Status

Unseal will not be accepting any new features. All future work will be rolled into hookpick

Why?

When initially deploying vault across multiple sites, you're probably deploying it in a HA config (ie with multiple vault servers in the cluster) and you'll need several people to unseal all of them to get started. This got quite annoying over multiple vault servers and multiple sites, so in order to speed it up, I wrote this little tool.

Features

Some of the advantages you might gain over using the vault HTTP API or the standard vault binary

  • Zero touch interaction. Once you've written your yaml config, you can simply invoke the command and it'll unseal all the servers that need to be unsealed
  • Parallel execution. Each unseal command runs in a goroutine, meaning you can unseal multiple servers in a matter of seconds
  • Overwriting of unseal key stored in memory. The unseal key you use is zeroed out when the unseal operation is completed, meaning it can't be hijacked by malware etc (see considerations for more info)

Usage

In order to use unseal, simply create a config file. Here's an example:

hosts:
  - name: vault-server-1
    port: 8200
    key: <base64 encoded key>
  - name: vault-server-2
    port: 8200
    key: <base64 encoded key>
  - name: different-site-vault-server.example.com 
    port: 8200
    key: <different base64 encoded key>

The app will look for the config file in the following directories, in order:

  • /etc/unseal/config.yaml
  • $HOME/.unseal/config.yaml
  • config.yaml (in the directory you're running the binary from)

Once that's done, simply run the binary:

./unseal
INFO[0007] Unseal operation performed                    host=site1-consulserver-1 progress=2 threshold=3
INFO[0007] Unseal operation performed                    host=site1-consulserver-2 progress=2 threshold=3
INFO[0008] Unseal operation performed                    host=site1-consulserver-3 progress=2 threshold=3
INFO[0008] Vault is unsealed!                            host=site2-consulserver-2 progress=0 threshold=3
INFO[0008] Vault is unsealed!                            host=site2-consulserver-1 progress=0 threshold=3
INFO[0008] Vault is unsealed!                            host=site2-consulserver-3 progress=0 threshold=3
INFO[0008] Vault is unsealed!                            host=site3-consulserver-1 progress=0 threshold=3
INFO[0008] Vault is unsealed!                            host=site3-consulserver-3 progress=0 threshold=3
INFO[0008] Vault is unsealed!                            host=site3-consulserver-2 progress=0 threshold=3

Your vault server progress is now 1 of 3. Yay!

GPG Support

While you can of course store the unseal keys in plaintext in your config.yaml - it is a really bad idea.

With that in mind, Unseal supports GPG decryption. If you've initialized your Vault servers using PGP/GPG (and in my opinion, you really should) you can specify the base64 encrypted unseal token for your host, and unseal will prompt you for your GPG passphrase to decrypt the key.

An example config would look like this:

gpg: true
hosts:
  - name: test
  - port: 8200
  - key: <base 64 encoded gpg encrypted key>

Note - if you have a GPG agent running and you've put the unseal keys in your config.yaml - anyone with access to your machine can easily decrypt the values without having to know your GPG password. Be warned.

Troubleshooting

Unseal simply executes the gpg command to decrypt keys. If you're having any issues with GPG support, I'd suggest doing the following:

  1. Ensure you can decrypt the keys manually. Use echo <base64_key> | base64 -D | gpg -dq. If this doesn't work, unseal won't work either
  2. Ensure you have gpg-agent running, and have a valid gpg-agent.conf
  3. Ensure your key is a valid base64 encoded string. Again, echo <base64_key> | base64 -D | gpg -dq will verify this

CAPath

Unseal does not support unsecured HTTP API calls, and you probably shouldn't be using Vault over HTTP anyway :)

All your vault servers may use different CA certs, so you can specify a directory with CA certs in it which vault will read and use to attempt to verify the vault server.

Simple specify it like this in your config file:

capath: "/path/to/ca/certs"
hosts:
  - name: test
  - port: 8200
  - key: <key>

Environment Variables

By default, vault will read some environment variables to do the unseal config. You can find them here

You can use some of these environment variables if you wish when using unseal.

  • VAULT_CACERT: Set this to the path of a CA Cert you wish to use to verify the vault connection. Note, this will use the same CA cert for all vaults
  • VAULT_CAPATH: An alternative to the above CA Path config option.
  • VAULT_CLIENT_CERT: An SSL client cert to use when connecting to your vaults. Note, this will use the same cert for all vaults
  • VAULT_CLIENT_KEY: An SSL client key to use when connecting to your vaults. Note, this will use the same key for all vaults
  • VAULT_SKIP_VERIFY: Skip SSL verification. This is not recommended in production use.

Considerations

A few security considerations before you use this tool.

  • Your unseal key is clearly stored in plaintext in the yaml file. This is clearly a security issue. Please don't store your unseal key in plaintext permanantly.
  • While I've taken steps to overwrite the unseal key in memory, I am not a Golang expert and it may not be fool proof. If you think you can improve the implementation, pull requests will be warmly welcomed
  • I am just getting started with Golang, and therefore there may be errors, security issues and gremlins in this code. Again, pull requests are much appreciated.
  • There is currently no way of setting HTTPS certificates, so you must trust the certificate presented by the vault API

Building

If you want to contribute, we use glide for dependency management, so it should be as simple as:

  • cloning this repo into $GOPATH/src/github.com/jaxxstorm/unseal
  • run glide install from the directory
  • run go build -o unseal main.go

unseal's People

Contributors

jaxxstorm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

unseal's Issues

Overwrite unsealkey

In order to ensure we don't compromise the unseal key, we should overwrite the buffer with nonsense once the key has been used

Add a version command

Currently we have no idea which version we're running!

Add a version command so we can see :)

Key validation

If the unseal key is not a valid base64 encoded string, we get a panic:

[root@consulserver-0 unseal]# /usr/local/bin/unseal --config config.yaml
INFO[0000] Vault is unsealed!                            host=consulserver-0.briggs.lan progress=0 threshold=1
ERRO[0000] Error running unseal operation                host=consulserver-2.briggs.lan
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x45c1d6]

We should verify it's properly base64 encoded before we try running the goroutine.

Also, if the config array doesn't contain a key, it'll bomb. We should check there's a key present for the entry

Create a setup and add command

Probably a later task, but nice to have.

It would be good to be able to run something like unseal setup and have it build the yaml config for you.

Additionally, if I want to add a new host, being able to run unseal add would be a good addition

Remove all `panic` exits

Currently, when bad things happen, the app panics. This leads to an unfriendly output.

We should instead capture the err in a log output, then use os.Exit to stop the process.

Better logging

Currently, the app just uses fmt package to dump a bunch of stuff to stdout.

It'd be much better to use the logrus package to get proper output logging!

Sane configuration defaults and checking

Currently, if someone forgets some config details/options, unseal will panic.

We should do some basic sanity checking such as:

  • If GPG is enabled, set a sane default of $HOME/.gnupg/secring.gpg etc
  • Check if the files exist, and log.Fatal if not (only if GPG support is enabled

GPG support

Currently we are prompted for the key, which gives us no benefit over the standard Vault command line tool.

Add support for GPG to the config file! This way, we can specify the path to GPG keys during usage, and it can automagically unlock the GPG keyring and grab the token.

Configuration Support

One of the key features is the ability to unlock multiple vaults in one go, using multiple different keys.

Support a configuration file which allows users to specify a site, as well as the type of unseal key (whether it be GPG, standard etc) as well as an array of hostnames which should be checked/unlocked. Something like:

dev:
  type: GPG
  hosts:
    - vault1
    - vault2

prod:
  type: keybase
  hosts:
    - vault3
    - vault4

Would be ideal

Add a warning when env vars are set

If you set something like VAULT_ADDR you end up with a situation whereby unseal will read that config value, and then the client that gets created is only for that host. Example output from dumper.

If VAULT_ADDR is set, we should print a warning saying it's there so people are aware.

No support for newer versions of GnuPG

I've made an assumption that when you've generated a GPG key, you'll have a [secring[(https://github.com/jaxxstorm/unseal/blob/master/gpg/decrypt.go#L16).

However, in newer versions of GnuPG, it doesn't exist. See the release notes for GnuPG release 2.1 here.

With that in mind, we need to figure out how to support newer versions of GnuPG. Fun.

Exit when no config file found

Currently, if there's no config file, unseal won't tell you it didn't find one.

We should change this, and have it exit when it doesn't find one.

Better differentiate between unsealed and sealed servers

Currently, when you run unseal, it's not clear if the server is sealed or unsealed without grokking the comments.

Example:

INFO[0000] Using GPG
Please enter your password:
INFO[0005] Unseal operation performed                    host=consul-2 progress=1 threshold=3
INFO[0005] Vault is unsealed!                            host=consul-1 progress=0 threshold=3

It would be better to have either:

  • Some colour coding to the output
  • Another field with the current status of the server

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.