1
0
Fork 0
mirror of https://github.com/Luzifer/vault-openvpn.git synced 2024-12-26 06:41:20 +00:00

Merge remote-tracking branch 'callidus/master' into tls-auth

closes #7
This commit is contained in:
Knut Ahlers 2018-05-27 10:16:00 +02:00
commit 86a9864b56
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
2 changed files with 52 additions and 0 deletions

View file

@ -88,3 +88,32 @@ In case someone needs to get removed from your OpenVPN there is also a revoke:
``` ```
To have revokes being executed by OpenVPN you need to periodically update the CRL file OpenVPN reads. For my solution see the `living-example` in the `example` folder. To have revokes being executed by OpenVPN you need to periodically update the CRL file OpenVPN reads. For my solution see the `living-example` in the `example` folder.
## Using Tls Auth
OpenVPN highly recommends using TLS Authentication hardening, see https://community.openvpn.net/openvpn/wiki/GettingStartedwithOVPN#TLSAuthentication
This requires the use of a pre-shared key, if you want to use it you will first need to generate tls auth key and then upload it to vault.
```bash
openvpn --genkey --secret openvpn.key
vault kv put secret/ovpn key=@openvpn.key
```
In the above example we call the secret "ovpn" but you can call it anything you want, so long as its a known value.
The key must be placed into both the client and server configurations and must match, edit both config templates to include a section as shown below
```
<tls-auth>
{{ .TlsAuth }}
</tls-auth>
```
Now run vault-openvpn passing in the name of the secret that holds our key, e.g.
```bash
# for the server config
vault-openvpn --auto-revoke --ovpn-key ovpn --pki-mountpoint luzifer_io server edda.openvpn.luzifer.io
# and for the client config
vault-openvpn --auto-revoke --ovpn-key ovpn --pki-mountpoint luzifer_io client workwork01.openvpn.luzifer.io
```

23
main.go
View file

@ -45,6 +45,7 @@ var (
AutoRevoke bool `flag:"auto-revoke" vardefault:"auto-revoke" description:"Automatically revoke older certificates for this FQDN"` AutoRevoke bool `flag:"auto-revoke" vardefault:"auto-revoke" description:"Automatically revoke older certificates for this FQDN"`
CertTTL time.Duration `flag:"ttl" vardefault:"ttl" description:"Set the TTL for this certificate"` CertTTL time.Duration `flag:"ttl" vardefault:"ttl" description:"Set the TTL for this certificate"`
OvpnKey string `flag:"ovpn-key" vardefault:"secret/ovpn" description:"Specify a secret name that holds an OpenVPN shared key"`
LogLevel string `flag:"log-level" vardefault:"log-level" description:"Log level to use (debug, info, warning, error)"` LogLevel string `flag:"log-level" vardefault:"log-level" description:"Log level to use (debug, info, warning, error)"`
Sort string `flag:"sort" vardefault:"sort" description:"How to sort list output (fqdn, issuedate, expiredate)"` Sort string `flag:"sort" vardefault:"sort" description:"How to sort list output (fqdn, issuedate, expiredate)"`
@ -71,6 +72,7 @@ type templateVars struct {
CertAuthority string CertAuthority string
Certificate string Certificate string
PrivateKey string PrivateKey string
TlsAuth string
} }
type listCertificatesTableRow struct { type listCertificatesTableRow struct {
@ -290,6 +292,13 @@ func generateCertificateConfig(tplName, fqdn string) error {
tplv.CertAuthority = caCert tplv.CertAuthority = caCert
if cfg.OvpnKey != "" {
tplv.TlsAuth, err = fetchOvpnKey(fqdn)
if err != nil {
return fmt.Errorf("Could not fetch TlsAuth key: %s", err)
}
}
if err := renderTemplate(tplName, tplv); err != nil { if err := renderTemplate(tplName, tplv); err != nil {
return fmt.Errorf("Could not render configuration: %s", err) return fmt.Errorf("Could not render configuration: %s", err)
} }
@ -434,6 +443,20 @@ func getCACert() (string, error) {
return cs.Data["certificate"].(string), nil return cs.Data["certificate"].(string), nil
} }
func fetchOvpnKey(fqdn string) (string, error) {
path := strings.Join([]string{"secret", "data", strings.Trim(cfg.OvpnKey, "/")}, "/")
secret, err := client.Logical().Read(path)
if err != nil {
return "", err
}
if secret == nil {
return "", errors.New("Got no data from backend")
}
return secret.Data["data"].(map[string]interface {})["key"].(string), nil
}
func generateCertificate(fqdn string) (*templateVars, error) { func generateCertificate(fqdn string) (*templateVars, error) {
path := strings.Join([]string{strings.Trim(cfg.PKIMountPoint, "/"), "issue", cfg.PKIRole}, "/") path := strings.Join([]string{strings.Trim(cfg.PKIMountPoint, "/"), "issue", cfg.PKIRole}, "/")
secret, err := client.Logical().Write(path, map[string]interface{}{ secret, err := client.Logical().Write(path, map[string]interface{}{