cloudtools / ssh-cert-authority

An implementation of an SSH certificate authority.
BSD 2-Clause "Simplified" License
723 stars 71 forks source link

Minimal instructions for ssh-cert-authority for your wiki #47

Open tkschmidt opened 3 years ago

tkschmidt commented 3 years ago

Hey, thank you for your project.

I think your project could hit a sweet spot for me/us between manually signing keys and setting up a complete vault. But I'm still hitting a wall. Could you perhaps tell me what Im doing wrong?

Creation of authority

root@identity-1:~/ssh-cert-authority# ssh-keygen -f my_ssh_cert_authority
Generating public/private rsa key pair.
Your identification has been saved in my_ssh_cert_authority.
Your public key has been saved in my_ssh_cert_authority.pub.
The key fingerprint is:
SHA256:Q9yWgSdLa2VLgjF/xeiwytoP6xmz7C87WsLY5G6ekKQ root@identity-1

The public key would than be distributed to all servers.

User

private CA

Next, every user would generate their private CA (?)

root@identity-1:~/ssh-cert-authority# ssh-keygen -f my_ssh_cert_authority_private
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in my_ssh_cert_authority_private.
Your public key has been saved in my_ssh_cert_authority_private.pub.
The key fingerprint is:
SHA256:xhHdtjZgGAYznjlSvc/qN8H2p2P6AhAGkkNYJq2WOzg root@identity-1

private/public keys

root@identity-1:~/ssh-cert-authority# ssh-keygen
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Hg/ZTAn+BkoICveRpi0hkupEwYHmN7TTOXWv0fCwSKA root@identity-1

Server

So, I would put the key fingerprint of the private CA as an authorizedUser as well as identity

Therefore my sign_certd_config.json would look like

{
   "production":{
      "NumberSignersRequired":1,
      "MaxCertLifetime":86400,
      "PrivateKeyFile":"/root/ssh-cert-authority/my_ssh_cert_authority",
      "AuthorizedUsers":{
         "SHA256:xhHdtjZgGAYznjlSvc/qN8H2p2P6AhAGkkNYJq2WOzg":"root@identity-1"
      }
   }
}

With that at hand, I started the server

root@identity-1:~/ssh-cert-authority# ssh-add my_ssh_cert_authority
Identity added: my_ssh_cert_authority (my_ssh_cert_authority)
root@identity-1:~/ssh-cert-authority# ./ssh-cert-authority runserver --config-file ./sign_certd_config.json --listen-address 0.0.0.0:8080
2021/04/13 07:21:11 Server running version 2.0.0-6-g59dae40
2021/04/13 07:21:11 Using SSH agent at /tmp/ssh-UGpiNK15qM/agent.26492
2021/04/13 07:21:11 Added private key for env production: d6:05:03:9a:40:f9:db:11:80:eb:cd:43:39:9f:7a:a9
2021/04/13 07:21:11 Server started with config map[string]ssh_ca_util.SignerdConfig{"production":ssh_ca_util.SignerdConfig{SigningKeyFingerprint:"d6:05:03:9a:40:f9:db:11:80:eb:cd:43:39:9f:7a:a9", AuthorizedSigners:map[string]string(nil), AuthorizedUsers:map[string]string{"SHA256:C4wJWc3767N6rQlXqtVzxpWmtThOrQMFCHI4vU7Wxp4":"root@identity-1"}, NumberSignersRequired:1, SlackUrl:"", SlackChannel:"", MaxCertLifetime:86400, PrivateKeyFile:"/root/ssh-cert-authority/my_ssh_cert_authority", KmsRegion:"", CriticalOptions:map[string]string(nil)}}

User

Preparation

Lets first get a requester_config.json

mkdir -p ~/.ssh_ca/
./ssh-cert-authority generate-config --url=http://localhost:8080 > ~/.ssh_ca/requester_config.json

and the content looks like

{
    "production": {
        "PublicKeyPath": "/root/.ssh/id_rsa.pub",
        "SignerUrl": "http://localhost:8080/"
    }
}

Sigining a key for my request

