项目作者: square

项目描述 :
Sharkey is a service for managing certificates for use by OpenSSH
高级语言: Go
项目地址: git://github.com/square/sharkey.git
创建时间: 2016-07-14T18:44:39Z
项目社区:https://github.com/square/sharkey

开源协议:Apache License 2.0

下载


say no to TOFU

sharkey

license
development status
tests
report

Sharkey is a service for managing certificates for use by OpenSSH.

sharks

Sharkey has a client component and a server component. The server is
responsible for issuing signed host certificates, the client is responsible for
installing host certificates on machines. Sharkey builds on the trust relationships
of your existing X.509 PKI to manage trusted SSH certificates. Existing X.509
certificates can be minted into SSH certificates, so you don’t have to maintain
two separate PKI hierarchies.

Build

Check out the repository, and build client/server:

  1. go build -o sharkey-client ./client
  2. go build -o sharkey-server ./server

Server

The server component accepts requests and issues short lived host certificates.

Clients send their public key to the server (via TLS with mutual
authentication) periodically. The server authenticates the client by checking
that its certificate is valid for the requested hostname. If everything looks
good, the server will take the public key in the request and issue an OpenSSH
host certificate for the requested hostname.

A log of all issued certificates is stored in a database. The server can
generate a known_hosts file from the issuance log if required.

Usage:

  1. usage: sharkey-server --config=CONFIG [<flags>] <command> [<args> ...]
  2. Certificate issuer of the ssh-ca system.
  3. Flags:
  4. --help Show context-sensitive help (also try --help-long and --help-man).
  5. --config=CONFIG Path to config file for server.
  6. --version Show application version.
  7. Commands:
  8. help [<command>...]
  9. Show help.
  10. start
  11. Run the sharkey server.
  12. migrate [<flags>]
  13. Set up database/run migrations.

Configuration (example):

  1. # SQLite database
  2. # ---
  3. db:
  4. address: /path/to/sharkey.db
  5. type: sqlite
  6. # MySQL database
  7. # ---
  8. # db:
  9. # username: root
  10. # password: password
  11. # address: hostname:port
  12. # schema: ssh_ca
  13. # type: mysql
  14. # tls: # MySQL TLS config (optional)
  15. # ca: /path/to/mysql-ca-bundle.pem
  16. # cert: /path/to/mysql-client-cert.pem # MySQL client cert
  17. # key: /path/to/mysql-client-cert-key.pem # MySQL client cert key
  18. # Server listening address
  19. listen_addr: "0.0.0.0:8080"
  20. # TLS config for serving requests
  21. # ---
  22. tls:
  23. ca: /path/to/ca-bundle.pem
  24. cert: /path/to/server-certificate.pem
  25. key: /path/to/server-certificate-key.pem
  26. # Signing key (from ssh-keygen)
  27. signing_key: /path/to/ca-signing-key
  28. # Lifetime/validity duration for generated host certificates
  29. host_cert_duration: 168h
  30. # Lifetime/validity duration for generated user certificates
  31. user_cert_duration: 24h
  32. # Optional suffix to strip from client hostnames when generating certificates.
  33. # This is useful if all your machines have a common TLD/domain, and you want to
  34. # include an alias in the generated certificate that doesn't include that suffix.
  35. # Leave empty to disable
  36. strip_suffix: ".example.com"
  37. # Optional set of aliases for hosts. If a hostname matches an alias entry, the
  38. # listed principals will be added to its certificate. This is useful if you have
  39. # special hosts that are accessed via CNAME records.
  40. aliases:
  41. "host.example.com":
  42. - "alias1.example.com"
  43. - "alias2.example.com"
  44. # Optional set of extra entries to provide to clients when they fetch a known_hosts
  45. # file. This is useful if you have externally-managed servers in your infrastructure
  46. # that you want to tell clients about, of if you want to add CA entries to the
  47. # known_hosts file.
  48. extra_known_hosts:
  49. - "@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBwhA8rKPESjDy4iqTlkBqUlBU2xjwtmFUHY6cutA9TYbB5H/mjxzUpnSNw/HyFWNpysjTSQtHWWBdJdJGU/0aDgFUwbduHeDFxviGVSkOxm2AYn7XJopzITZRqmAmsYXHUBa75RQb+UgIG7EpCoi8hF4ItJV+TT777j1irkXwlMmeDiJEaA+7bPNdUdGw8zRbk0CyeotYVD0griRtkXdfgnQAu+DvBwOuW/uiZaPz/rAVjt4b9fmp6pcFKI3RsBqqn5tQVhKCPVuSwqvIQ7CTVkMClYovlH1/zGe8PG1DHbM9irP98S5j3mVD9W5v3QILpsg24RIS14M8pLarlD6t root@authority"
  50. # User certs are issued to users who connect through an authenticating proxy
  51. # That user should connect with a user certificate and set the username
  52. # in a header.
  53. auth_proxy:
  54. # Hostname is validated against the incoming user certificate
  55. hostname: proxy.example.com
  56. # The HTTP header containing the username
  57. username_header: X-Forwarded-User
  58. # Optional settings related to SSH
  59. ssh:
  60. # List of extensions that should be set on the user certificate (default is no extensions)
  61. user_cert_extensions:
  62. - "permit-X11-forwarding"
  63. - "permit-agent-forwarding"
  64. - "permit-port-forwarding"
  65. - "permit-pty"
  66. - "permit-user-rc"

A signing key for generating host certificates can be generated with ssh-keygen.

Database

Sharkey supports both SQLite and MySQL. There is a built-in command in the
server binary to manage migrations (based on goose).

