1
0
Fork 0

step-ca: Redeploy with DCH CA R3

I never ended up using _Step CA_ for anything, since I was initially
focused on the SSH CA feature and I was unhappy with how it worked
(which led me to write _SSHCA_).  I didn't think about it much until I
was working on deploying Grafana Loki.  For that project, I wanted to
use a certificate signed by a private CA instead of the wildcard
certificate for _pyrocufflink.blue_.  So, I created *DCH CA R3* for that
purpose.  Then, for some reason, I used the exact same procedure to
fetch the certificate from Kubernetes as I had set up for the
_pyrocufflink.blue_ wildcard certificate, as used by Frigate.  This of
course defeated the purpose, since I could have just as easily used
the wildcard certificate in that case.

When I discovered that Grafana Loki expects to be deployed behind a
reverse proxy in order to implement access control, I took the
opportunity to reevaluate the certificate issuance process.  Since a
reverse proxy is required to implement the access control I want (anyone
can push logs but only authenticated users can query them), it made
sense to choose one with native support for requesting certificates via
ACME.  This would eliminate the need for `fetchcert` and the
corresponding Kubernetes API token.  Thus, I ended up deciding to
redeploy _Step CA_ with the new _DCH CA R3_ for this purpose.
etcd
Dustin 2024-02-20 09:17:20 -06:00
parent 4c238a69aa
commit d08cc6fb0f
9 changed files with 105 additions and 101 deletions

View File

@ -0,0 +1,13 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: step-ca
namespace: argocd
spec:
destination:
server: https://kubernetes.default.svc
project: default
source:
path: step-ca
repoURL: https://git.pyrocufflink.blue/infra/kubernetes.git
targetRevision: master

View File

@ -10,80 +10,39 @@ OpenID Connect, mTLS, and more.
## Offline Root CA
The *dch Root CA R2* private key is managed externally from Step CA. It is
stored offline (on a flash drive in a fireproof save). Only the CA certificate
The *DCH Root CA R3* private key is managed externally from Step CA. It is
stored offline (on a flash drive in a fireproof safe). Only the CA certificate
is used by the online CA service, where it is provided to clients to include in
as a trust anchor in their respective certificate stores.
*dch Root CA R2* replaces *dch Root CA R1*, which has not been used for some
time.
*DCH Root CA R3* replaces *DCH Root CA R2*, which never ended up being used,
and *DCH Root CA R1*, which has not been used for some time.
## Online Intermediate CA
Step CA manages the *dch CA R2* intermediate certificate authority. The
Step CA manages the *DCH CA R3* intermediate certificate authority. The
private key for this CA is stored in the `intermediate_ca.key` file, encrypted
with the password in `password`. This key pair is needed by the online CA to
sign end-entity certificates.
## SSH CA
### ACME Provisioner
In addition to X.509 (TLS) certificates, Step CA can also manage SSH
certificates. These can be used in place of "plain" SSH keys that must be
managed out-of-band (i.e. `~/.ssh/known_hosts` and `~/.ssh/authorized_keys`).
Hosts can obtain certificates signed by *DCH CA R3* using the ACME protocol.
The CA will only sign certificates for names that map to addresses controlled
by the requesting client. For most machines, that means they can only get a
certificate for their hostname. Other names can be added using DNS CNAME
records.
Instead of maintaining a database of hosts' public keys, clients can trust the
CA certificate that signs the hosts' certificates. To do so, simply add a
single line to `~/.ssh/known_hosts`:
Only the `http-01` and `tls-alpn-01` challenges will work, since clients cannot
modify DNS server records.
```
@cert-authority *.pyrocufflink.blue ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ8KfNjDh0R/jCmPcJrVafvmuw5JZw+cKoy9RCYNwHsRwPoRHfyzjV1VUZolJfEz+Qm3u+mgYJ/oSquCelY84xE=
```
Any host with a hostname that matches `*.pyrocufflink.blue` and presents a
certificate signed by the listed certificate will be automatically trusted; the
`ssh` client will not prompt for manual key verification on the first
connection.
### OIDC Provisioner
Similarly, hosts can trust client keys that are signed by the CA by *either*
adding the certificate to per-user `~/.ssh/authorized_keys` files *or* by
setting the global `TrustedUserCAKeys` parameter in the SSH server
configuration.
`~/.ssh/authorized_keys`:
```
cert-authority ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBImIoTTmhynCVy/vJ/Q2bWydzqVsvwhGvDgBbklw0eDt8UEbbP9HHPhxiMDtiAhbvRTg5BhYVAlR1MgdooT5dwQ=
```
`/etc/ssh/sshd_config`:
```
TrustedUserCAKeys /etc/ssh/ca.pub
```
`/etc/ssh/ca.pub`:
```
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBImIoTTmhynCVy/vJ/Q2bWydzqVsvwhGvDgBbklw0eDt8UEbbP9HHPhxiMDtiAhbvRTg5BhYVAlR1MgdooT5dwQ=
```
SSH host certificates are typically valid for 30 days, so hosts need to have
some automation in place to automatically renew their certificates. Using the
"SSHPOP" provisioner, hosts can use the `step ssh renew` command to renew their
certificates; existing signed SSH certificates are usable as authentication
credentials.
SSH user certificates are typically valid for 24 hours. Clients will need to
request a new certificate every day using the `step ssh login` command:
```sh
step ssh login --provisioner=authelia dustin
```
Note the `--provisioner=authelia` argument seems to be required, even if a
default provisioner is specified in `~/.step/config/defaults.json`.
The final positional argument is the name of the *remote* SSH user, *not* the
user logging in to the OIDC IdP.
Step CA is configured to integrate with Authelia for OpenID Connect
authorization. Users can obtain personal certificates using this provisioner.
## NodePort Service (No Ingress)

