Apply your own domain to Rails of VPS and make it SSL (https) (CentOS 8.2 / Nginx)

In addition, I am working continuously from the following articles posted last time. However, since there is no direct connection with the previous article, it is okay to carry out the work of this article independently.

"Deploy to ConoHa VPS (CentOS 8.2) with Rails 6 + PostgreSQL + Nginx + Unicorn + Capistrano"

The following is the start immediately.


It is premised on CentOS (8.2) and Nginx environment. At the start of work, it is assumed that the Rails application will be displayed when you enter http: // IP address.

Also, I wrote it on the assumption that I have already acquired my own domain at Name.com (although it does not matter which registrar I acquired it from).

Now, follow the steps below.

1. 1. Apply your own domain

1-1. Change the DNS settings of your name dot com

Add the following two on the DNS record setting page of your name dot com. As an example, the domain is ʻexample.com`.

hostname TYPE TTL VALUE
example.com A 3600 IP address of the server (xxx.xxx.xxx.xxx)
www.example.com CNAME 3600 example.com

After the above, the record settings should be as follows.

hostname TYPE TTL VALUE
example.com NS 86400 01.dnsv.jp
example.com NS 86400 02.dnsv.jp
example.com NS 86400 03.dnsv.jp
example.com NS 86400 04.dnsv.jp
example.com A 3600 IP address of the server (xxx.xxx.xxx.xxx)
www.example.com CNAME 3600 example.com

As soon as the settings are reflected, when you access ʻexample.com and www.example.com`, it changes to access the server.

However, when I try to access ʻexample.com` in this state, the Nginx page is displayed. You also need to change the Nignx settings.

hostname TYPE TTL VALUE
example.com A 3600 IP address of the server (xxx.xxx.xxx.xxx)
www.example.com CNAME 3600 example.com

What the above means

--The IP address of ʻexample.com is xxx.xxx.xxx.xxx --www.example.com is another name for ʻexample.com

So, in other words, you will access xxx.xxx.xxx.xxx no matter which one you enter.

Here, without using the CNAME (alias) setting

hostname TYPE TTL VALUE
example.com A 3600 IP address of the server (xxx.xxx.xxx.xxx)
www.example.com A 3600 IP address of the server (xxx.xxx.xxx.xxx)

Even if it is above, the movement will be exactly the same, but for the sake of meaning, it is better to set it using CNAME.

1-2. Change Nginx settings

After connecting to the server and switching to the root user, open the config file below.

vim /etc/nginx/conf.d/Application name.conf

It should look like the one below.

nginx:/etc/nginx/conf.d/Application name.conf


upstream unicorn_Application name{
  server unix:/var/www/Application name/current/tmp/sockets/unicorn.sock;
}
server {
  listen 80;
  server_name server IP address;
  root /var/www/Application name/current/public;
  access_log /var/log/nginx/Application name_access.log;
  error_log /var/log/nginx/Application name_error.log;
  location / {
    try_files $uri @unicorn;
  }
  location @unicorn {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unicorn_Application name;
  }
}

Change the IP address of server_name above to ʻexample.com` as shown below.

nginx:/etc/nginx/conf.d/Application name.conf


server_name example.com;

After the change, test if there is a problem with the configuration file.

nginx -t

If all goes well, restart Nginx.

systemctl restart nginx

After that, when you access http://example.com, the page of the application will be displayed.

Here, if you access with http: // IP address, the application was displayed before, but now the Nginx page is displayed. This is the result of rewriting the previous configuration file and eliminating the description of the IP address.

Once again, modify the Nginx config file to achieve the following behavior.

--When you access ʻexample.com, the page of ʻexample.com opens. --When you access www.example.com, the page of ʻexample.com opens (with a 301 redirect). --When you access the ʻIP address (with a 301 redirect), the ʻexample.com` page opens.

In other words, the move to shift everything to ʻexample.com` (without www).

Open the file again and

vim /etc/nginx/conf.d/Application name.conf

Update the server part of the configuration file as follows.

nginx:/etc/nginx/conf.d/Application name.conf


server {
  listen 80;
  server_name example.com;
  root /var/www/Application name/current/public;
  access_log /var/log/nginx/Application name_access.log;
  error_log /var/log/nginx/Application name_error.log;
  location / {
    try_files $uri @unicorn;
  }
  location @unicorn {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unicorn_Application name;
  }
}
server {
  listen 80;
  server_name www.example.IP address of com server;
  return 301 http://example.com$request_uri;
}

Add another description of server, add www.example.com and the server's ʻIP address to server_name (insert a space between them), and use 301 redirect for ʻexample. Directed to com.

$request_uriというのはその時のページを指している変数で、例えば、www.example.com/blogsにアクセスしたら、example.com/blogsにリダイレクトしている。

After changing, don't forget to test the settings and restart Nginx if there is no problem.

nginx -t
systemctl restart nginx

This completes the settings to enable access by domain.

2. Make SSL (https)

2-1. Allow https connection (open port 443)

Open port 443 to allow https.

First, let's check the setting status of firewalld.

firewall-cmd --list-all

Check that services: cockpit dhcpv6-client http ssh. http and ssh are allowed.

Do the following:

firewall-cmd --add-service=https --permanent

Reload firewalld to reflect the settings.

firewall-cmd --reload

Execute again to confirm the change.

