How to deploy SSL Certificate [nginx]
Tags: ssl, nginx, tutorial
Published: 2021-02-11 22:56:12

So you want to install/deploy an SSL Certificate to your website? Great! In this post, you can see how to do so with simple steps with 2 options.

## Option 1: Use Certbot (Easy one)

You can see the instructions based on your setup here
https://certbot.eff.org/instructions

## Option 2: Manual Setup (A little bit hard one)

I will assume you are using a UNIX based system (Linux, macOS, etc.) 
### Requirements
- A live website
- SSH access to your server
- nginx server running in your server
- SSL Certificate 

#### Step 1: Connect to your server with SSH

Using the `i` flag lets us pass the path of the identity file to access the remote server

You can connect to your server 
`ssh -i path_to_pem_file username@server_ip`

In my case
`ssh -i ~/.ssh/pem_file ubuntu@my_server_ip`

#### Step 2: Copy SSL files to your server using SCP

SCP command will help us copy from one computer to another using SSH protocol. We need to copy the crt and the key file to the remote server.
Notice the `i` flag here. It does the same job

`scp filename remote_username@server_ip:/home/user`
`user` at the end of the line here represents the folder of the user. This is `ubuntu` in my case. You can change the path whatever you want if `remote_username` has access to those paths.

#### Step 3: Configure nginx

We have copied the crt and the key to the remote server. Great! Now we need to configure nginx to listen 443 (HTTPS). 

First I suggest you move the crt and key files (In the remote server of course) to a different location other than your `/home/user` folder. You can move them into `/etc/ssl/`. But you will need sudo access to do that operation since accessing system paths require to have it.

* Go into the path your files are located in. I am assuming yours are in `/home/user`. 

`cd /home/user`
Again, `user` here is the username in the remote server. This is `ubuntu` in my case.

By the way, you may already in the correct location. You can see the current location you are in by using `pwd` command.


* Move the files to `/etc/ssl`
We need sudo access to do this operation
`sudo mv filename /etc/ssl`

* Go into nginx folder
`cd /etc/nginx`

* Edit the nginx.conf file using a text editor
You can use `nano` for that. 
We need sudo access for this operation too.
`sudo nano nginx.conf`

Now you are looking at the content of `nginx.conf`.
Look down a little bit and you will see this block

```
##
# SSL Settings
##

```
Notice the `#` sign. Those are for commenting out the lines.

Just below that block, you need to tell nginx where our crt and key files are located.

```
##
# SSL Settings
##

ssl_certificate /etc/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/ssl.key;
```
My files are named `ssl-bundle.crt` and `ssl.key`. If you have different filenames you need to change them of course.

You can go ahead and close nano by hitting `ctrl+X`. It will ask you `Save modified buffer?` which you can answer it by hitting `Y` for yes or `X` for no. Or you can hit `ctrl+C` to cancel the operation. 

We need to hit `Y` for nano to save the file.

#### Step 4: Restarting nginx
Now we need to restart nginx to see if it gives any error. Again, sudo access...
`sudo service nginx restart`

If you see nothing happens, that's great. But if you see lines like this 
```
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.
```
it means we made something wrong.

We can see what's wrong with nginx by typing this in the console
`sudo nginx -t`

Which may tell us some info like this
```
nginx: [emerg] cannot load certificate key "/etc/ssl/ssl.keya": BIO_new_file() failed (SSL: error:02001002:system library:fopen:No such file or directory:fopen('/etc/ssl/ssl.keya','r') error:2006D080:BIO routines:BIO_new_file:no such file)
nginx: configuration file /etc/nginx/nginx.conf test failed
```

From the info I understand that I made a typo. I typed `ssl.keya` instead of typing `ssl.key`. Fixing the typo and restarting nginx fixes the problem.

#### Step 5: Making nginx to listen to 443 for your site
This is the final step. We need to change the port that nginx listens to from 80 to 443. 

There is a folder in the nginx folder which is named `sites-available` which you should already know because I am assuming you have an already live website. Maybe I need to create a tutorial named **How to create and deploy a website**. 

* Go into sites-available folder
We are currently in `/etc/nginx`. If you are not you can use this command `cd /etc/nginx`. 
Now we can use `cd sites-available`.

There should be a file for your website. Let's call it `mysite`

We need to configure the file by using nano again.

* Edit the file

`sudo nano mysite`
There is a block like this. You can tell that nginx is listening port 80 (HTTP) for your site. We need to change that into 443 (HTTPS).
```
server {
	listen 80;
...
```
Changing the block above to below is what we desire.
```
server {
	listen 443 ssl;
...
```
And we can exit the editor by hitting `ctrl+X` and then `Y`.
#### Step 6: We need to restart nginx 
`sudo service nginx restart`
If you don't see any errors then you are good to go!

#### Step 7: Check your site
Now you can check your site if the certificate is correctly installed or not. And let me know in the comments if you have any issues.


## Some Notes
* The console commands were used in `Ubuntu 20.04.1 LTS (GNU/Linux 5.4.0-1028-aws x86_64)` in AWS EC2. Yours may be different. So **maybe** some commands will be different too.
* Typing the paths of the crt and the key files paths directly into the `nginx.conf` file allows you to have only 1 domain. If you have a wildcard SSL Certificate you still have 1 domain but you can have multiple subdomains. So if you want to have more than 1 domain you can define the certificate paths in the respective files under `sites-available` folder. Not in global `nginx.conf` file.
* If I made any typos or did not use best case usages please let me know so I can update this document.