Generate SSL certificates for free on shared hosting providers

Generate SSL certificates for free with Let's encrypt on shared hosting providers such as Namecheap

How to Generate free SSL Certificates on Shared Hosting Providers using Scala 3.3

Introduction

SSL stands for Secure Sockets Layer, a protocol that encrypts the data exchanged between a web server and a web browser. This ensures that your website visitors can securely access your content and submit sensitive information without worrying about hackers or eavesdroppers. SSL certificates are digital files that contain information about your website’s identity and the public key that is used to encrypt the data. You need to install an SSL certificate on your web server and configure your website to use HTTPS instead of HTTP. HTTPS is the secure version of HTTP that indicates that your website is using SSL.

There are many ways to obtain an SSL certificate for your website, but one of the easiest and cheapest ways is to use Let’s Encrypt, a free, open, and automated certificate authority that provides domain-validated certificates. Let’s Encrypt certificates are trusted by most browsers and have a validity of 90 days, which can be renewed automatically. To use Let’s Encrypt, you need to prove that you own the domain name that you want to secure. There are different methods to do this, such as using a DNS record, a file on your web server, or an email address associated with your domain.

In this article, I will show you how to use Scala 3.3, a modern and powerful programming language, to install, download, and generate SSL certificates for free with Let’s Encrypt on shared hosting providers such as Namecheap. I will assume that you have access to your web server via SSH and that you have installed Scala 3.3 and sbt, a build tool for Scala projects, on your local machine. I will also assume that you have a domain name registered with Namecheap and that you have pointed it to your web server’s IP address.

Prerequisites

