{"id":441,"date":"2018-10-16T23:41:30","date_gmt":"2018-10-16T23:41:30","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw93\/?p=441"},"modified":"2018-10-17T09:26:38","modified_gmt":"2018-10-17T09:26:38","slug":"automated-certificate-provisioning-in-kubernetes-using-kube-lego-jetstack-blog","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/automated-certificate-provisioning-in-kubernetes-using-kube-lego-jetstack-blog\/","title":{"rendered":"Automated certificate provisioning in Kubernetes using kube-lego &#8211; Jetstack Blog"},"content":{"rendered":"<p>By <a target=\"\">Christian Simon<\/a><\/p>\n<p>In this blog post, we are pleased to introduce <a href=\"https:\/\/github.com\/jetstack\/kube-lego\">Kube-Lego<\/a>, an open source tool for automated Let\u2019s Encrypt TLS-enabled web services running in <a href=\"https:\/\/kubernetes.io\/\">Kubernetes<\/a>.<\/p>\n<p>TLS has become increasingly important for production deployment of web services. This has been driven by revelations of surveillance post-Snowden, as well as the fact that Google now <a href=\"https:\/\/security.googleblog.com\/2015\/12\/indexing-https-pages-by-default.html\">favours secure HTTPS sites<\/a> in search result rankings.<\/p>\n<p>An important step towards increased adoption of TLS has been the availability of<br \/>\n<a href=\"https:\/\/letsencrypt.org\/\">Let\u2019s Encrypt<\/a>. It provides an easy, free-of-charge way to obtain certificates. Certificates are limited to a 90-day lifetime and so the free certificate authority (CA) encourages full automation for ease-of-use. At the time of writing, Let\u2019s Encrypt has approaching <a href=\"https:\/\/letsencrypt.org\/stats\/\">3.5 million unexpired certificates<\/a> so adoption has certainly been strong.<\/p>\n<p>Kube-Lego automates the process in Kubernetes by watching ingress resources and automatically requesting missing or expired TLS certificates from Let\u2019s Encrypt.<\/p>\n<p>In order to automate the process of verification and certificate issuance for<br \/>\nLet\u2019s Encrypt\u2019s CA, the ACME (Automated Certificate Management Environment)<br \/>\nprotocol is used. It specifies an API that can be integrated into many products<br \/>\nthat require publicly trusted certificates.<\/p>\n<p>To interact with the CA\u2019s ACME server, clients are required to<br \/>\nauthenticate with a private\/public key pair (account). This helps to identify<br \/>\nthe user later for actions like extension or revocation of certificates. Let\u2019s<br \/>\nEncrypt supports only domain validation and requires you to specify every<br \/>\nvalid domain individually, so while a certificate can be valid for multiple<br \/>\nhostnames using <a href=\"https:\/\/en.wikipedia.org\/wiki\/Subject_Alternative_Name\">SAN<\/a>, there is currently no support for wildcard certificates.<\/p>\n<h2>Validation methods<\/h2>\n<p>Let\u2019s Encrypt allows you to prove the validity of a certificate request<br \/>\nwith four methods. They all use a so-called \u2018key auth challenge response\u2019, which<br \/>\nis derived from the account\u2019s key pair.<\/p>\n<ul>\n<li>Simple HTTP: The CA connects to the specified URL<br \/>\n(http:\/\/$\/.well-known\/acme-challenge\/$) to verify the<br \/>\nauthenticity of a certificate request. The response of the HTTP server has to<br \/>\ncontain the key auth.<\/li>\n<li>TLS-SNI: With this method, the CA connects to the requested domain<br \/>\nname via HTTPS and selects the verification hostname<br \/>\n$.$.acme.invalid via <a href=\"https:\/\/en.wikipedia.org\/wiki\/Server_Name_Indication\">SNI<\/a>. The returned certificate<br \/>\nis not verified, it only has to contain the verification hostname.<\/li>\n<li>DNS: A TXT-record _acme-challenge.$ has to be published,<br \/>\nto verify the authenticity of your request via the DNS method. The content of<br \/>\nthis records has to include the key auth.<\/li>\n<li>Proof of Possession of a Prior Key: If you already have a valid<br \/>\ncertificate for the domain name you want to request another certificate. You can then use this method to get validated.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/github.com\/jetstack\/kube-lego\">Kube-Lego<\/a> brings fully automated TLS management to a Kubernetes cluster.<br \/>\nTo achieve this it interfaces with the Kubernetes API on one side and an ACME<br \/>\nenabled CA on the other. Kube-Lego is written in Go and uses <a href=\"https:\/\/github.com\/xenolf\">xenolf<\/a>\u2019s<br \/>\nACME client implementation <a href=\"https:\/\/github.com\/xenolf\/lego\">Lego<\/a> for communicating with Let\u2019s<br \/>\nEncrypt (this explains the project name). Currently, the only<br \/>\nimplemented validation method is Simple HTTP<\/p>\n<h2>Pre-requisites<\/h2>\n<p>To use Kube-Lego you need a working Kubernetes cluster. The minimum<br \/>\nversion supported is 1.2, as this includes TLS support for ingress resources. There are plenty of ways getting Kubernetes<br \/>\nbootstrapped; for instance, take a look at this <a href=\"http:\/\/kubernetes.io\/docs\/getting-started-guides\/\">Getting Started<br \/>\nGuide<\/a> from the Kubernetes<br \/>\nproject.<\/p>\n<p>Note: Jetstack will also soon open source its cluster provisioner tool.<\/p>\n<p>Another requirement for using Kube-Lego is a supported<br \/>\ningress controller. The only supported controller at the moment is the<br \/>\n<a href=\"https:\/\/github.com\/kubernetes\/contrib\/tree\/master\/ingress\/controllers\/nginx\">nginx-ingress-controller<\/a> from Kubernetes\u2019 contrib project. The current<br \/>\nrelease of the upstream controller needs a simple modification to fully support<br \/>\nKube-Lego. There is already a <a href=\"https:\/\/github.com\/kubernetes\/contrib\/pull\/850\">pull<br \/>\nrequest<\/a> filed to integrate<br \/>\nthis change into the next upstream release. Meanwhile you can use a modified<br \/>\nbuild of the<br \/>\n<a href=\"https:\/\/hub.docker.com\/r\/simonswine\/nginx-ingress-controller\/\">nginx-ingress-controller<\/a>.<\/p>\n<p>Before you can use Kube-Lego you have to make the nginx-ingress-controller pods<br \/>\naccessible publicly. This usually happens with a service resource of the type<br \/>\n<a href=\"http:\/\/kubernetes.io\/docs\/user-guide\/load-balancer\/\">LoadBalancer<\/a>.<br \/>\nDepending on the environment the cluster is running, this will create an<br \/>\nELB\/Forwarding Rule and you can point the domains you wish to use to that entry<br \/>\npoint into your cluster.<\/p>\n<h2>Validity check<\/h2>\n<p>After starting up, Kube-Lego looks at all ingress objects in all namespaces in the Kubernetes cluster. If the ingress is annotated with kubernetes.io\/tls-acme: &#8220;true&#8221;, Kube-Lego will check the TLS configuration and make sure that the specified secret:<\/p>\n<ul>\n<li>Exists and contains a valid private\/public key pair;<\/li>\n<li>The certificate is not expired;<\/li>\n<li>The certificate covers all domain names specified in the ingress config.<\/li>\n<\/ul>\n<p>Let\u2019s take a look at the following example of an ingress resource:<\/p>\n<p>apiVersion: extensions\/v1beta1<br \/>\nkind: Ingress<br \/>\nmetadata:<br \/>\nname: hello-world<br \/>\nannotations:<br \/>\n# enable kube-lego for this ingress<br \/>\nkubernetes.io\/tls-acme: &#8220;true&#8221;<br \/>\nspec:<br \/>\n# this enables tls for the specified domain names<br \/>\ntls:<br \/>\n&#8211; hosts:<br \/>\n&#8211; demo.kube-lego.jetstack.net<br \/>\nsecretName: hello-world-tls<br \/>\nrules:<br \/>\n&#8211; host: demo.kube-lego.jetstack.net<br \/>\nhttp:<br \/>\npaths:<br \/>\n&#8211; path: \/<br \/>\nbackend:<br \/>\nserviceName: hello-world<br \/>\nservicePort: 80<\/p>\n<h2>Certificate Request<\/h2>\n<p>Let\u2019s assume we haven\u2019t run Kube-Lego before, so neither the certificate nor<br \/>\nthe user account exists. The Kube-Lego validity check comes to the conclusion<br \/>\nthat it needs to request a certificate for the domain<br \/>\n<em>demo.kube-lego.jetstack.net<\/em>.<\/p>\n<p>Before requesting the certificate, Kube-Lego sets up the challenge endpoint<br \/>\n(\/.well-known\/acme-challenge\/) in a separate ingress resource named<br \/>\n<em>kube-lego<\/em>. This resource is meant to only be used by Kube-Lego and the endpoint<br \/>\nwill be reachable over the public URL. This<br \/>\nmakes sure that actual traffic can reach the cluster and we do not<br \/>\nunnecessarily try to validate with Let\u2019s Encrypt.<\/p>\n<p>Kube-Lego looks for the secret <em>kube-lego-account<\/em>; if it does not<br \/>\nexist, Kube-Lego creates it by registering with Let\u2019s Encrypt. Finally, the<br \/>\nrequest for the certificate can be made with Let\u2019s Encrypt. Kube-Lego<br \/>\nresponds to the HTTP validation via the challenge endpoint and then finally<br \/>\nreceives the certificate, which is stored into the secret <em>hello-world-tls<\/em>.<\/p>\n<p>The following diagram illustrates this flow and the various interfaces.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetstack.io\/blog\/kube-lego\/architecture.gif\" alt=\"Kube-Lego process\" \/><\/p>\n<p>Kube-Lego process<\/p>\n<h2>Demo<\/h2>\n<p>If you want to run these examples, you can always find the latest<br \/>\nversion on <a href=\"https:\/\/github.com\/jetstack\/kube-lego\/tree\/master\/examples\">GitHub<\/a>.<\/p>\n<p>A short demo was also part of the Kubernetes Community Hangout on June 2nd. See the recording <a href=\"https:\/\/www.youtube.com\/watch?v=M3b8Wzqi56A\">here<\/a>.<\/p>\n<p>A screencast of an extended demo can be found here:<\/p>\n<p>Screencast<\/p>\n<h2>Future work<\/h2>\n<p>This is a very early project and does not cover all common use cases.<br \/>\nFeel free to report any issues and enhancements via <a href=\"https:\/\/github.com\/jetstack\/kube-lego\/issues\">GitHub<br \/>\nIssues<\/a>. You can also see some<br \/>\nalready identified issues there.<\/p>\n<p><a href=\"https:\/\/blog.jetstack.io\/blog\/kube-lego\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Christian Simon In this blog post, we are pleased to introduce Kube-Lego, an open source tool for automated Let\u2019s Encrypt TLS-enabled web services running in Kubernetes. TLS has become increasingly important for production deployment of web services. This has been driven by revelations of surveillance post-Snowden, as well as the fact that Google now &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw93\/index.php\/2018\/10\/16\/automated-certificate-provisioning-in-kubernetes-using-kube-lego-jetstack-blog\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Automated certificate provisioning in Kubernetes using kube-lego &#8211; Jetstack Blog&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":["post-441","post","type-post","status-publish","format-standard","hentry","category-kubernetes"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/441","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/comments?post=441"}],"version-history":[{"count":1,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/441\/revisions"}],"predecessor-version":[{"id":551,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/posts\/441\/revisions\/551"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/media?parent=441"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/categories?post=441"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw93\/index.php\/wp-json\/wp\/v2\/tags?post=441"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}