View File

@ -8,28 +8,44 @@
"dnsNames": [
"ca.pyrocufflink.blue"
],
"ssh": {
"hostKey": "secrets/ssh_host_ca_key",
"userKey": "secrets/ssh_user_ca_key"
},
"logger": {
"format": "text"
"format": "json"
},
"db": {
"type": "badgerv2",
"dataSource": "db",
"badgerFileLoadingMode": ""
"type": "bbolt",
"dataSource": "db/step.db"
},
"authority": {
"enableAdmin": true,
"provisioners": []
"claims": {
"enableSSHCA": false,
"disableRenewal": false,
"allowRenewalAfterExpiry": false,
"disableSmallstepExtensions": false
},
"provisioners": [
{
"type": "ACME",
"name": "acme"
},
{
"type": "OIDC",
"name": "authelia",
"clientID": "step-ca",
"clientSecret": "",
"configurationEndpoint": "https://auth.pyrocufflink.blue/.well-known/openid-configuration",
"admins": [
"dustin@hatch.name"
]
}
],
"backdate": "1m0s"
},
"tls": {
"cipherSuites": [
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
],
"minVersion": 1.2,
"minVersion": 1.3,
"maxVersion": 1.3,
"renegotiation": false
}

View File

@ -1,13 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICCTCCAa+gAwIBAgIUOrt38QEPFGRaBSZgyuDNQPCLUZowCgYIKoZIzj0EAwIw
QDELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD0R1c3RpbiBDLiBIYXRjaDEXMBUGA1UE
AwwORENIIFJvb3QgQ0EgUjIwHhcNMjMwOTI4MDI0NzMwWhcNMjMxMDI4MDI0NzMw
WjAUMRIwEAYDVQQDEwlkY2gtY2EgUjIwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AAQ1rK98igj6Y5lbeP8HS1zqQCtkcmz8uk1jp4VgznWT3Q8BanjA55UHQi/xx4xz
BYu4QIkJhtqcR5a7YXSr7fQvo4GyMIGvMB0GA1UdDgQWBBQGy1GZZxrCjGDiIGdR
YhTMZZqhkTAfBgNVHSMEGDAWgBTM+d8kb1koGmKRtJs4gN9zYa+6oTASBgNVHRMB
Af8ECDAGAQH/AgEAMAsGA1UdDwQEAwIBhjBMBggrBgEFBQcBAQRAMD4wPAYIKwYB
BQUHMAKGMGh0dHBzOi8vZHVzdGluLmhhdGNoLm5hbWUvZGNoLWNhL2RjaC1yb290
LWNhLmNydDAKBggqhkjOPQQDAgNIADBFAiADzZFTGwWNkwZF1U7uZEon7D6sLmCS
WGftl3/IgOrpwwIhAM8bE5UlY3gXt8AObj8VQgGk5Bh38jmOXnDaK0iRz1qm
MIICTzCCAgGgAwIBAgIUDNTFsSYYl8xsEcg9kTatxvOSkmUwBQYDK2VwMEAxCzAJ
BgNVBAYTAlVTMRgwFgYDVQQKDA9EdXN0aW4gQy4gSGF0Y2gxFzAVBgNVBAMMDkRD
SCBSb290IENBIFIzMB4XDTI0MDIxNzIwMjk0M1oXDTI1MDIxNzIwMjk0M1owOzEL
MAkGA1UEBhMCVVMxGDAWBgNVBAoMD0R1c3RpbiBDLiBIYXRjaDESMBAGA1UEAwwJ
RENIIENBIFIzMCowBQYDK2VwAyEA50stJ8iW6/f+uECPxAJwpSfQDRQg4/AgKJY2
lpd3uNijggEQMIIBDDAdBgNVHQ4EFgQUtiqtFaZZ/c4IfWXV5SjJIOPbmoowHwYD
VR0jBBgwFoAUtmjEAcG9apstYyBr8MACUb2J2jkwEgYDVR0TAQH/BAgwBgEB/wIB
ADALBgNVHQ8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMEwG
CCsGAQUFBwEBBEAwPjA8BggrBgEFBQcwAoYwaHR0cHM6Ly9kdXN0aW4uaGF0Y2gu
bmFtZS9kY2gtY2EvZGNoLXJvb3QtY2EuY3J0MDwGA1UdHwQ1MDMwMaAvoC2GK2h0
dHBzOi8vZHVzdGluLmhhdGNoLm5hbWUvZGNoLWNhL2RjaC1jYS5jcmwwBQYDK2Vw
A0EAACaKAJAKejpFXQV+mgPdDXaylvakc4rCEs1pFhPXbbMMGflNOeiiy+c+aMwt
yfObaZ8/YiXxCSjL6/KzRSSjAQ==
-----END CERTIFICATE-----