firewall-cmd --list-all

services: cockpit dhcpv6-client http https ssh, and https is added.

2-2. Install Certbot

Certbot is a tool that automatically performs everything from SSL certificate to setting with Let ’s Encrypt.

Install Certbot and the plugins needed to use Certbot with Nginx.

dnf -y install certbot python3-certbot-nginx

Check if it was installed.

certbot --version

If certbot 1.7.0 is displayed, it's OK.

2-3. Obtain and set the SSL certificate

Use Certbot to get and set up an SSL certificate.

certbot --nginx

You will be asked questions about the settings interactively, so answer them. Below are all the questions and examples of answers.

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices)
 (Enter 'c' to cancel): [email protected] #Enter your email address

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: (A)gree/(C)ancel: A #Select A (Agree)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: N #Select N (No)

Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: example.com
2: www.example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1 # exmaple.HTTPS conversion of jp
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/Application name.conf
Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/Application name.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-XX-XX. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Confirm that the certificate has been obtained and set. Do the following:

certbot certificates

OK if the certificate information for the example.com domain is displayed.

You can now connect via HTTPS. Make sure you can access it at https://example.com.

Also, since the certificate is valid for 3 months, it will expire after 3 months if it is left as it is. Add a Coulomb job and have the certificate automatically renewed on a regular basis so that it can be used virtually permanently. Do the following:

echo "0 0,12 * * * root python3 -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q" | sudo tee -a /etc/crontab > /dev/null

Output the contents of the file to confirm that Coulomb has been set.

cat /etc/crontab

Confirm that there is "0 0,12 * * * root python3 -c'import random; import time; time.sleep (random.random () * 3600)'&& certbot renew -q" at the end of the output result.

Restart the Coulomb daemon to reflect the settings.

systemctl restart crond

Finally, try a dry run (= test) for confirmation.

certbot renew --dry-run

If it says "Congratulations, all renewals succeeded." In the result, it's OK.

2-4. Change Nginx settings

Now check the Nginx configuration file.

vim /etc/nginx/conf.d/Application name.conf

Then, you can confirm that the server part of the contents has changed automatically. This is because Certbot has updated it. The following is an example after being updated.

nginx:/etc/nginx/conf.d/Application name.conf


server {
  server_name example.com;
  root /var/www/Application name/current/public;
  access_log /var/log/nginx/Application name_access.log;
  error_log /var/log/nginx/Application name_error.log;
  location / {
    try_files $uri @unicorn;
  }
  location @unicorn {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unicorn_Application name;
  }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
  listen 80;
  server_name www.example.IP address of com server;
  return 301 https://example.com$request_uri;
}

server {
    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


  listen 80;
  server_name example.com;
    return 404; # managed by Certbot


}

However, if you keep the above, you may not be able to redirect when accessed with https://www.example.com or https: // IP address, or you may want to arrange the indentation and description position neatly. Therefore, it was redeveloped into the following form.

In addition, writing "listen 443 ssl;" in one line and writing "listen 443;" and "ssl on;" in two lines have the same meaning.

nginx:/etc/nginx/conf.d/Application name.conf


server {
  listen 443;
  ssl on;
  server_name example.com;
  root /var/www/Application name/current/public;
  access_log /var/log/nginx/Application name_access.log;
  error_log /var/log/nginx/Application name_error.log;
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
  include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  location / {
    try_files $uri @unicorn;
  }
  location @unicorn {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unicorn_Application name;
  }
}
server {
  listen 443;
  server_name www.example.IP address of com server;
  return 301 https://example.com$request_uri;
}
server {
  listen 80;
  server_name example.com www.example.IP address of com server;
  return 301 https://example.com$request_uri;
}

Now you will be 301 redirected to https://example.com in all of the following cases:

Don't forget to test & restart Nginx for the settings to take effect.

nginx -t
systemctl restart nginx

3. 3. reference

Rails config / environments / production.rb has the following options:

config/environments/production.rb


# config.force_ssl = true

By default, it should be commented out as above.

If you uncomment and enable this option, you will be able to redirect to https when your app is accessed via http. In other words, you can achieve the same thing as the content set in Nginx.

However, I think that such processing is originally handled by the Web server (Nginx), so if you are using a Web server like this time, do not use the above Rails function and handle it on the Web server side. Keep it.

that's all

This is the end.

Supplement

Thank you for reading the article.

I will put a link to the original blog article below, but since the content is the same as this article, you do not need to refer to it in particular, but rather, because it has the syntax highlighting function of Qiita, the article on Qiita It should be easier to understand if you read.

knmts.com | Apply your own domain to Rails of VPS and make it SSL (https) (CentOS 8.2 / Nginx)

Recommended Posts

Apply your own domain to Rails of VPS and make it SSL (https) (CentOS 8.2 / Nginx)
Make Nginx of CentOS8 SSL compatible with Let's Encrypt
Make your own Rails validate
If you are new to Rails and want to make your own validation, stop by this finger.
Build Metabase with Docker on Lightsail and make it https with nginx
Redirect to your own domain with rack-rewrite on Heroku x Rails
How to make the schema of the URL generated by Rails URL helper https
Memorandum to make CentOS 7.9 and put pacemaker
Protect REST APIs built with Cloud Functions with Firebase authentication. And apply Firebase authentication to the API of your own REST server.