Before you start, you need to have the following:

  • A domain name registered with Namecheap or other hosting and pointed to your web server’s IP address. You can use Namecheap’s DNS management tool to do this. For example, if your domain name is api.example.com and your web server’s IP address is 123.456.789.0, you need to create two A records: one for api.example.com and one for www.api.example.com, both pointing to 123.456.789.0.

  • Access to your web server via SSH. You can use a terminal application such as PuTTY or Terminal to connect to your web server using your username and password. For example, if your username is username and your web server’s IP address is 123.456.789.0, you can use the following command to connect:

    ssh username@123.456.789.0
    
  • Scala 3.3 and sbt installed on your local machine. You can download and install them from their official websites: Scala and sbt (I'll create another post with the best way to setup your computer with Scala). You can check if they are installed correctly by running the following commands in your terminal:

    scala -version
    sbt -version
    
  • A Scala project with scalassh as a dependency. Scalassh is a library that simplifies SSH operations in Scala. You can create a new Scala project using sbt or use an existing one. To add scalassh as a dependency, you need to edit the build.sbt file in your project directory and add the following line:

     libraryDependencies += "com.decodified" %% "scala-ssh" % "0.10.0"
    
  • A configuration file called .getssl.cfg in your home directory. This file contains the SSH credentials and other settings for your web server. You can create this file using a text editor such as Notepad or Vim. The file should have the following format:

      namecheap {
        host = 123.456.789.0
        user = username
        password = password
        port = 22
      }
    

You need to replace the values with your own web server’s IP address, username, password, and port number. You can also use other authentication methods such as public key or agent, as described in the scalassh documentation.

Step 1: Download and Install acme.sh on Your Web Server

Acme.sh is a shell script that interacts with Let’s Encrypt and handles the certificate issuance and renewal process. You need to download and install acme.sh on your web server using SSH. To do this, you can follow these steps:

  1. Connect to your web server via SSH using your terminal application.

  2. Run the following command to download acme.sh from GitHub:

    curl https://get.acme.sh | sh
    
  3. Run the following command to check if acme.sh is installed correctly:

    acme.sh --version
    

    You should see something like this:

    https://github.com/acmesh-official/acme.sh
    v3.0.1
    
  4. Run the following command to create an alias for acme.sh in your home directory:

    alias acme.sh=~/.acme.sh/acme.sh
    

This will make it easier to run acme.sh commands in the future.

You have successfully downloaded and installed acme.sh on your web server. You can now use it to generate SSL certificates for your domain name.

Step 2: Generate SSL Certificates for Your Domain Name Using acme.sh

To generate SSL certificates for your domain name using acme.sh, you need to use the web root method, which involves creating a file on your web server that Let’s Encrypt can access to verify your domain ownership. To do this, you can follow these steps:

  1. Connect to your web server via SSH using your terminal application.

  2. Run the following command to create a directory for your domain name in your web root directory. You need to replace api.example.com with your own domain name and /home/username/api.example.com/ with your own web root path:

    mkdir -p /home/username/api.example.com/.well-known/acme-challenge
    
  3. Run the following command to generate SSL certificates for your domain name and the www domain name using acme.sh. You need to replace api.example.com with your own domain name and /home/username/api.example.com/ with your own web root path:

    acme.sh --issue -d api.example.com -d www.api.example.com --webroot /home/username/api.example.com/
    
  4. Wait for the command to finish. You should see something like this:

    [Thu Jan  2 22:06:50 EST 2024] Creating domain key
    [Thu Jan  2 22:06:50 EST 2024] The domain key is here: /home/username/.acme.sh/api.example.com_ecc/api.example.com.key
    [Thu Jan  2 22:06:50 EST 2024] Multi domain='DNS:api.example.com,DNS:www.api.example.com'
    [Thu Jan  2 22:06:50 EST 2024] Getting domain auth token for each domain
    [Thu Jan  2 22:06:51 EST 2024] Getting webroot for domain='api.example.com'
    [Thu Jan  2 22:06:51 EST 2024] Getting webroot for domain='www.api.example.com'
    [Thu Jan  2 22:06:51 EST 2024] Verifying: api.example.com
    [Thu Jan  2 22:06:54 EST 2024] Success
    [Thu Jan  2 22:06:54 EST 2024] Verifying: www.api.example.com
    [Thu Jan  2 22:06:57 EST 2024] Success
    [Thu Jan  2 22:06:57 EST 2024] Verify finished, start to sign.
    [Thu Jan  2 22:06:57 EST 2024] Lets finalize the order, Le_OrderFinalize: https://acme-v02.api.letsencrypt.org/acme/finalize/123456789/987654321
    [Thu Jan  2 22:06:58 EST 2024] Download cert, Le_LinkCert: https://acme-v02.api.letsencrypt.org/acme/cert/abcdef0123456789abcdef0123456789abcdef01
    [Thu Jan  2 22:06:59 EST 2024] Cert success.
    -----BEGIN CERTIFICATE----- MIIFZTCCBE2gAwIBAgISA+8vASNFZ4mr4s8rRZ5mr0s9MA0GCSqGSIb3DQEBCwUA … -----END CERTIFICATE----- [Thu Jan 2 22:06:59 EST 2024] Your cert is in /home/username/.acme.sh/api.example.com_ecc/api.example.com.cer [Thu Jan 2 22:06:59 EST 2024] Your cert key is in /home/username/.acme.sh/api.example.com_ecc/api.example.com.key [Thu Jan 2 22:06:59 EST 2024] The intermediate CA cert is in /home/username/.acme.sh/api.example.com_ecc/ca.cer [Thu Jan 2 22:06:59 EST 2024] And the full chain certs is there: /home/username/.acme.sh/api.example.com_ecc/fullchain.cer
    
    List acme folder: api.example.com.cer api.example.com.conf api.example.com.csr api.example.com.csr.conf api.example.com.key ca.cer fullchain.cer
    
    Key Certificate: -----BEGIN EC PRIVATE KEY----- MHcCAQEEIMyZ4t8j8ZLxZ4mr4s8rRZ5mr0s9ASNFZ4mr4s8rRZ5moAoGCCqGSM49 … -----END EC PRIVATE KEY-----
    
    CER Certificate: -----BEGIN CERTIFICATE----- MIIFZTCCBE2gAwIBAgISA+8vASNFZ4mr4s8rRZ5mr0s9MA0GCSqGSIb3DQEBCwUA … -----END CERTIFICATE-----
    
    Expiration Date: 2024-04-02
    
    Domain api.example.com Setup finished!
    

Step 3: Automating the generation of SSL Certificates with Scala

In order to generate a certificate for your domain, you need to run the following command:

   import com.decodified.scalassh.SSH

   @main def farolApp(domain: String, path: String, certs: String = "generate-certs"): Unit =
     println(s"Setting up Domains: $domain and www.$domain")
     println(s"Setting up Path: $path")
     println(s"Setting up Certs: $certs")
     val wwwDomain = s"www.$domain"
     val generateCerts = certs=="generate-certs"

     def commandCerts(genCerts: Boolean) = if (genCerts) s"~/.acme.sh/acme.sh --issue -d $domain -d $wwwDomain -w $path" else s"echo 'Not generating certs'"

     SSH("namecheap") { client =>
       for {
         acmeResult <- client.exec(commandCerts(generateCerts))
         sshResult <- client.exec(s"ls ~/.acme.sh/${domain}_ecc/")
         keyCertificate <- client.exec(s"cat ~/.acme.sh/${domain}_ecc/${domain}.key")
         cerCertificate <- client.exec(s"cat ~/.acme.sh/${domain}_ecc/${domain}.cer")
         expirationDate <- client.exec(s"~/.acme.sh/acme.sh --list --listraw | grep $domain | awk -F\\| '{print $$NF}'")
       } yield {
         println("Acme Result:\n" + acmeResult.stdOutAsString())
         println(s"List acme folder:\n ${sshResult.stdOutAsString()}\n")
         println(s"Key Certificate: ${keyCertificate.stdOutAsString()}\n")
         println(s"CER Certificate: ${cerCertificate.stdOutAsString()}\n")
         println(s"Expiration Date: ${expirationDate.stdOutAsString()}\n")
       }
     }
     print(s"Domain $domain Setup finished!\n")

Congratulations! You have successfully installed, downloaded and generated SSL certificates for free with Let’s Encrypt on shared hosting providers such as Namecheap using Scala 3.3.