View File

@ -3,9 +3,14 @@ kind: Kustomization
namespace: step-ca
labels:
- pairs:
app.kubernetes.io/instance: step-ca
resources:
- namespace.yaml
- step-ca.yaml
- secrets.yaml
configMapGenerator:
- name: step-ca-config
@ -16,13 +21,3 @@ configMapGenerator:
files:
- root_ca.crt
- intermediate_ca.crt
- ssh_host_ca_key.pub
- ssh_user_ca_key.pub
secretGenerator:
- name: step-ca
files:
- intermediate_ca.key
- password
- ssh_host_ca_key
- ssh_user_ca_key

View File

@ -1,12 +1,11 @@
-----BEGIN CERTIFICATE-----
MIIBxDCCAWqgAwIBAgIUbHz2tssa09zsHk+EdGD3QKprMKQwCgYIKoZIzj0EAwQw
QDELMAkGA1UEBhMCVVMxGDAWBgNVBAoMD0R1c3RpbiBDLiBIYXRjaDEXMBUGA1UE
AwwORENIIFJvb3QgQ0EgUjIwHhcNMjMwOTI0MjA1MzA5WhcNNDMwOTE5MjA1MzA5
WjBAMQswCQYDVQQGEwJVUzEYMBYGA1UECgwPRHVzdGluIEMuIEhhdGNoMRcwFQYD
VQQDDA5EQ0ggUm9vdCBDQSBSMjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE2D
NJHRcjuA19ZoprBKaxIfUxAbz6LigM7dgtO6+isaMlxRAVJmsITADIE/22RrUDgD
Ofkt2iZTUjMrz3AxXhWjQjBAMB0GA1UdDgQWBBTM+d8kb1koGmKRtJs4gN9zYa+6
oTASBgNVHRMBAf8ECDAGAQH/AgEBMAsGA1UdDwQEAwIBBjAKBggqhkjOPQQDBANI
ADBFAiEA2Ka8mMiAFLmrFWt0dAml247re2+i4UPhyHcOBfNK+goCIHv+vEw7CHZQ
irIa697nfe4KiXIMwHlAMS1+1QZohFDC
MIIBgTCCATOgAwIBAgIUTf/ZBSJEi8IQb8Ndoxp4/tHB/lcwBQYDK2VwMEAxCzAJ
BgNVBAYTAlVTMRgwFgYDVQQKDA9EdXN0aW4gQy4gSGF0Y2gxFzAVBgNVBAMMDkRD
SCBSb290IENBIFIzMB4XDTI0MDIxNzIwMjkzNloXDTM0MDIxNzIwMjkzNlowQDEL
MAkGA1UEBhMCVVMxGDAWBgNVBAoMD0R1c3RpbiBDLiBIYXRjaDEXMBUGA1UEAwwO
RENIIFJvb3QgQ0EgUjMwKjAFBgMrZXADIQDORylVcWcxwGDJvsJIc2NctfNfDaIU
T6mLebahKdshaKM/MD0wHQYDVR0OBBYEFLZoxAHBvWqbLWMga/DAAlG9ido5MA8G
A1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMAUGAytlcANBANLV79joVd9s9bmL
0a91HqvOotOnN/416Ek4UTl95jIqy/TvTfRjXX56wSALXqP1iYQM5i3zk3gVEhh4
DaY+6wQ=
-----END CERTIFICATE-----

