Self-signed Certs, Jenkins, and NGINX.
Self-signed certs is something I have written about, mostly on how to set it up. The original need for self-signed certs was that we wanted to securely lock-down internet-facing applications. Self-signed certificate authority worked because I could secure external access by putting applications behind NGINX and make it so that you had to have a SSL cert signed by the same authority. We didn’t have money for a REAL VeriSign cert and this was a perfect solution for the small tech-startup.
Listen, OpenLDAP is cool but it creates a level of administrative work that, in my case, I did not have time for. To be honest, it’s easier to make one cert per person (in fact, I scripted it), and for the Dev and Business-side person (e.g. BizDev, Product, TAM teams) it’s just easier to let them work without managing passwords, resetting, etc. There is a cost-benefit analysis that needs to be thought out. Self-signed certs is a great medium to manage security with ease-of-access for those who have been granted access.
Anyways, so I ran into a problem by protecting our Jenkins box. We use Jenkins for everything, and while it’s ‘secure’ with local usernames and passwords, it’s just not good enough. So, I put Jenkins behind NGINX and our certs into a directory:
sudo mkdir /etc/nginx/ssl
I will paste my conf file and explain the parts:
upstream jenkins { server 127.0.0.1:8080 fail_timeout=0; } server { listen 80; server_name jenkins.company.com; location / { return 301 https://$server_name$request_uri; } location /github-webhook/ { proxy_pass http://jenkins; } } server { listen 443; server_name jenkins.company.com; root /var/lib/jenkins/jenkins.war; access_log /var/log/nginx/jenkins.access_log main; error_log /var/log/nginx/jenkins.error_log info; ssl on; ssl_certificate /etc/nginx/ssl/jenkins.crt; ssl_certificate_key /etc/nginx/ssl/jenkins.key; ssl_client_certificate /etc/nginx/ssl/root-chain.crt; ssl_verify_client on; ssl_verify_depth 5; location / { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_redirect http:// https://; proxy_pass http://jenkins; } }
Here is what this config does (for those who don't know) and why it does it:
First, we put the jenkins box behind NGINX and from the outside block port 8080. Then, we rewrite all top-level access (http://jenkins.company.com) to https:// as a 301 permanent route. But, we allow access to jenkins.company.com/github-hook/ because, well, it would deny all Jenkins jobs to access Github to run after a commit has been push. I made this mistake, as I wasn't thinking through, and this is how I was able to maintain that feature.
Under server, we just have it run on 443. Point servername and root and access log to whatever your jenkins and naming conventions are.
Under ssl Cert, we map the crt and key files to the ../ssl directory and we set ssl_verify_client on as that is what checks the validation and the depth to be 5. For self-signed certs, you have to make sure NGINX checks the root-chain cert for Immediate and Root Authority by adding depth on here.
The rest? ehh some Proxy stuff.
I decided to post this up as I found a lot of people ASKING how to do this but no one actually posting an answer. So, hope this helps!