<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Aaron Ogle</title>
    <description>The latest articles on Forem by Aaron Ogle (@geekgonecrazy).</description>
    <link>https://forem.com/geekgonecrazy</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F976197%2F707ba245-addb-4a0e-a8a9-d7d42c4a9eb9.jpg</url>
      <title>Forem: Aaron Ogle</title>
      <link>https://forem.com/geekgonecrazy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/geekgonecrazy"/>
    <language>en</language>
    <item>
      <title>Implementing Client SSL Authentication</title>
      <dc:creator>Aaron Ogle</dc:creator>
      <pubDate>Wed, 24 May 2023 13:06:19 +0000</pubDate>
      <link>https://forem.com/rocketchat/how-to-set-up-client-ssl-certificate-authentication-for-rocketchat-836</link>
      <guid>https://forem.com/rocketchat/how-to-set-up-client-ssl-certificate-authentication-for-rocketchat-836</guid>
      <description>&lt;p&gt;Are you looking to add an extra layer of security to access Rocket.Chat? One way to do this is by implementing client SSL certificate authentication. This authentication method requires clients to present a valid SSL certificate to authenticate themselves to the server.&lt;/p&gt;

&lt;p&gt;In this post, we will walk through the steps to set up client SSL certificate authentication using Nginx.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A server running Ubuntu

&lt;ul&gt;
&lt;li&gt;Allow HTTP/HTTPS/ssh in security group&lt;/li&gt;
&lt;li&gt;Create a public IP and associate it.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;A domain&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Domain pointed to the server&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Install Docker
&lt;/h2&gt;

&lt;p&gt;Lets do a quick and easy install of Docker if you haven't already.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -L https://get.docker.com | sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Lets add your user to the docker group so you don't have to use &lt;code&gt;sudo&lt;/code&gt; before every docker command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo usermod -aG docker $USER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally here we'd say logout and back in.. but I don't want to mess with it so I use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;newgrp docker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Install Rocket.Chat
&lt;/h2&gt;

&lt;p&gt;Now that we have Docker installed lets get Rocket.Chat up and running.&lt;/p&gt;

&lt;p&gt;Start off with creating a rocketchat directory and grabbing the docker-compose file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir rocketchat &amp;amp;&amp;amp; cd "$_"
curl -L https://go.rocket.chat/i/docker-compose.yml -O
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next lets fire it up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker compose up -d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If impatient or only came here to install Rocket.Chat you could access on port 3000 if your firewall is open.  But I suspect you came here for seeing how to do client SSL.  So lets carry on!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Install Nginx
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install -y nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Install Certbot
&lt;/h2&gt;

&lt;p&gt;To help us get a valid certificate we are going to use letsencrypt but using a tool called certbot.  This will help us make sure to keep the certificate valid as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo snap install --classic certbot
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now use certbot to generate and plug everything up for letsencrypt and nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo certbot --nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be asked to provide a valid email and the domain set.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Generate Certificate Authority (CA) Certificates
&lt;/h2&gt;

&lt;p&gt;In order to do client SSL Authentication we’re going to need a CA.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate a key for your CA:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -des3 -out ca.key 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generate a certificate for your CA:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -x509 -days 365 -key ca.key -out ca.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Note what you’ve entered for Country, State, Locality, and Organization; you’ll want these to match later when you renew the certificate.&lt;/li&gt;
&lt;li&gt;Do not enter a common name (CN) for the certificate.&lt;/li&gt;
&lt;li&gt;Email can be omitted.&lt;/li&gt;
&lt;li&gt;Note renewing certificate involves running the same command. If you need to remember what options you chose you can run:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -in ca.crt -noout -text
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Move CA cert
&lt;/h3&gt;

&lt;p&gt;To: &lt;code&gt;/etc/ssl/private/client-cert-ca.crt&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Update Nginx config
&lt;/h3&gt;

&lt;p&gt;We need to add CA cert, turn on client ssl authentication and add location block:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ssl_client_certificate /etc/ssl/private/client-cert-ca.crt;
ssl_verify_client optional;

location / {
   if ($ssl_client_verify != SUCCESS) {
     return 403;
   }

    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_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 https;
    proxy_set_header X-Nginx-Proxy true;
    proxy_redirect off;
  }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Issue Client SSL Certificates for users
