{ "info": { "author": "Mark Peek", "author_email": "mark@peek.org", "bugtrack_url": null, "classifiers": [], "description": "Certificate based SSH\n=====================\n\n\"*One key to rule them all, One key to find them, \nOne key to bring them all and in the cloud bind them*\"\n\nCertificate based SSH allows us to launch a server at time X and grant\nSSH access to that server later at time X + Y without touching the\nauthorized keys file. Further it allows us to generate certificates that\nexpire at some predefined time meaning that users can be granted access\nto a system for a short period of time.\n\nThe primary use case is:\n\n Jane the Engineer needs shell access to a machine running in\n production in order to help debug a problem. In general Jane does not\n need access to these machines and it is expected that she only needs\n access for a few hours at which point her access should automatically\n be revoked.\n\nA second use case is around host keys:\n\n A server is launched into the cloud by an adminstrator and made\n available to other users over SSH. The first time a user connects to\n that machine she is prompted to inspect the host key fingerprint and\n type either \"yes\" or \"no\". Most users blindly type yes. By signing a\n host key and generating a certificate users can blindly accept any\n server that presents a valid certificate as trustworthy and never be\n prompted to blindly type \"yes\" again.\n\nQuick start\n===========\n\nUser keys\n---------\n\nGenerate a certificate authority (yep, this is exactly like making an ordinary private key):\n\n`ssh-keygen -f ~/.ssh/ssh_ca_production -b 4096`\n\nPut the CA's public key on the remote host of your choosing into\n`authorized_keys`, but prefix it with cert-authority:\n\n`echo \"cert-authority $(cat ssh_ca_production.pub)\" >> ~/.ssh/authorized_keys`\n\nGenerate a certificate using the utility in this github repo:\n\n`sign_key -e production -u user@example.com -p ~/.ssh/id_rsa.pub -t +1d`\n\nInstall the certificate using the other utility in this github repo:\n\n`get_cert ''`\n\nSSH like normal.\n\nHost keys\n---------\n\nFirst create a CA using ssh-keygen as described in the previous section.\nThen use the `sign_host_key` script included in this distribution.\n\nThis script will SSH out to the remote server and:\n\n - Copy back the host's public key\n - Sign it (it will ask you for the passphrase to your CA\n - Copy it back to the host\n - Restart sshd\n\nOnce the cert is in place you need to have your client computers told to\ntrust the CA. Take the public portion of your CA and add it into your\n`authorized_keys` file according to this format:\n\n `@cert-authority *.domain ssh-rsa ...`\n\nThe `*.domain` is intended to be the domain you're signing keys for. If\nyou were working with a CA that only signed host keys for veznat.com you\ncould enter `*.veznat.com`. If you sign keys for all sorts of domains\nyou can enter a `*` here without any qualification, however, you should\nunderstand what this means in the context of a compromised CA before\ndoing so.\n\nUsage\n=====\n\nIf you're running this command you must already have access to the\nroot-ca certificate. Despite being really well encrypted this file is\nkept secret and you'll need to pass the \"I require access to this file\"\ntest in order to get a copy.\n\nOnce you've got the CA file you can use the script here. Usage is found\nwith the --help option (not documented here to avoid duplicating the\ncode).\n\nWhen running this script a number of things happen:\n\n- An entry is made in an audit log in S3 to document that the key was\n made, for who, by who and how long the key is valid.\n- A serial number is incremented and stored in S3. This makes revoking\n certificates later a lot easier.\n- The generated certificate is stored in S3 and a temporary (2 hour) URL\n is generated for the user to download the certificate\n\nIf a user's public key is given as an argument to the script it is also\nuploaded to S3 effectively caching it for the next time the script is\nused for that user. Without a public key filename being passed in the\nscript attempts to load the key from S3.\n\nHow it works\n============\n\nThe CA owner creates a new certificate authority keypair. This is just a\ngeneric 4096 bit RSA keypair that could be used for regular old SSH\nauthentication. However, we will protect the generated private key with our\nlives (and a really great 2-factor passphrase).\n\n```\ncd ~/.ssh\nssh-keygen -f ssh_ca_production -b 4096\n```\n\nWe take the public key portion of that key pair and add it to the\nauthorized_keys file of machines we want to login to. However, unlike\nnormal, the line in authorized_keys is prefixed with `cert-authority`.\n\n```\necho \"cert-authority $(cat ssh_ca_production.pub)\" >> ~/.ssh/authorized_keys\n```\n\nAt this point the server is ready to accept authentication using any\nprivate key that can also present a certifcate that was signed using the\nroot-ca's private key.\n\nWe now get the users public key and sign it with the CA key. The below command\nspecifies the S3 bucket (-b), S3 region (-r), environment (-e), user name (-u),\nusers public key file (-p) and how long before the key expires (-t).\n\n```\nsign_key -b my-s3-bucket -r us-west-1 -e production -u user@example.com -p user-example.pub -t +1d\n```\n\nThe output of this is an S3 URL that you give to the user. The user will now\nrun `get_key` to download the generated certificate from S3 and install it\ninto their ~/.ssh directory. Note the quotes around the download link.\n\n```\nget_key 'https://my-s3-bucket.s3-us-west-1.amazonaws.com/certs/user%40example.com-cert.pub?Signature=neidfJ5bZ5YbmAi2ouJVZzZzZz%3D&Expires=1391025703&AWSAccessKeyId=AKIAJ7HFYKZIVF3ZZZZ'\n```\n\nThe user can now log into the remote system using these new keys.\n\n`get_key` is nothing particularly fancy. It simply downloads the\ncertificate and attempts to find the corresponding private key for the\nuser and places the cert next to it. OpenSSH requires that the cert be\nnamed similarly to the private key. For example, if your private key is\nnamed `id_rsa` the cert must be in a file named `id_rsa-cert.pub`. It\nreally does simply append `-cert.pub` to the filename.\n\nTroubleshooting\n===============\n\nTypical problems include not having the certificate added to the running\nssh-agent. You can list certificates and keys with the ssh-add command:\n`ssh-add -l`. You should see the certificate listed:\n\n```\n2048 66:b5:be:e5:7e:09:3f:98:97:36:9b:64:ec:ea:3a:fe .ssh/id_rsa (RSA)\n2048 66:b5:be:e5:7e:09:3f:98:97:36:9b:64:ec:ea:3a:fe .ssh/id_rsa (RSA-CERT)\n```\nIf you don't see it listed simply run `ssh-add ` again.\n\nIncompatibilities and Annoyances\n================================\n\nOpenSSH - One cert per key\n--------------------------\nYou can only have one SSH cert loaded per private key at any one time\n(The SSH agent works by loading your private key file `keyfile` and then\nlooks for a certificate in a file named `keyfile`-cert.pub.\n\nIf, like us, you have multiple environments that you want to access in a\nshort time window the best workaround is to have multiple private keys.\nThis project has builtin support for per-environment keys. To take\nadvantage of this upload your private key, using the sign_key command,\nbut specifying your username in the format\n`user?environment=THE-ENVIRONMENT`. For example, I might use\n`bob@veznat.com?environment=stage` for staging and\n`bob@veznat.com?environment=prod` for production. The public keys that\nare being uploaded her must correspond to separate private keys\notherwise when get_cert runs it will not be able to reliably figure out\nwhere to put the downloaded cert.\n\nIf you use this multiple environment naming trick in your username you\ndo not need to specify anything special when running sign_key in the\nfuture. Sign key searches for your public key first by doing an\nenvironment specific lookup and second looking for a generic one.\n\nVagrant\n-------\nWhen a user has one of these cert keys in their keychain\n[vagrant](http://www.vagrantup.com/) will hang in bringing up a new box.\nThis is due to an incompatibility in the Ruby net-ssh package included in\nvagrant. This is being tracked in this\n[net-ssh issue](https://github.com/net-ssh/net-ssh/pull/142).\n\nOS X\n----\nOS X's magic ssh-add (the one where it prompts you in the GUI of OS X\nfor your passphrase) does not properly add the certificate. In order to\nutilize certificates you'll want to `ssh-add .ssh/my_private_key` at a\nterminal in order for the certificate to properly be added to your\nssh-agent.\n\n\n", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/cloudtools/ssh-ca", "keywords": null, "license": "New BSD license", "maintainer": null, "maintainer_email": null, "name": "ssh-ca", "package_url": "https://pypi.org/project/ssh-ca/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/ssh-ca/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/cloudtools/ssh-ca" }, "release_url": "https://pypi.org/project/ssh-ca/0.3.2/", "requires_dist": null, "requires_python": null, "summary": "SSH CA utilities", "version": "0.3.2" }, "last_serial": 1470741, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "1884e07fa6ec27a5de0042af49676a3f", "sha256": "a60150297b67575ac097d0e19b6f4b75e6c90aa268c98dca8253650a84e0844d" }, "downloads": -1, "filename": "ssh-ca-0.1.0.tar.gz", "has_sig": false, "md5_digest": "1884e07fa6ec27a5de0042af49676a3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7686, "upload_time": "2014-02-04T16:13:46", "url": "https://files.pythonhosted.org/packages/d1/06/0b30cf9cfb115a73a1abeba9ca88061d83868a2e0084cfa07dfc89cbe4ee/ssh-ca-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "10f77100c5b66c4dd1529b0ea55dd8b3", "sha256": "c3605b08d6898f656044ed6bc71d3ef65a18d401c7ffbddf270b740f08128f9d" }, "downloads": -1, "filename": "ssh-ca-0.2.0.tar.gz", "has_sig": false, "md5_digest": "10f77100c5b66c4dd1529b0ea55dd8b3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8367, "upload_time": "2014-02-25T18:33:07", "url": "https://files.pythonhosted.org/packages/43/62/bd61ad49324abb2fa6e87b18c4c10e4b59ab2d99e4204b15fe80a9c33207/ssh-ca-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "83e3008808173cc49874e5b61bc29b03", "sha256": "41f3935f7b26a9e1d3be9cf4961bc38dc49f67012f5fd143f4e4cfcc390a651c" }, "downloads": -1, "filename": "ssh-ca-0.3.0.tar.gz", "has_sig": false, "md5_digest": "83e3008808173cc49874e5b61bc29b03", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10284, "upload_time": "2014-04-07T19:51:05", "url": "https://files.pythonhosted.org/packages/46/6a/a8d978c082f71bf43c5201769f4b2ae86bfa46dc0b3d0e1dcb92ee892a82/ssh-ca-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "f54648ec8be65dcda4b22cb3030488cf", "sha256": "075e5744a7f7f01ef649f28066801499aba176e96779b8ea18f0cf3f134691c5" }, "downloads": -1, "filename": "ssh-ca-0.3.1.tar.gz", "has_sig": true, "md5_digest": "f54648ec8be65dcda4b22cb3030488cf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10332, "upload_time": "2014-04-17T18:26:17", "url": "https://files.pythonhosted.org/packages/9a/db/fd81cc26673893c77c4bbb457ac30d9b628eaf269afda8604dda001a1c40/ssh-ca-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "012518fe141d3631e1caa2aece190dac", "sha256": "ea1e4f30fd392f9d185217062d3ed5af70926f706a8884263d84040732e5534c" }, "downloads": -1, "filename": "ssh-ca-0.3.2.tar.gz", "has_sig": true, "md5_digest": "012518fe141d3631e1caa2aece190dac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13121, "upload_time": "2015-03-20T21:31:25", "url": "https://files.pythonhosted.org/packages/46/98/4e5673956d0b295a2d9dafab7e5b3aa0c684b7a89451b73c3efa59547119/ssh-ca-0.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "012518fe141d3631e1caa2aece190dac", "sha256": "ea1e4f30fd392f9d185217062d3ed5af70926f706a8884263d84040732e5534c" }, "downloads": -1, "filename": "ssh-ca-0.3.2.tar.gz", "has_sig": true, "md5_digest": "012518fe141d3631e1caa2aece190dac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13121, "upload_time": "2015-03-20T21:31:25", "url": "https://files.pythonhosted.org/packages/46/98/4e5673956d0b295a2d9dafab7e5b3aa0c684b7a89451b73c3efa59547119/ssh-ca-0.3.2.tar.gz" } ] }