root@identity-1:~/ssh-cert-authority# ssh-keygen -V +1h -s my_ssh_cert_authority_private -I confusedGithubPerson -n ubuntu ~/.ssh/id_rsa.pub
Signed user key /root/.ssh/id_rsa-cert.pub: id "confusedGithubPerson" serial 0 for ubuntu valid from 2021-04-13T07:33:00 to 2021-04-13T08:34:58

Lets check the public key

root@identity-1:~/ssh-cert-authority# ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub
/root/.ssh/id_rsa-cert.pub:
        Type: ssh-rsa-cert-v01@openssh.com user certificate
        Public key: RSA-CERT SHA256:Hg/ZTAn+BkoICveRpi0hkupEwYHmN7TTOXWv0fCwSKA
        Signing CA: RSA SHA256:xhHdtjZgGAYznjlSvc/qN8H2p2P6AhAGkkNYJq2WOzg
        Key ID: "confusedGithubPerson"
        Serial: 0
        Valid: from 2021-04-13T07:33:00 to 2021-04-13T08:34:58
        Principals:
                ubuntu
        Critical Options: (none)
        Extensions:
                permit-X11-forwarding
                permit-agent-forwarding
                permit-port-forwarding
                permit-pty
                permit-user-rc

Request a certificate

./ssh-cert-authority request --environment production --reason "Do important maintenance work"

but will receive

Cert request rejected: Cert not valid: not signed by an authorized key

on the client-side and the server will show

2021/04/13 07:36:51 Invalid certificate signing request received from 127.0.0.1:40682, ignoring

This means I do something wrong and are stopped here https://github.com/cloudtools/ssh-cert-authority/blob/6c6c46312dfb36bd7bbdf08a290997198077c2a2/sign_certd.go#L405-L409

My mistake must be in the sign_certd_config.json, but I don't understand how it can be wrong as the AuthorizedUsers is exactly the key that is used for my request.

Could you point in the correct direction?

bobveznat commented 3 years ago

Users shouldn't generate a CA. There's only one CA per environment and it's purely on the server side.

Given that, the config on the server for the user should specific the fingerprint of the is_rsa.pub of the user (SHA256:Hg/ZTAn+BkoICveRpi0hkupEwYHmN7TTOXWv0fCwSKA)

And then it's been a long time but I don't remember implementing support for sha256. If the sign certd config loaded maybe I did implement it and I'm just forgetting. Otherwise use the md5 format in config files. Pass -E md5 to ssh key utilities to get this format.

That was the only anomaly I saw while reading through this. Please let me know if this doesn't get you going.

On Tue, Apr 13, 2021, 1:02 AM Tobias @.***> wrote:

Hey, thank you for your project.

I think your project could hit a sweet spot for me/us between manually signing keys and setting up a complete vault. But I'm still hitting a wall. Could you perhaps tell me what Im doing wrong. Creation of of authority

@.:~/ssh-cert-authority# ssh-keygen -f my_ssh_cert_authority Generating public/private rsa key pair. Your identification has been saved in my_ssh_cert_authority. Your public key has been saved in my_ssh_cert_authority.pub. The key fingerprint is: SHA256:Q9yWgSdLa2VLgjF/xeiwytoP6xmz7C87WsLY5G6ekKQ @.

The public key would than be distributed to all servers. User private CA

Next, every user would generate their private CA (?)

@.:~/ssh-cert-authority# ssh-keygen -f my_ssh_cert_authority_private Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in my_ssh_cert_authority_private. Your public key has been saved in my_ssh_cert_authority_private.pub. The key fingerprint is: SHA256:xhHdtjZgGAYznjlSvc/qN8H2p2P6AhAGkkNYJq2WOzg @.

private/public keys

@.:~/ssh-cert-authority# ssh-keygen Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:Hg/ZTAn+BkoICveRpi0hkupEwYHmN7TTOXWv0fCwSKA @.

Server

So, I would put the key fingerprint of the private CA as an authorizedUser as well as identity

Therefore my sign_certd_config.json would look like