&lt;/h2&gt;

&lt;p&gt;You can have your users perform most of these steps if you want. But the following are the steps needed to create a certificate to present as client authentication.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generate key for user
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl genrsa -des3 -out user.key 4096
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Generate a CSR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl req -new -key user.key -out user.csr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A number of questions will be asked; answer each one, including the Common Name (CN) and email address. The CSR needs to be sent to the admin (or you if you are doing this for the user).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sign CSR with CA
&lt;/h3&gt;

&lt;p&gt;As the admin, take the CSR given to you or generated by you and sign the CSR and create valid certificate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl x509 -req -days 365 -in user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out user.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;You’ll want to increment the serial number with each signing. Once the certificate expires, a new CSR doesn’t need to be recreated; the same one can be signed, which will create a new certificate tied to that public key.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Return Certificate
&lt;/h3&gt;

&lt;p&gt;The signed certificate (user.crt) can now be sent back to the user along with the CA cert(ca.crt).&lt;/p&gt;

&lt;p&gt;To be able to use in browsers and mobile generate a pkcs #12 using the user cert and key along with the Ca:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openssl pkcs12 -export -out user.pfx -inkey user.key -in user.crt -certfile ca.crt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beware if you intend to install on Mac or iOS, you may need to use an older version of OpenSSL. More info here: &lt;a href="https://developer.apple.com/forums/thread/697030?answerId=710429022#710429022"&gt;https://developer.apple.com/forums/thread/697030?answerId=710429022#710429022&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Access Rocket.Chat using Client SSL Certificate
&lt;/h2&gt;

&lt;p&gt;To access your application with client certificate authentication:&lt;/p&gt;

&lt;h3&gt;
  
  
  On iOS:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add the file on Files app (depending on what you do, iOS will try to install it on the whole OS. e.g. copying from airdrop)&lt;/li&gt;
&lt;li&gt;Go to new server screen and try the server URL just to confirm (an error message should show because you haven't applied the cert yet)&lt;/li&gt;
&lt;li&gt;Tap &lt;code&gt;apply your certificate&lt;/code&gt; on the bottom of the screen and select it from the Files app&lt;/li&gt;
&lt;li&gt;Try again, and it should navigate to the workspace info&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  On Android:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Install the certificate&lt;/li&gt;
&lt;li&gt;Go to new server screen and try the server URL just to confirm (an error message should show because you haven't applied the cert yet)&lt;/li&gt;
&lt;li&gt;Tap &lt;code&gt;apply your certificate&lt;/code&gt;, and the OS should prompt you to select a cert&lt;/li&gt;
&lt;li&gt;Select it&lt;/li&gt;
&lt;li&gt;Tap connect, and it should navigate to the workspace info&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  On Firefox:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open Firefox and click on the three horizontal lines in the top-right corner of the window.&lt;/li&gt;
&lt;li&gt;Select "Preferences".&lt;/li&gt;
&lt;li&gt;In the left-hand menu, click on "Privacy &amp;amp; Security".&lt;/li&gt;
&lt;li&gt;Scroll down to the "Certificates" section and click on "View Certificates".&lt;/li&gt;
&lt;li&gt;Click on the "Your Certificates" tab.&lt;/li&gt;
&lt;li&gt;Click on "Import".&lt;/li&gt;
&lt;li&gt;Browse to the location of your client certificate file and select it.&lt;/li&gt;
&lt;li&gt;Enter the password for the certificate if prompted.&lt;/li&gt;
&lt;li&gt;Click "OK".&lt;/li&gt;
&lt;li&gt;Your client certificate should now be imported and ready to use in Firefox.&lt;/li&gt;
&lt;li&gt;Visit the address and you should be prompted to select the certificate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations! You have successfully set up client SSL certificate authentication for &lt;a href="http://Rocket.Chat"&gt;Rocket.Chat&lt;/a&gt; using Nginx.&lt;/p&gt;

&lt;p&gt;Extremely useful Reference: &lt;a href="https://fardog.io/blog/2017/12/30/client-side-certificate-authentication-with-nginx/"&gt;https://fardog.io/blog/2017/12/30/client-side-certificate-authentication-with-nginx/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
