{ "info": { "author": "Commerce Technologies, LLC", "author_email": "", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "# SSH CA Server\n\nSimple web service to provide SSH key signing.\n\n\n## Purpose\n\nThe SSH CA Server provides a central service for authorizing SSH certificate signing requests. LDAP groups are used to determine a users authorization level. [ca-client](https://github.com/commercehub-oss/ssh-ca-client) can be deployed to workstations for interacting with the SSH CA Server.\n\n\n## SSH Background:\n\nSSH permits the use of signed certificates for authenticating. This simplifies the distribution of SSH keys because only the public key of the CA needs to be deployed to remote hosts. All new users just need their public keys signed by the CA to allow access to any remote host authorizing the CA.\n\nCreate a new CA\n```\nssh-keygen -f MyCA\n```\n\nSign key with CA:\n```\nssh-keygen -V +1h -s MyCA -I username -n principal ~/.ssh/id_rsa.pub\n```\n\n*-V +1h:* Amount of time certificate is valid\n\n*-s MyCA:* Certificate authority used to sign key\n\n*-I username:* Signs the certificate with an identifier that will be logged to auth.log by sshd. This allows signing a certificate with a username and allows for uniquely identifying users (helpful for meeting audit requirments).\n\n*-n principal:* Comma delimited list of principals included in certificate. The signed certificate can only be used for the designated principals. This is helpful when using a single CA for many different teams by using different principals and singing accordingly.\n\n\nTo view the certificate:\n```\nssh-keygen -L -f ~/.ssh/id_rsa-cert.pub\n```\n\nOn remote host update /etc/ssh/sshd_config to include:\nTrustedUserCAKeys /etc/ssh/MyCA.pub\n\nUpload MyCA.pub to /etc/ssh\n\nThis approach will grant access to any principal a cert is signed for. The principal must exist on the remote host or access will be denied.\n\nAlternatively you can allow access per principal by updating the authorized_keys for the specific principal.\n\nOn remote host update ~/.ssh/authorized_keys for the signed principal. Add the public key of the CA preceded with cert-authority\n\nAn example ~/.ssh/authorized_keys:\n```\ncert-authority ssh-rsa AAAA5Adk8.....\n```\n\n\nYou can now login to the remote host using your new certificate\n\nWhile CA signing is a great feature there is an obvious need to protect the CA. The goal of this project is to protect your CA and authorize signing requests using an LDAP directory.\n\n\n## Installation instructions for Ubuntu\n\n1. Install ssh-ca-server\n ```\n pip install ssh-ca-server\n ```\n\n2. Create service account and required directories\n\n ```\n # Service account for running ssh-ca-server\n useradd ssh-ca-server\n\n # Required configuration directory\n mkdir /etc/ssh-ca-server\n chown ssh-ca-server:ssh-ca-server /etc/ssh-ca-server\n\n # Location to store all CA public and private keys\n mkdir /etc/ssh-ca-server/cas\n chown ssh-ca-server:ssh-ca-server /etc/ssh-ca-server/cas\n chmod 600 /etc/ssh-ca-server/cas\n\n # Location for log file\n mkdir /var/log/ssh-ca-server\n chown ssh-ca-server:ssh-ca-server /var/log/ssh-ca-server\n\n ```\n\n\n3. Create configuration under /etc/ssh-ca-server/config.json (See server configuration section for available options)\n\n Example /etc/ssh-ca-server/config.json:\n ```json\n {\n \"ldap_server\": \"ldap-server.mydomain.com\",\n \"ldap_domain\": \"mydomain.com\",\n \"bind_user\": \"bind-user\",\n \"bind_password\": \"bind-password\",\n \"base_dn\": \"DC=mydomain,DC=com\",\n \"group_dn\": \"OU=MyGroups,DC=mydomain,DC=com\",\n \"role_attribute\": \"extensionAttribute1\",\n \"role_description\": \"description\",\n \"ca_attribute\": \"extensionAttribute2\",\n \"principal_attribute\": \"extensionAttribute3\",\n \"ca_path\": \"/etc/ssh-ca-server/cas\",\n \"cas\":\n [\n {\n \"name\": \"production\",\n \"max_duration\": \"24h\"\n },\n {\n \"name\": \"nonproduction\",\n \"max_duration\": \"30d\"\n }\n ]\n }\n ```\n\n4. Install gunicorn\n ```\n apt-get install gunicorn\n ```\n\n5. Create upstart script /etc/init/ssh-ca-server\n ```\n setuid ssh-ca-server\n setgid ssh-ca-server\n\n start on runlevel [2345]\n stop on runlevel [06]\n respawn\n respawn limit 20 5\n\n script\n gunicorn -w 4 ssh_ca_server:app -b 0.0.0.0\n end script\n ```\n\n6. Start service\n ```\n service ssh-ca-server start\n ```\n\n\n\n## Server Configuration\n\nBy default configuration is loaded from /etc/ca-server/config.json. To change this behavior set environment variable SSHCA_CONFIG_PATH to the full path of the configuration file.\n\nParameter | Default |Description\n--------------------|-----------------------|------------------\nldap_server | - |FQDN of LDAP server\nldap_domain | - |Domain name of LDAP server used to derive UPN for bind_user\nbind_user | - |Username of LDAP service account for validating group membership\nbind_password | - |Password for bind_user\nbase_dn | - |Base DN used to find authenticating user\ngroup_dn | - |Base DN used to find groups with role definitions\nrole_attribute | extensionAttribute1 |LDAP attribute that must be set to ca-role to filter groups\nrole_description | description |LDAP attribute that stores the role description\nca_attribute | extensionAttribute2 |LDAP attribute that stores a comma delimited list of allowed CA names\nprincipal_attribute | extensionAttribute3 |LDAP attribute that stores a comma delimited list of allowed principals\nca_path | /etc/ca-server/certs |Location to store CA public and private keys\ncas | - |List of supported CAs (See available CA parameters below)\nlog_level | INFO |Log level (ERROR, INFO, DEBUG)\nlog_file |/var/log/ca-server/server.log |Location of log file\n\n\ncas is a list of certificate authorities supported by the CA server and supports the following parameters:\n\nParameter | Default |Description\n--------------------|-----------------------|------------------\nname | - |Name of CA\nmax_duration | 7d |Expriation for key signing\n\n\n## HTTP Endpoint\n\n#### /\n\nThis endpoint can be used to validate the basic health of the service and returns an empty payload.\n\nAll responses include the following attributes:\n* message: String value of an error response\n* version: The API version\n* payload: The payload returned by a successful request\n* error: Boolean value indicating an error occurred, if True message should always have a user friendly message.\n\nIt returns a JSON body like this:\n```json\n{\n \"message\": \"\", \n \"version\": \"1.01\", \n \"payload\": \"\", \n \"error\": false\n}\n```\n\n#### /list/cas\n\nThis endpoint is hit with a GET and returns a complete list of available certificate authorities.\n\nIt returns a json body like this:\n```json\n{\n \"message\": \"\",\n \"version\": \"1.01\",\n \"payload\": \n [\n {\n \"max_duration\": \"24h\",\n \"name\": \"production\"\n }, \n {\n \"max_duration\": \"30d\",\n \"name\": \"nonproduction\"\n } \n ], \n \"error\": false\n}\n```\n#### /list/roles\n\nThis endpoint is hit with a GET and returns a complete list of roles for a given user. Use the **?user=** query parameter to filter the role list to a given user.\n\nIt returns a json body like this:\n```json\n{\n \"message\": \"\",\n \"version\": \"1.01\",\n \"payload\": \n [\n {\n \"allowed_principals\": \"admin\",\n \"allowed_cas\": \"nonproduction,production\",\n \"ldap_group\": \"ssh-admin-group\",\n \"description\": \"Super Admin Role\",\n \"name\": \"ssh-admin-group\"\n }\n ],\n \"error\": false\n}\n```\n#### /get/\\\n\nThis endpoint is hit with a GET and returns the certificate authority public key for the ca_name provided in the path.\n\n```json\n{\n \"message\": \"\",\n \"version\": \"1.01\",\n \"payload\": \"94ABaQZ....\",\n \"error\": false\n}\n```\n#### /sign\n\nThis endpoint is hit with a POST and returns a signed certificate. The desired certificate authority is provided using the **?ca=** query parameter.\n\nBasic HTTP Authentication is used and requires the users LDAP username and password.\n\nThe **file** POST field should contain the users public key as multipart/form-data\n\n\nExample request:\n```\ncurl -u username -F file=@my_ssh_key.pub https://ca-server.mydomain.com/sign?ca=nonproduction\n```\n\nIt returns a json body like this:\n```json\n{\n \"message\": \"\",\n \"version\": \"1.01\",\n \"payload\": \"ssh-rsa-cert-v01@openssh.com AC1Et...\",\n \"error\": false\n}\n```\n\nThe returned signed SSH certificate will include all authorized principals plus the requesters username. The Key ID value is what will appears in the authlog of the remote node.\n\nThe below examples shows the result of a successfully signed SSH certificate:\n\n```\n$ ssh-keygen -L -f ~/.ssh/nonproduction_rsa-cert.pub \n\n~/.ssh/nonproduction_rsa-cert.pub:\n Type: ssh-rsa-cert-v01@openssh.com user certificate\n Public key: RSA-CERT 3c:3d:47:...\n Signing CA: RSA 2b:2a:23:...\n Key ID: \"username\"\n Serial: 12515602213705584981\n Valid: from 2017-02-06T17:03:00 to 2017-03-08T17:04:44\n Principals: \n username\n admin\n Critical Options: (none)\n Extensions: \n permit-X11-forwarding\n permit-agent-forwarding\n permit-port-forwarding\n permit-pty\n permit-user-rc\n```\n\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/commercehub-oss/ssh-ca-server", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "ssh-ca-server", "package_url": "https://pypi.org/project/ssh-ca-server/", "platform": "", "project_url": "https://pypi.org/project/ssh-ca-server/", "project_urls": { "Homepage": "https://github.com/commercehub-oss/ssh-ca-server" }, "release_url": "https://pypi.org/project/ssh-ca-server/0.1.3/", "requires_dist": [ "ldap3 (>=2.2.1)", "flask (>=0.11.1)" ], "requires_python": "", "summary": "SSH CA Server", "version": "0.1.3" }, "last_serial": 3869009, "releases": { "0.1.2": [ { "comment_text": "", "digests": { "md5": "cc77ad16fc1c739953708b2c169b9264", "sha256": "6d269d5bfce21732bf8855dd4cd5b5dd49413ba17ab27b3b1cefb393b613fb9c" }, "downloads": -1, "filename": "ssh_ca_server-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "cc77ad16fc1c739953708b2c169b9264", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 18196, "upload_time": "2017-03-01T18:54:01", "url": "https://files.pythonhosted.org/packages/24/95/c4ec9ae4261c87f760fad089a3aeb18780c168546fc8ffc2f07c05c0ff65/ssh_ca_server-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "c9b684935148958a6f599929297fe84f", "sha256": "be7cdade368503d32a42d3e387be7826a92755b5862983ee419ee4fb03d770c9" }, "downloads": -1, "filename": "ssh-ca-server-0.1.2.tar.gz", "has_sig": false, "md5_digest": "c9b684935148958a6f599929297fe84f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12955, "upload_time": "2017-03-01T18:44:51", "url": "https://files.pythonhosted.org/packages/0b/6c/bbd309767e42f388c661ec59e7472bc8178223c0cce39dbd65ed86020a3a/ssh-ca-server-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "41fd7f9387300cf100191df415bb1cd5", "sha256": "9ad10d28115a58ea7694e86a067dfbcb78466e6b46359df34ad8fb9488c4e8ec" }, "downloads": -1, "filename": "ssh_ca_server-0.1.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "41fd7f9387300cf100191df415bb1cd5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 14298, "upload_time": "2018-05-16T14:48:23", "url": "https://files.pythonhosted.org/packages/a5/ca/a014b6e6ad2b77aac52c3c5a9e8da70a2a207701266e58eb71025ce9cd86/ssh_ca_server-0.1.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9ff8c4b4ce4a190dc284bcc9d298d947", "sha256": "c40697443e8add669bbd09fc5e1ce83c42086c02ec9f59147d9f831c21c27291" }, "downloads": -1, "filename": "ssh-ca-server-0.1.3.tar.gz", "has_sig": false, "md5_digest": "9ff8c4b4ce4a190dc284bcc9d298d947", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10694, "upload_time": "2018-05-16T14:48:24", "url": "https://files.pythonhosted.org/packages/41/6a/57b4206ef92e13518c83ebcbe4a0244329c4171934985005441edd5a0681/ssh-ca-server-0.1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "41fd7f9387300cf100191df415bb1cd5", "sha256": "9ad10d28115a58ea7694e86a067dfbcb78466e6b46359df34ad8fb9488c4e8ec" }, "downloads": -1, "filename": "ssh_ca_server-0.1.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "41fd7f9387300cf100191df415bb1cd5", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 14298, "upload_time": "2018-05-16T14:48:23", "url": "https://files.pythonhosted.org/packages/a5/ca/a014b6e6ad2b77aac52c3c5a9e8da70a2a207701266e58eb71025ce9cd86/ssh_ca_server-0.1.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "9ff8c4b4ce4a190dc284bcc9d298d947", "sha256": "c40697443e8add669bbd09fc5e1ce83c42086c02ec9f59147d9f831c21c27291" }, "downloads": -1, "filename": "ssh-ca-server-0.1.3.tar.gz", "has_sig": false, "md5_digest": "9ff8c4b4ce4a190dc284bcc9d298d947", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10694, "upload_time": "2018-05-16T14:48:24", "url": "https://files.pythonhosted.org/packages/41/6a/57b4206ef92e13518c83ebcbe4a0244329c4171934985005441edd5a0681/ssh-ca-server-0.1.3.tar.gz" } ] }