{ "production":{ "NumberSignersRequired":1, "MaxCertLifetime":86400, "PrivateKeyFile":"/root/ssh-cert-authority/my_ssh_cert_authority", "AuthorizedUsers":{ @.***" } } }

With that at hand, I started the server

@.:~/ssh-cert-authority# ssh-add my_ssh_cert_authority Identity added: my_ssh_cert_authority (my_ssh_cert_authority) @.:~/ssh-cert-authority# ./ssh-cert-authority runserver --config-file ./sign_certd_config.json --listen-address 0.0.0.0:8080 2021/04/13 07:21:11 Server running version 2.0.0-6-g59dae40 2021/04/13 07:21:11 Using SSH agent at /tmp/ssh-UGpiNK15qM/agent.26492 2021/04/13 07:21:11 Added private key for env production: d6:05:03:9a:40:f9:db:11:80:eb:cd:43:39:9f:7a:a9 2021/04/13 07:21:11 Server started with config map[string]ssh_ca_util.SignerdConfig{"production":ssh_ca_util.SignerdConfig{SigningKeyFingerprint:"d6:05:03:9a:40:f9:db:11:80:eb:cd:43:39:9f:7a:a9", AuthorizedSigners:map[string]string(nil), @.***"}, NumberSignersRequired:1, SlackUrl:"", SlackChannel:"", MaxCertLifetime:86400, PrivateKeyFile:"/root/ssh-cert-authority/my_ssh_cert_authority", KmsRegion:"", CriticalOptions:map[string]string(nil)}}

User Preparation

Lets first get a requester_config.json

mkdir -p ~/.ssh_ca/ ./ssh-cert-authority generate-config --url=http://localhost:8080 > ~/.ssh_ca/requester_config.json

and the content looks like

{ "production": { "PublicKeyPath": "/root/.ssh/id_rsa.pub", "SignerUrl": "http://localhost:8080/" } }

Sigining a key for my request

@.***:~/ssh-cert-authority# ssh-keygen -V +1h -s my_ssh_cert_authority_private -I confusedGithubPerson -n ubuntu ~/.ssh/id_rsa.pub Signed user key /root/.ssh/id_rsa-cert.pub: id "confusedGithubPerson" serial 0 for ubuntu valid from 2021-04-13T07:33:00 to 2021-04-13T08:34:58

Lets check the public key

@.:~/ssh-cert-authority# ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub /root/.ssh/id_rsa-cert.pub: Type: @. user certificate Public key: RSA-CERT SHA256:Hg/ZTAn+BkoICveRpi0hkupEwYHmN7TTOXWv0fCwSKA Signing CA: RSA SHA256:xhHdtjZgGAYznjlSvc/qN8H2p2P6AhAGkkNYJq2WOzg Key ID: "confusedGithubPerson" Serial: 0 Valid: from 2021-04-13T07:33:00 to 2021-04-13T08:34:58 Principals: ubuntu Critical Options: (none) Extensions: permit-X11-forwarding permit-agent-forwarding permit-port-forwarding permit-pty permit-user-rc

Request a certificate

./ssh-cert-authority request --environment production --reason "Do important maintenance work"

but will receive

Cert request rejected: Cert not valid: not signed by an authorized key

on the client side and the server will show

2021/04/13 07:36:51 Invalid certificate signing request received from 127.0.0.1:40682, ignoring

This means I do something wrong and are stopped here https://github.com/cloudtools/ssh-cert-authority/blob/6c6c46312dfb36bd7bbdf08a290997198077c2a2/sign_certd.go#L405-L409

My mistake must be in the sign_certd_config.json, but I dont understand how it can be wrong as the AuthorizedUsers is exactly the key that is used for my request .

Could you point in the correct direction?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/cloudtools/ssh-cert-authority/issues/47, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAE3A7YBJ7BGG74YLVFCDDDTIPM67ANCNFSM422UUP7Q .

tkschmidt commented 3 years ago

Okay, that was my mistake. I can request a certificate now, will investigate further. Thanks for your help.

I will update the issue with the solution above and close it tomorrow.