To run migrations on a configured database:

  1. # SQLite
  2. ./sharkey-server --config=[CONFIG] migrate --migrations=db/sqlite
  3. # MySQL
  4. ./sharkey-server --config=[CONFIG] migrate --migrations=db/mysql

You can also manage migrations using the goose command-line utility.
See the goose documentation for more info.

Client

The client component periodically requests a new host certificate from the
server and installs it on the machine.

The client will use a TLS client certificate to make a connection to the server
and authenticate itself. This assumes that there is a long-lived certificate
and key installed on each machine that uses the client. We then periodically
read the host key for the locally running OpenSSH (host_key), send it to the
server, and retrieve a signed host certificate based on that key. The signed
host certificate is then installed on the machine (signed_cert).

Usage:

  1. usage: sharkey-client --config=CONFIG [<flags>]
  2. Flags:
  3. --help Show context-sensitive help (also try --help-long and --help-man).
  4. --config=CONFIG Path to yaml config file for setup
  5. --version Show application version.

Configuration (example):

  1. # Server address
  2. request_addr: "https://sharkey-server.example:8080"
  3. # TLS config for making requests
  4. # ---
  5. tls:
  6. ca: /path/to/ca-bundle.pem
  7. cert: /path/to/client-certificate.pem
  8. key: /path/to/client-certificate-key.pem
  9. # List of host keys for OpenSSH server
  10. host_keys:
  11. # Here, 'key' is the public key, and 'cert' is where to install the signed cert
  12. - plain: "/etc/ssh/ssh_host_rsa_key.pub"
  13. signed: "/etc/ssh/ssh_host_rsa_key-cert.pub"
  14. # You can specify multiple host keys (e.g. if you have both RSA, ED25519 keys)
  15. - plain: "/etc/ssh/ssh_host_ed25519_key.pub"
  16. signed: "/etc/ssh/ssh_host_ed25519_key-cert.pub"
  17. # Where to install the known_hosts file
  18. known_hosts: /etc/ssh/known_hosts
  19. # If set to true, only install authorities in known_hosts file (ignore other machine's host keys).
  20. known_hosts_authorities_only: false
  21. # How often to refresh/request new certificate
  22. sleep: "24h"
  23. # Path to sudo binary on client host
  24. # Uses sudo to write known_hosts and signed_cert.pub if this field specified
  25. sudo: "/usr/bin/sudo"
  26. # Command to restart ssh daemon for the host
  27. # If sudo is set as well, this command will be prefixed with 'sudo'
  28. ssh_reload: ["/usr/sbin/service", "ssh", "restart"]

OpenSSH will have to be configured to read the signed host certificate (this is
with the HostCertificate config option in sshd_config). If the signed host
certificate is missing from disk, OpenSSH will fall back to TOFU with the
default host key. Therefore, it should always be safe to configure a host
certificate; even if the Sharkey client fails you can still SSH into your
machine.

User Certificates

For a user to SSH into an openssh server, they can present a certificate, which
should have a principal matching their username.
Sharkey outsources identifying users to an SSO proxy. That proxy needs to
connect to sharkey over mTLS. You can configure the DNS SAN that should appear
on the server’s client cert (eg, proxy.example.com) and the HTTP header it sets
the username to (eg, X-Forwarded-User). See example configs.

No client helper is included with Sharkey at this time, so you have to set up
a script yourself at this time to enroll the user.

Testing looks something like this:
curl --cert proxy.crt --key proxy.key https://localhost:8080/enroll_user -H "X-Forwarded-User: bob" -d @~/.ssh/bob.pub

But in production use you’d expect it more like
curl <auth to your proxy> https://ssoproxy.example.com/enroll_user -d @~/.ssh/bob.pub

GitHub SSH CA Support

Sharkey supports issuing user certificates that are compatible with GitHub SSH CA format by:

  • Mapping a GitHub username to a SAML identity
  • Including appropriate GitHub username in each certificate

GitHub supports authentication using SSH certificates for Enterprise Cloud accounts. The only requirement is that certificates include GitHub usernames, so that they can be matched to a particular user.

Sharkey already requires SSO proxy for the user certificate feature. Additionally, the GitHub integration requires that the GitHub organization is configured with SSO (i.e. non-GitHub) access.

An example config with GitHub SSH CA Support enabled can be found in test/git_server_config.yaml.
A GitHub App with read/write access to Organization:members is required.

Sharkey will periodically query GitHub for a mapping of SAML identities to GitHub usernames and store it in Sharkey’s DB.
When issuing a certificate, Sharkey will check the DB and if a mapping exists, attaches it to the certificate as an extension.

An example cert is shown below:

  1. Type: ssh-rsa-cert-v01@openssh.com user certificate
  2. Public key: RSA-CERT SHA256:Eabuov2aAPLhN1FscJ6P3Lle85N6Txhj4sy4ALTkG6M
  3. Signing CA: ED25519 SHA256:HYgRf1dHbVtWY/e3jjfnAlwvAPPBKYxdXz8SDfhlAws (using ssh-ed25519)
  4. Key ID: "alice"
  5. Serial: 1
  6. Valid: from 2020-07-31T16:10:25 to 2020-08-01T16:10:25
  7. Principals:
  8. alice
  9. Critical Options: (none)
  10. Extensions:
  11. login@github.com UNKNOWN OPTION (len 5)
  12. permit-X11-forwarding
  13. permit-agent-forwarding
  14. permit-port-forwarding
  15. permit-pty
  16. permit-user-rc

Telemetry

Sharkey supports sending DogStatsD metrics. Currently only metrics regarding GitHub SSH CA are being emitted.
Adding the following block to the server configuration will enable metrics:

  1. telemetry:
  2. address: "127.0.0.1:8200"

Unix sockets are also supported.