22
step-ca/secrets.yaml Normal file
View File

@ -0,0 +1,22 @@
apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
name: step-ca
namespace: step-ca
labels:
app.kubernetes.io/name: step-ca
app.kubernetes.io/component: step-ca
app.kubernetes.io/instance: step-ca
app.kubernetes.io/part-of: step-ca
spec:
encryptedData:
intermediate_ca.key: AgA4MOOCi8WvBSqyGw6T1wrK7zGgC7kvHYNpgZpZlBq3ZcW4l2d/huT7SbpIUQZN8OhLsgsZqK73VisFRsTG//KrMsJ+CCv6DSpaoEEL0LzUFWVldK27oZ3CDfAo6pZS50M8DSzcA7foxvw7++DSnytS9ken6qu2Azf3iFOFetES23XMT7IIFfcJz+qgBVGIOrxYULj19Y3EZD++kgRM22pCSrnoOQHJV3DOE6SjMZfg9Nhbg7Z5jrpsoM5w7QXd3g8jfsOS0Yv+95CL5SgTtJBAPqVi/2bK7nPuQxGFBy/qhwktzeeagOgFwe5McnEL0aB8K7GQEhOeIiHNSf/AAffronCdGapHQcthAA9CD3P4qXHogiY6x6JgqOXaZ3/BNF4gIlEJoJV36Z51BZUpZLakqOcxw2XNungITq4XMZqUybyqq/oHZEjcqqwSgeHtGJ7aaCAdV1AK4J8kNYXSs0+JcKU+1BzCDTB2YY1nT3uXz5g2d6eLlAe3S6pLDBdZGfyXv4e/nS9ouhdQm9qknNt2hqLAkm5u2g0C6MWYqgCKKdWQBg0JrLvN799zOj5FOGFOEa+gA2t6WwpVeiuo/6Xhn2WtkU710cXdblROM/DWoiI7YUxG4GsmzZOG/1TsbGTPoP1+evxD+VxCIOag6yxBCHnrpUVyCwdp7GLH/+72KyKClhJLb/ub/MKKVTlsWk0JhP3EhfvChO4tbeFMjeGt7afuKKghRt3ZXjAAZFW28qx5oLvirRoUSKOdEU+jE0RWFFeB0Qac9Hz9BFM5iAhdlcpGOOi5bGeMqR/nGlTRV9oUENeopiHBvVXfXr88yumVDE7FzXy4RyC4hypQFddS7kVR3MYoA9c6hWrCAAiuooOKa1JhdfhdlvlQij9PAJW921ClBBXcB2ykcivcrJd6GPAzCHOj6cQjUDeTwarKqZGf1PdtNnCsU1r1V0MOqyuhNjZZ4ZoGEGlq3r3TJY8Hh/+w//ZTpbvHpTUD2rhQjXuVyzqBpU2z5SoFt23U7sV/8+LizZMKfJl9fveJU/CbZ3bGC756ZhpHykbX7bgy9Q0iBg9ke1w+7lepsZVZKhlfnQ==
password: AgAspVB0c402ymidL6YoRTRtmPekLZHlQXtZecftoakjm75OArueAnH+1dquknV4MJ7g8XUVLkguh4lKkNPxjCs2Jen5UM+aSxoqii/2KdTAIb1WINebDOhyj3lY8aZw9+qeDfc5590+x+8jASwm7rVf6QfGygdjwQ6D6xeNUC7xwU3bC8xH9mHq2wSKbI6iGAik4Di7Ma4bvm/nTNfB+Ogb7rdLoJsvDDFbZ1io3wWNJGsWleged2HRPPwkmGq7pkxE2xUpjgbqeWX0y8RbNLC6DwsE3mUce9hanfLvxJVCDMnbUKfUYUxULBMFpheT6lmyz1YgFu+NiuSFvX3An4PNfgeQ2Hl931qfoG9h2kX4wyYcJt0ELZ2tdcrSS7zWgNNx450LuWmGQPvhApLhH2U7CUsSrjbWS/NZKMHuZryp0sEtykoEOOtNezU5slSY/0aB9XWFDu78RaYJOZy1VqGy+ulWkhCFv+3D2MEF6JJXmI4RNTdWmUQx1hr85uTS9Xi6stovkLMHxrEJfDI581yZv7Z9DrSssp5U4Ydf3gjKN7UTgFXrSz25R7SJ4lYso7yHhka9L2YMuIuPS7iPg1F+RPjiG6KAxP3roqRfeMXP3LoDn/21pYsO1QNrq2fBLXaO8Wq0hRXaICZzGveWdeM8sIbjBNqxjb50YtmkF/bDI8BY/sogPWitzDDyNU3bVS5Qyl0AaTHasGzJ9Es26Q4C0GHLd3iVQq0GTSsmtUbZGg==
template:
metadata:
name: step-ca
namespace: step-ca
labels:
app.kubernetes.io/name: step-ca
app.kubernetes.io/component: step-ca
app.kubernetes.io/part-of: step-ca

View File

@ -1 +0,0 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJ8KfNjDh0R/jCmPcJrVafvmuw5JZw+cKoy9RCYNwHsRwPoRHfyzjV1VUZolJfEz+Qm3u+mgYJ/oSquCelY84xE=

View File

@ -1 +0,0 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBImIoTTmhynCVy/vJ/Q2bWydzqVsvwhGvDgBbklw0eDt8UEbbP9HHPhxiMDtiAhbvRTg5BhYVAlR1MgdooT5dwQ=