From 531f439b5fc2dede0f26abc6419fc9574e8956e0 Mon Sep 17 00:00:00 2001 From: realaravinth Date: Mon, 12 Sep 2022 09:36:40 +0000 Subject: [PATCH] new deploy: 2022-09-12T09:36:40+00:00 --- about/index.html | 2 +- .../index.html | 824 ++++++++++++++++++ blog/atom.xml | 367 ++++++++ blog/index.html | 51 +- blog/main.css | 2 +- coc/index.html | 2 +- index.html | 2 +- legalese/index.html | 2 +- main.css | 2 +- nav/main.css | 2 +- page/main.css | 2 +- privacy-policy/index.html | 2 +- search_index.en.js | 2 +- sitemap.xml | 22 + tags/bare-metal/atom.xml | 367 ++++++++ tags/bare-metal/index.html | 328 +++++++ tags/git/atom.xml | 367 ++++++++ tags/git/index.html | 328 +++++++ tags/index.html | 391 +++++++++ tags/jamstack/atom.xml | 367 ++++++++ tags/jamstack/index.html | 328 +++++++ tags/nginx/atom.xml | 367 ++++++++ tags/nginx/index.html | 328 +++++++ tags/self-hosting/atom.xml | 367 ++++++++ tags/self-hosting/index.html | 328 +++++++ 25 files changed, 5139 insertions(+), 11 deletions(-) create mode 100644 blog/2022-09-10-how-to-publish-website-without-librepages/index.html create mode 100644 blog/atom.xml create mode 100644 tags/bare-metal/atom.xml create mode 100644 tags/bare-metal/index.html create mode 100644 tags/git/atom.xml create mode 100644 tags/git/index.html create mode 100644 tags/index.html create mode 100644 tags/jamstack/atom.xml create mode 100644 tags/jamstack/index.html create mode 100644 tags/nginx/atom.xml create mode 100644 tags/nginx/index.html create mode 100644 tags/self-hosting/atom.xml create mode 100644 tags/self-hosting/index.html diff --git a/about/index.html b/about/index.html index df48eff..38b36be 100644 --- a/about/index.html +++ b/about/index.html @@ -274,7 +274,7 @@ built with Free Software.

Privacy | + + + + + + + + + + + + + + + + + + + + + + + + + How to deploy a website WITHOUT LibrePages | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+

How to deploy a website WITHOUT LibrePages

+ + + +
+ + +

In this blog post tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!

+

We will be using the following technologies to deploy our website:

+
    +
  1. GNU/Linux server(Debian)
  2. +
  3. Nginx (webs server)
  4. +
  5. Let's Encrypt (for HTTPS)
  6. +
  7. Gitea (but any Git hosting works)
  8. +
+

Let's get started!

+

1. Setup Debian GNU/Linux# +

+

We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like Digital +Ocean (not affiliated).

+

1.1) Give your account sudo privileges# +

+

On GNU/Linux systems, the root account is the most powerful user account. +It is good practice to avoid working as root since a careless mistake +could wipe the entire system out.

+

sudo give the ability to execute commands with root capabilities +from a lower-privileged account. Let's make our account sudo capable:

+
su # become root
+
+# add `realaravinth`, my account` to `sudo` group to be able to use `sudo`
+usermod -aG sudo realaravinth # my account is called `realaravinth`, replace it with yours
+exit
+$ exit
+
+

Log out and log back in.

+

1.2) Install and setup firewall(ufw)# +

+

Uncomplicated Firewall(ufw) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.

+

We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.

+
install ufw # we are using `ufw` for the firewall
+$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server
+$ sudo ufw enable # deploy firewall
+
+

1.3) Secure SSH# +

+

SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.

+

1.3.1) Generate key pair# +

+

On your local computer, generate an SSH key pair:

+
$ ssh-keygen
+Generating public/private rsa key pair.
+Enter file in which to save the key (/home/realaravinth/.ssh/id_rsa):
+Enter passphrase (empty for no passphrase):
+Enter same passphrase again:
+Your identification has been saved in /home/realaravinth/.ssh/id_rsa
+Your public key has been saved in /home/realaravinth/.ssh/id_rsa.pub
+The key fingerprint is:
+SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo realaravinth@myserver.com
+The key's random art image is:
++---[RSA 3072]----+
+|      .. .o.     |
+|   . .  . .. . . |
+|    o    o  + o .|
+|   .      o* + .+|
+|    o   S ooB o+.|
+|   . . . o.. +o*=|
+|      . . . ooo*X|
+|           +=.ooB|
+|           o+E .o|
++----[SHA256]-----+
+
+

Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at ~/.ssh/id_rsa.pub and your private key at +~/.ssh/id_rsa. Never share the private key with anyone.

+

1.3.2) Setup public-key authentication# +

+

We have to copy the public key that we generated in the previous setup +onto our server:

+
$ ssh-copy-id  -i ~/.ssh/id_rsa.pub myserver.com
+/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/realaravinth/.ssh/id_rsa.pub"
+/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
+/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
+realaravinth@myserver.com's password:
+
+Number of key(s) added: 1
+
+Now try logging into the machine, with:   "ssh 'myserver.com'"
+and check to make sure that only the key(s) you wanted were added.
+
+

1.3.3) Disable SSH password authentication# +

+
+

NOTE: Verify you can log into your account before proceeding

+
+

Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:

+

Open /etc/ssh/sshd_config and add the following lines:

+
PubkeyAuthentication yes
+PasswordAuthentication no
+
+

And restart the SSH server:

+
$ sudo systemctl restart sshd
+
+

1.3) Install and setup fail2ban# +

+

We will be using fail2ban for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.

+

1.3.1) Install fail2ban# +

+
$ sudo apt install fail2ban
+
+

1.3.2) Enable fail2ban for sshd# +

+
[sshd]
+enabled = true
+
+

1.3.3) Configure fail2ban to start on boot# +

+
$ sudo systemctl enable fail2ban
+$ sudo systemctl start fail2ban
+
+

1.4) Install and setup nginx# +

+

nginx is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.

+

To install, run the following command:

+

1.4.1) Install nginx:# +

+
$ sudo apt install nginx
+
+

1.4.2) Allow web traffic: open ports 80 and 443# +

+

Ports 80 is the default for HTTP and 443 for HTTPS. To serve +web traffic, we'll have to Configure ufw to accept traffic on them:

+
$ sudo ufw allow 80 # open ports 80 HTTP traffic
+$ sudo ufw allow 443 # open ports 443 for HTTPS traffic
+
+

1.4.2) Configure nginx to start on boot# +

+
$ sudo systemtl enable nginx # automatically start nginx on boot
+$ sudo systemtl start nginx # start nginx server
+
+

And verify it works:

+
$ curl localhost
+<!DOCTYPE html>
+<html>
+<head>
+<title>Welcome to nginx!</title>
+<style>
+    body {
+        width: 35em;
+        margin: 0 auto;
+        font-family: Tahoma, Verdana, Arial, sans-serif;
+    }
+</style>
+</head>
+<body>
+<h1>Welcome to nginx!</h1>
+<p>If you see this page, the nginx web server is successfully installed and
+working. Further configuration is required.</p>
+
+<p>For online documentation and support please refer to
+<a href="http://nginx.org/">nginx.org</a>.<br/>
+Commercial support is available at
+<a href="http://nginx.com/">nginx.com</a>.</p>
+
+<p><em>Thank you for using nginx.</em></p>
+</body>
+</html>
+
+

nginx is working!

+

2) Deploy website# +

+

For this demo, we'll deploy a single file(index.html) +HTML website.

+

2.1) Install the webpage on the server# +

+

Edit /var/www/html/index.html and add the following HTML to it:

+
<!DOCTYPE html>
+<html>
+	<head>
+		<title>My cool website!</title>
+	</head>
+	<body>
+		<h1>Welcome to my website! o/</h1>
+	</body>
+</html>
+
+

The webpage should now be available on localhost, and we should see it when we run the following command:

+
$ curl localhost
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>My cool website!</title>
+    </head>
+    <body>
+        <h1>Welcome to my website! o/</h1>
+    </body>
+</html>
+
+

2.2) Serve webpage on a custom domain# +

+

2.2.1) Buy a domain if you don't own one already# +

+

2.2.2) Go to the domain's DNS dashboard and add the following record# +

+
@    A    300    <your server IP address>
+
+

2.2.3) Setup nginx to serve the website at http://<your-domain.# +

+

Open /etc/nginx/sites-available/your-domain and add the following:

+
server {
+    # serve website on port 80
+    listen [::]:80;
+    listen 80;
+
+    # write error logs to file
+    error_log /var/log/nginx/<your-domain>.error.log;
+    # write access logs to file
+    access_log /var/log/nginx/<your-domain>.access.log;
+
+    # serve only on this domain:
+    server_name <your-domain>; # replace me
+
+
+    # use files from this directory
+    root /var/www/html/;
+
+    # remove .html from URL; it is cleaner this way
+    rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
+
+    # when a request is received, try the index.html in the directory
+    # or $uri.html
+    try_files $uri/index.html $uri.html $uri/ $uri =404;
+}
+
+

It is good practice to have all nginx deployment configurations in +/etc/nginx/sites-available/ directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.

+

Let's enable <your-domain>

+
$ sudo ln -s /etc/nginx/sites-available/<your-domain> /etc/nginx/sites-available/<your-domain>
+
+

Verify configurations before deploying, nginx has a command +to do it:

+
$ sudo nginx -t
+
+

If there are no errors, reload nginx to deploy the website:

+
$ sudo nginx -s reload
+
+

Your webpage should now be accessible at http://<your-domain>!

+

2.3) Install certbot to set up HTTPS# +

+

HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using Let's +Encrypt a popular nonprofit certificate +authority to get our SSL certificates.

+

SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.

+

Thankfully, Let's Encrypt provides automation through certbot

+

2.3.1) Install certbot:# +

+
$ sudo apt install certbot python3-certbot-nginx
+
+

2.3.2) Get a certificate for <your-domain># +

+
$ sudo certbot --nginx -d <your-domain>
+
+

certbot will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the ACME +protocol. +By configuring the DNS to point to our server and by telling nginx at +that domain.

+

When it has verified ownership, it will automatically issue, deploy the +certificate on nginx and setup redirects.

+

2.3.3) Setup cronjob to automate SSL certificate renewals# +

+

Become root and edit crontab

+
$ su
+crontab -e
+
+

Add the following job and exit:

+
0 */12 * * * certbot -n --nginx renew
+
+

It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, certbot will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.

+

Now our GNU/Linux server is configured and ready to serve our website at +http://<your-website>!

+ +
+
+
+ +
+ +
+ + +
+ + diff --git a/blog/atom.xml b/blog/atom.xml new file mode 100644 index 0000000..bddb365 --- /dev/null +++ b/blog/atom.xml @@ -0,0 +1,367 @@ + + + - Posts + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/blog/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/blog/index.html b/blog/index.html index b3a73c9..95dbce4 100644 --- a/blog/index.html +++ b/blog/index.html @@ -227,6 +227,55 @@ general development ecosystem" /> Privacy | thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.blog__content table th{text-align:center}.blog__content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.blog__content p,.blog__content h2,.blog__content h3{margin:10px 0}.blog__content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.blog__content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.blog__content p{margin:30px 0}.blog__container{margin:auto;max-width:50%}.blog__list{list-style:none}.blog__post-link,.blog__post-link:visited{text-decoration:none;color:inherit}.blog__title{margin:35px 0}.blog__post-link{display:block}.blog__post-item{border-bottom:1px dashed #333;margin:10px;padding:10px}.blog__post-item:hover{background-color:lightgray}.blog__post-item:last-child{border-bottom:none}.blog__post-description{font-size:0.9rem;margin:5px 0}.blog__post-tag{font-size:0.7rem;font-family:monospace, monospace}.blog__post-tag:hover{color:#0056b3;text-decoration:underline}.blog__post-meta{font-size:0.7rem}.blog__post-title{font-size:1.4rem;font-weight:550}.blog__post-tag-container{margin:0}.blog__post-warning{background:yellow;padding:5px;margin:10px;border-left:10px solid orange}.blog__post-warning *{margin:5px !important} +.blog__content img{max-width:100%;display:block}.blog__content video{max-width:100%;display:block}.blog__content li{margin-left:40px}.blog__content a:hover{color:#0056b3;text-decoration:underline}.blog__content code{word-wrap:break-word;overflow-wrap:break-word}.blog__content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.blog__content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.blog__content table th{text-align:center}.blog__content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.blog__content p,.blog__content h2,.blog__content h3,.blog__content h4,.blog__content h5,.blog__content h6{margin:10px 0}.blog__content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.blog__content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.blog__content p{margin:30px 0}.blog__container{margin:auto;max-width:50%}.blog__list{list-style:none}.blog__post-link,.blog__post-link:visited{text-decoration:none;color:inherit}.blog__title{margin:35px 0}.blog__post-link{display:block}.blog__post-item{border-bottom:1px dashed #333;margin:10px;padding:10px}.blog__post-item:hover{background-color:lightgray}.blog__post-item:last-child{border-bottom:none}.blog__post-description{font-size:0.9rem;margin:5px 0}.blog__post-tag{font-size:0.7rem;font-family:monospace, monospace}.blog__post-tag:hover{color:#0056b3;text-decoration:underline}.blog__post-meta{font-size:0.7rem}.blog__post-title{font-size:1.4rem;font-weight:550}.blog__post-tag-container{margin:0}.blog__post-warning{background:yellow;padding:5px;margin:10px;border-left:10px solid orange}.blog__post-warning *{margin:5px !important} diff --git a/coc/index.html b/coc/index.html index 5f72ce7..cf1bfd7 100644 --- a/coc/index.html +++ b/coc/index.html @@ -303,7 +303,7 @@ Privacy | Privacy | Privacy | thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.page__group-content table th{text-align:center}.page__group-content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.page__group-content p,.page__group-content h2,.page__group-content h3{margin:10px 0}.page__group-content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.page__group-content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.page__preview-banner{width:10%;height:min(250px, 50vh);margin:20px auto}.page__banner{width:100%;height:max(450px, 50vh);margin:20px auto}.blog__content img{max-width:100%;display:block}.blog__content video{max-width:100%;display:block}.blog__content li{margin-left:40px}.blog__content a:hover{color:#0056b3;text-decoration:underline}.blog__content code{word-wrap:break-word;overflow-wrap:break-word}.blog__content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.blog__content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.blog__content table th{text-align:center}.blog__content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.blog__content p,.blog__content h2,.blog__content h3{margin:10px 0}.blog__content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.blog__content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.blog__content p{margin:30px 0}.blog__container{margin:auto;max-width:50%}.blog__list{list-style:none}.blog__post-link,.blog__post-link:visited{text-decoration:none;color:inherit}.blog__title{margin:35px 0}.blog__post-link{display:block}.blog__post-item{border-bottom:1px dashed #333;margin:10px;padding:10px}.blog__post-item:hover{background-color:lightgray}.blog__post-item:last-child{border-bottom:none}.blog__post-description{font-size:0.9rem;margin:5px 0}.blog__post-tag{font-size:0.7rem;font-family:monospace, monospace}.blog__post-tag:hover{color:#0056b3;text-decoration:underline}.blog__post-meta{font-size:0.7rem}.blog__post-title{font-size:1.4rem;font-weight:550}.blog__post-tag-container{margin:0}.blog__post-warning{background:yellow;padding:5px;margin:10px;border-left:10px solid orange}.blog__post-warning *{margin:5px !important}.tag__item-link,.tag__item-link:visited{text-decoration:none}.tag__item-link{display:flex;align-items:start;flex-direction:column;flex:2}.tag__item{border-bottom:1px dashed #333;margin:10px;display:flex;justify-content:space-between;padding:5px}.tag__item-title{font-size:1.4rem}.tag__meta{font-size:0.7rem}.tag__rss-link{margin:auto 20px}.tag__title{display:inline;flex:2}.tag__title-container{margin:35px 0;display:flex}.tag__rss-link--single{margin:auto}.clinic__doctors-container{display:flex}.doctor__profile_photo{width:100px;height:100px;border-radius:100px}.doctor__container{background-color:#eee;margin:10px 30px;padding:10px;height:250px;border-radius:5px;width:30%;display:flex;flex-direction:column;align-items:center;justify-content:space-around}.doctor__name{text-align:center;margin:0 auto !important}.doctor_rating-stars,.doctor_rating-value{margin:0 auto !important;text-align:center}.zola-anchor{margin-left:5px}.anchor-icon{color:inherit !important} +*{padding:0;margin:0;font-family:"Segoe UI", Tahoma, Geneva, Verdana, sans-serif;font-family:"Segoe UI", Tahoma, Geneva, Verdana, sans-serif}a{text-decoration:none}a:hover,button:hover{cursor:pointer}a,a:visited{color:#0056b3}.base{min-height:100vh;display:flex;flex-direction:column;width:100%}.main__content-container{display:flex;flex-direction:column;min-height:100%;justify-content:space-between;flex:2}p,h1,h2,h3,h4,li,ol,ul{color:#333}main{width:100%}blockquote{border-left:0.3em solid rgba(55,55,55,0.4);margin-bottom:16px;padding:0 1em;color:#707070}blockquote p,blockquote h1,blockquote h2,blockquote h3,blockquote h4,blockquote li,blockquote ol,blockquote ul{color:inherit}.home-card__group{display:flex;margin:0px auto;width:80%}.home-card__conatiner{background-color:#eee;margin:10px 30px;padding:10px;border-radius:5px;width:30%}.home-card__icon{width:100px;height:100px;margin:auto;border-radius:100px}.home-card__title{margin:auto;text-align:center}.home-card__text{font-size:0.7rem;text-align:center}.service__features{margin:20px 0px;height:100vh;min-height:500px;max-height:800px;display:flex;flex-direction:column;justify-content:space-between}.service__features--split{margin:20px 0px;height:100vh;min-height:500px;max-height:800px;display:flex;flex-direction:column;justify-content:space-between;max-height:1300px}.service-card__group{margin:0px auto}.service-card__conatiner{margin:10px 0px;border-radius:5px;display:flex;width:80%;margin:0 auto}.line-border{width:80%;display:block;border-bottom:1px solid #cacaca;margin:auto}.service-card__icon{width:100px;height:100px;margin:auto;flex:2;border-radius:100px}.service-card__service-name{color:green;font-weight:600}.service-card__title{margin:auto}.service-card__text{margin-bottom:30px !important}.service-card__text-container{flex:2;margin:auto !important}.service-card__aciton-btn{margin:auto 0;padding:10px;display:block;font-weight:400;border:none;background-color:#000}.service__features{display:flex;flex-direction:column;align-items:center}.service__features-title{margin:10px auto !important}.service-card__icon-container{width:30%;margin:auto}.service-card__aciton-btn--inactive{margin:auto;padding:10px;display:block;font-weight:400;border:none;background-color:lightgrey;color:#000}.home__vision-container{display:flex;align-items:center;height:200px;justify-content:space-between}.home__vision-text-line{font-size:0.8rem;font-style:italic}.home__vision-intro-title{text-align:center}.home__vision-intro-tagline{font-size:0.9rem;margin:auto;display:block;text-align:center}.home__vision-aciton-btn{display:block;font-weight:400;margin:20px auto;padding:15px;border:none;background-color:black;color:#fff}.home__vision-aciton-btn:hover{background-color:lightgray}.home__vision-action-link{color:white !important}.page__container--split{width:50%;margin:auto;padding:50px 0;width:80%;height:100vh;min-height:500px;max-height:800px;max-height:1300px;height:90vh !important;display:flex;flex-direction:column;justify-content:space-around}.index-banner__container{width:100%;display:flex;flex-direction:column;font-family:"Segoe UI", Tahoma, Geneva, Verdana, sans-serif;height:100vh;min-height:500px;max-height:800px;flex-grow:1}.index-banner{margin:auto;width:80%;display:flex;justify-content:space-between}.index-banner__logo-container{margin:center;align-items:center;display:flex;width:500px}.index-banner__title{margin:auto;font-style:none}.index-banner__tagline{margin:auto}.index-banner__title-container{display:flex}.index-banner__logo{width:120px;margin:auto;border-radius:20px}.index-banner__main-action-btn{display:block;display:block;font-weight:400;padding:15px;border:none;margin:20px 0;background-color:green}.index-banner__main-action-link{color:white !important}.index-banner__features-list{margin:20px}.index-banner__features{margin:10px 0}.home__features{display:flex;flex-direction:column;align-items:center}.home__features-title{margin:auto}.index__group-content .page__container{width:80%;height:100vh;min-height:500px;max-height:800px;height:90vh !important;display:flex;flex-direction:column;justify-content:space-around}.action-call__container{background:#1f5818;width:100%;padding:60px 0}.action-call__margin-container{display:flex;width:80%;margin:auto;align-items:center;justify-content:space-around}.action-call__prompt{color:white;font-weight:400;font-size:1.7rem}.action-call__button{display:block;display:block;font-weight:400;padding:15px;border:none;margin:20px 0;background-color:#fff}.action-call__button:hover{background-color:lightgray}.action-call_link{color:#000 !important}.action-call_link:hover{text-decoration:none !important}header{z-index:5;position:sticky;top:0;background-color:#fff}.nav__container{display:flex;flex-direction:row;box-sizing:border-box;width:100%;padding-top:5px;border-bottom:1px solid #d3d3d3}.nav__home-btn{font-weight:bold;margin:auto;margin-left:10px}.nav__hamburger-menu{display:none}.nav__spacer--small{width:100px;margin:auto}.nav__spacer{flex:3;margin:auto}.nav__logo-container{display:inline-flex;text-decoration:none}.nav__logo-container:hover{color:#0056b3;text-decoration:underline}.nav__toggle{display:none}.nav__logo{display:inline-flex;margin:auto;padding:5px;width:40px}.nav__link-group{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center}.nav__link-group--small{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center;flex:0.5;margin-right:10px}.nav__link-container{display:flex;padding:10px;height:100%;margin:auto}.nav__link-container--action{display:flex;padding:10px;height:100%;margin:auto;background-color:green;padding:15px}.nav__link-container--action .nav__link{color:white !important}.nav__link{text-decoration:none;color:black !important;font-weight:600;font-size:14px}.nav__link:hover{color:#0056b3;text-decoration:underline}footer{display:block;color:#333;font-size:0.7rem;padding:0;margin:0}.footer__container{width:100%;padding:0;justify-content:space-between;margin:auto;display:flex;flex-direction:row;overflow:hidden}.footer__column{list-style:none;display:flex;margin:auto 50px;align-items:center;flex:2.5}.footer__column--center{list-style:none;display:flex;margin:auto 50px;align-items:center;flex:2.5;margin:auto;flex-direction:column;align-items:center;flex:2}.footer__column:last-child{justify-content:flex-end}.footer__column:last-child a{margin:10px}.footer__link-container{margin:5px}.footer__link{text-decoration:none}.license__link{display:inline}.license__link:hover{color:#0056b3;text-decoration:underline}.footer__column-divider,.footer__column-divider--mobile-visible,.footer__column-divider--mobile-only{font-weight:500;opacity:0.7;margin:0 5px}.footer__column-divider--mobile-only{display:none}.footer__icon{margin:auto 5px;height:20px}.page__container{width:50%;margin:auto;padding:50px 0}.page__group{display:flex;flex-direction:column}.page__group-title{margin:20px auto}.page__group-content{display:flex;flex-direction:column}.page__group-content img{max-width:100%;display:block}.page__group-content video{max-width:100%;display:block}.page__group-content li{margin-left:40px}.page__group-content a:hover{color:#0056b3;text-decoration:underline}.page__group-content code{word-wrap:break-word;overflow-wrap:break-word}.page__group-content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.page__group-content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.page__group-content table th{text-align:center}.page__group-content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.page__group-content p,.page__group-content h2,.page__group-content h3,.page__group-content h4,.page__group-content h5,.page__group-content h6{margin:10px 0}.page__group-content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.page__group-content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.page__preview-banner{width:10%;height:min(250px, 50vh);margin:20px auto}.page__banner{width:100%;height:max(450px, 50vh);margin:20px auto}.blog__content img{max-width:100%;display:block}.blog__content video{max-width:100%;display:block}.blog__content li{margin-left:40px}.blog__content a:hover{color:#0056b3;text-decoration:underline}.blog__content code{word-wrap:break-word;overflow-wrap:break-word}.blog__content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.blog__content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.blog__content table th{text-align:center}.blog__content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.blog__content p,.blog__content h2,.blog__content h3,.blog__content h4,.blog__content h5,.blog__content h6{margin:10px 0}.blog__content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.blog__content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.blog__content p{margin:30px 0}.blog__container{margin:auto;max-width:50%}.blog__list{list-style:none}.blog__post-link,.blog__post-link:visited{text-decoration:none;color:inherit}.blog__title{margin:35px 0}.blog__post-link{display:block}.blog__post-item{border-bottom:1px dashed #333;margin:10px;padding:10px}.blog__post-item:hover{background-color:lightgray}.blog__post-item:last-child{border-bottom:none}.blog__post-description{font-size:0.9rem;margin:5px 0}.blog__post-tag{font-size:0.7rem;font-family:monospace, monospace}.blog__post-tag:hover{color:#0056b3;text-decoration:underline}.blog__post-meta{font-size:0.7rem}.blog__post-title{font-size:1.4rem;font-weight:550}.blog__post-tag-container{margin:0}.blog__post-warning{background:yellow;padding:5px;margin:10px;border-left:10px solid orange}.blog__post-warning *{margin:5px !important}.tag__item-link,.tag__item-link:visited{text-decoration:none}.tag__item-link{display:flex;align-items:start;flex-direction:column;flex:2}.tag__item{border-bottom:1px dashed #333;margin:10px;display:flex;justify-content:space-between;padding:5px}.tag__item-title{font-size:1.4rem}.tag__meta{font-size:0.7rem}.tag__rss-link{margin:auto 20px}.tag__title{display:inline;flex:2}.tag__title-container{margin:35px 0;display:flex}.tag__rss-link--single{margin:auto}.clinic__doctors-container{display:flex}.doctor__profile_photo{width:100px;height:100px;border-radius:100px}.doctor__container{background-color:#eee;margin:10px 30px;padding:10px;height:250px;border-radius:5px;width:30%;display:flex;flex-direction:column;align-items:center;justify-content:space-around}.doctor__name{text-align:center;margin:0 auto !important}.doctor_rating-stars,.doctor_rating-value{margin:0 auto !important;text-align:center}.zola-anchor{margin-left:5px}.anchor-icon{color:inherit !important}code{font-family:ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, Liberation Mono, monospace;font-size:85%}p>code{background-color:#afb8c133;padding:0.2em 0.4em;border-radius:6px} diff --git a/nav/main.css b/nav/main.css index b363715..d148585 100644 --- a/nav/main.css +++ b/nav/main.css @@ -1 +1 @@ -header{z-index:5;position:sticky;top:0;background-color:#fff}.nav__container{display:flex;flex-direction:row;box-sizing:border-box;width:100%;padding-top:5px;border-bottom:1px solid #d3d3d3}.nav__home-btn{font-weight:bold;margin:auto;margin-left:10px}.nav__hamburger-menu{display:none}.nav__spacer--small{width:100px;margin:auto}.nav__spacer{flex:4;margin:auto}.nav__logo-container{display:inline-flex;text-decoration:none}.nav__logo-container:hover{color:#0056b3;text-decoration:underline}.nav__toggle{display:none}.nav__logo{display:inline-flex;margin:auto;padding:5px;width:40px}.nav__link-group{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center}.nav__link-group--small{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center;flex:0.5;margin-right:10px}.nav__link-container{display:flex;padding:10px;height:100%;margin:auto}.nav__link-container--action{display:flex;padding:10px;height:100%;margin:auto;background-color:green;padding:15px}.nav__link-container--action .nav__link{color:white !important}.nav__link{text-decoration:none;color:black !important;font-weight:600;font-size:14px}.nav__link:hover{color:#0056b3;text-decoration:underline} +header{z-index:5;position:sticky;top:0;background-color:#fff}.nav__container{display:flex;flex-direction:row;box-sizing:border-box;width:100%;padding-top:5px;border-bottom:1px solid #d3d3d3}.nav__home-btn{font-weight:bold;margin:auto;margin-left:10px}.nav__hamburger-menu{display:none}.nav__spacer--small{width:100px;margin:auto}.nav__spacer{flex:3;margin:auto}.nav__logo-container{display:inline-flex;text-decoration:none}.nav__logo-container:hover{color:#0056b3;text-decoration:underline}.nav__toggle{display:none}.nav__logo{display:inline-flex;margin:auto;padding:5px;width:40px}.nav__link-group{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center}.nav__link-group--small{flex:1.5;list-style:none;display:flex;flex-direction:row;align-items:center;align-self:center;margin:auto;text-align:center;flex:0.5;margin-right:10px}.nav__link-container{display:flex;padding:10px;height:100%;margin:auto}.nav__link-container--action{display:flex;padding:10px;height:100%;margin:auto;background-color:green;padding:15px}.nav__link-container--action .nav__link{color:white !important}.nav__link{text-decoration:none;color:black !important;font-weight:600;font-size:14px}.nav__link:hover{color:#0056b3;text-decoration:underline} diff --git a/page/main.css b/page/main.css index e172bf9..a9e761d 100644 --- a/page/main.css +++ b/page/main.css @@ -1 +1 @@ -.page__container{width:50%;margin:auto;padding:50px 0}.page__group{display:flex;flex-direction:column}.page__group-title{margin:20px auto}.page__group-content{display:flex;flex-direction:column}.page__group-content img{max-width:100%;display:block}.page__group-content video{max-width:100%;display:block}.page__group-content li{margin-left:40px}.page__group-content a:hover{color:#0056b3;text-decoration:underline}.page__group-content code{word-wrap:break-word;overflow-wrap:break-word}.page__group-content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.page__group-content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.page__group-content table th{text-align:center}.page__group-content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.page__group-content p,.page__group-content h2,.page__group-content h3{margin:10px 0}.page__group-content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.page__group-content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.page__preview-banner{width:10%;height:min(250px, 50vh);margin:20px auto}.page__banner{width:100%;height:max(450px, 50vh);margin:20px auto} +.page__container{width:50%;margin:auto;padding:50px 0}.page__group{display:flex;flex-direction:column}.page__group-title{margin:20px auto}.page__group-content{display:flex;flex-direction:column}.page__group-content img{max-width:100%;display:block}.page__group-content video{max-width:100%;display:block}.page__group-content li{margin-left:40px}.page__group-content a:hover{color:#0056b3;text-decoration:underline}.page__group-content code{word-wrap:break-word;overflow-wrap:break-word}.page__group-content table{border-collapse:collapse;caption-side:bottom;border-color:#e9ecef;text-align:center;width:100%}.page__group-content table>thead{vertical-align:bottom;border-bottom:1px solid #cdc8ca;text-align:center}.page__group-content table th{text-align:center}.page__group-content table td{margin:auto;padding:10px;border-bottom:1px solid #edddd1}.page__group-content p,.page__group-content h2,.page__group-content h3,.page__group-content h4,.page__group-content h5,.page__group-content h6{margin:10px 0}.page__group-content pre{padding:10px 10px 10px 20px;border-radius:8px;font-size:0.95rem;overflow:auto}.page__group-content pre{font-family:monospace, monospace;font-display:auto;font-size:1em}.page__preview-banner{width:10%;height:min(250px, 50vh);margin:20px auto}.page__banner{width:100%;height:max(450px, 50vh);margin:20px auto} diff --git a/privacy-policy/index.html b/privacy-policy/index.html index 70097d5..b2a87bd 100644 --- a/privacy-policy/index.html +++ b/privacy-policy/index.html @@ -305,7 +305,7 @@ see. This is derived from the User-Agent HTTP header. For example: ChromePrivacy | https://librepages.org/blog/ + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + 2022-09-10 + https://librepages.org/coc/ @@ -18,4 +22,22 @@ https://librepages.org/privacy-policy/ + + https://librepages.org/tags/ + + + https://librepages.org/tags/bare-metal/ + + + https://librepages.org/tags/git/ + + + https://librepages.org/tags/jamstack/ + + + https://librepages.org/tags/nginx/ + + + https://librepages.org/tags/self-hosting/ + diff --git a/tags/bare-metal/atom.xml b/tags/bare-metal/atom.xml new file mode 100644 index 0000000..a3e2293 --- /dev/null +++ b/tags/bare-metal/atom.xml @@ -0,0 +1,367 @@ + + + - bare-metal + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/tags/bare-metal/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/tags/bare-metal/index.html b/tags/bare-metal/index.html new file mode 100644 index 0000000..dd82e17 --- /dev/null +++ b/tags/bare-metal/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bare-metal | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/tags/git/atom.xml b/tags/git/atom.xml new file mode 100644 index 0000000..e30b870 --- /dev/null +++ b/tags/git/atom.xml @@ -0,0 +1,367 @@ + + + - git + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/tags/git/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/tags/git/index.html b/tags/git/index.html new file mode 100644 index 0000000..2b843fe --- /dev/null +++ b/tags/git/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + git | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/tags/index.html b/tags/index.html new file mode 100644 index 0000000..4209f40 --- /dev/null +++ b/tags/index.html @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + tags | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/tags/jamstack/atom.xml b/tags/jamstack/atom.xml new file mode 100644 index 0000000..a769f0b --- /dev/null +++ b/tags/jamstack/atom.xml @@ -0,0 +1,367 @@ + + + - JAMStack + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/tags/jamstack/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/tags/jamstack/index.html b/tags/jamstack/index.html new file mode 100644 index 0000000..c546ba7 --- /dev/null +++ b/tags/jamstack/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + JAMStack | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/tags/nginx/atom.xml b/tags/nginx/atom.xml new file mode 100644 index 0000000..1a8f781 --- /dev/null +++ b/tags/nginx/atom.xml @@ -0,0 +1,367 @@ + + + - nginx + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/tags/nginx/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/tags/nginx/index.html b/tags/nginx/index.html new file mode 100644 index 0000000..6d10fc5 --- /dev/null +++ b/tags/nginx/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + nginx | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + diff --git a/tags/self-hosting/atom.xml b/tags/self-hosting/atom.xml new file mode 100644 index 0000000..881be5a --- /dev/null +++ b/tags/self-hosting/atom.xml @@ -0,0 +1,367 @@ + + + - self-hosting + + + Zola + 2022-09-10T00:00:00+00:00 + https://librepages.org/tags/self-hosting/atom.xml + + How to deploy a website WITHOUT LibrePages + 2022-09-10T00:00:00+00:00 + 2022-09-10T00:00:00+00:00 + + https://librepages.org/blog/2022-09-10-how-to-publish-website-without-librepages/ + <p>In this <del>blog post</del> tutorial, I'll show you how to deploy a personal +website. LibrePages automates everything that is discussed in this +tutorial and lets you focus on creating content. Automation is good +but knowing how to do it manually using industry standard +technologies always helps!</p> +<p>We will be using the following technologies to deploy our website:</p> +<ol> +<li>GNU/Linux server(Debian)</li> +<li>Nginx (webs server)</li> +<li>Let's Encrypt (for HTTPS)</li> +<li>Gitea (but any Git hosting works)</li> +</ol> +<p>Let's get started!</p> +<h2 id="1-setup-debian-gnu-linux">1. Setup Debian GNU/Linux<a class="zola-anchor" href="#1-setup-debian-gnu-linux" aria-label="Anchor link for: 1-setup-debian-gnu-linux" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>We are going to start with a fresh GNU/Linux installation, you could get +one from a cloud provider like <a href="https://www.digitalocean.com">Digital +Ocean</a> (not affiliated).</p> +<h3 id="1-1-give-your-account-sudo-privileges">1.1) Give your account <code>sudo</code> privileges<a class="zola-anchor" href="#1-1-give-your-account-sudo-privileges" aria-label="Anchor link for: 1-1-give-your-account-sudo-privileges" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On GNU/Linux systems, the <code>root</code> account is the most powerful user account. +It is good practice to avoid working as <code>root</code> since a careless mistake +could wipe the entire system out.</p> +<p><code>sudo</code> give the ability to execute commands with <code>root</code> capabilities +from a lower-privileged account. Let's make our account sudo capable:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">su </span><span style="color:#65737e;"># become root +</span><span> +</span><span style="color:#65737e;"># add `realaravinth`, my account` to `sudo` group to be able to use `sudo` +</span><span style="color:#bf616a;">usermod -aG</span><span> sudo realaravinth </span><span style="color:#65737e;"># my account is called `realaravinth`, replace it with yours +</span><span style="color:#96b5b4;">exit +</span><span style="color:#bf616a;">$</span><span> exit +</span></code></pre> +<p>Log out and log back in.</p> +<h3 id="1-2-install-and-setup-firewall-ufw">1.2) Install and setup firewall(<code>ufw</code>)<a class="zola-anchor" href="#1-2-install-and-setup-firewall-ufw" aria-label="Anchor link for: 1-2-install-and-setup-firewall-ufw" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Uncomplicated Firewall(<code>ufw</code>) is a popular firewall that is easy to +set up and maintain. For most installations, this should be enough. +System administrators use firewalls to open only the ports that they +think should receive traffic from external networks. Without it, all +ports will be open, causing a security nightmare.</p> +<p>We will require standard SSH (22), and the standard web ports (80 and +443). A comprehensive list of services and the list of ports the listen +on is available at `/etc/services.</p> +<pre data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt "><code class="language-bash $ sudo apt update && apt upgrade # update system $ sudo apt" data-lang="bash $ sudo apt update && apt upgrade # update system $ sudo apt"><span>install ufw # we are using `ufw` for the firewall +</span><span>$ sudo ufw allow ssh # allow SSH traffic on port 22, required to log into the server +</span><span>$ sudo ufw enable # deploy firewall +</span></code></pre> +<h3 id="1-3-secure-ssh">1.3) Secure SSH<a class="zola-anchor" href="#1-3-secure-ssh" aria-label="Anchor link for: 1-3-secure-ssh" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>SSH allows remote access to our servers over secure, encrypted +channels. By default, users can log in with their password +using SSH. But password authentication is susceptible to brute force attacks, so we should disable password logins on our server and only allow public-key authentication only.</p> +<h3 id="1-3-1-generate-key-pair">1.3.1) Generate key pair<a class="zola-anchor" href="#1-3-1-generate-key-pair" aria-label="Anchor link for: 1-3-1-generate-key-pair" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>On your local computer, generate an SSH key pair:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-keygen +</span><span style="color:#bf616a;">Generating</span><span> public/private rsa key pair. +</span><span style="color:#bf616a;">Enter</span><span> file in which to save the key (/home/realaravinth/.ssh/id_rsa)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> passphrase (empty for no passphrase)</span><span style="color:#96b5b4;">: +</span><span style="color:#bf616a;">Enter</span><span> same passphrase again: +</span><span style="color:#bf616a;">Your</span><span> identification has been saved in /home/realaravinth/.ssh/id_rsa +</span><span style="color:#bf616a;">Your</span><span> public key has been saved in /home/realaravinth/.ssh/id_rsa.pub +</span><span style="color:#bf616a;">The</span><span> key fingerprint is: +</span><span style="color:#bf616a;">SHA256:i2DE1b9BQb9DqV0r6O9MfPeVqUwfww1/T8wIXL2Xqdo</span><span> realaravinth@myserver.com +</span><span style="color:#bf616a;">The</span><span> key&#39;</span><span style="color:#a3be8c;">s random art image is: +</span><span style="color:#a3be8c;">+---[RSA 3072]----+ +</span><span style="color:#a3be8c;">| .. .o. | +</span><span style="color:#a3be8c;">| . . . .. . . | +</span><span style="color:#a3be8c;">| o o + o .| +</span><span style="color:#a3be8c;">| . o* + .+| +</span><span style="color:#a3be8c;">| o S ooB o+.| +</span><span style="color:#a3be8c;">| . . . o.. +o*=| +</span><span style="color:#a3be8c;">| . . . ooo*X| +</span><span style="color:#a3be8c;">| +=.ooB| +</span><span style="color:#a3be8c;">| o+E .o| +</span><span style="color:#a3be8c;">+----[SHA256]-----+ +</span></code></pre> +<p>Set a strong password the program prompts for one and save it somewhere +safe. Your public key will be at <code>~/.ssh/id_rsa.pub</code> and your private key at +<code>~/.ssh/id_rsa</code>. <strong>Never share the private key with anyone</strong>.</p> +<h3 id="1-3-2-setup-public-key-authentication">1.3.2) Setup public-key authentication<a class="zola-anchor" href="#1-3-2-setup-public-key-authentication" aria-label="Anchor link for: 1-3-2-setup-public-key-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We have to copy the public key that we generated in the previous setup +onto our server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> ssh-copy-id</span><span style="color:#bf616a;"> -i ~</span><span>/.ssh/id_rsa.pub myserver.com +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: Source of key(s) </span><span style="color:#bf616a;">to</span><span> be installed: &quot;</span><span style="color:#a3be8c;">/home/realaravinth/.ssh/id_rsa.pub</span><span>&quot; +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: attempting to log in with the new key(s)</span><span style="color:#bf616a;">,</span><span> to filter out any that are already installed +</span><span style="color:#bf616a;">/usr/bin/ssh-copy-id:</span><span> INFO: 1 key(s) </span><span style="color:#bf616a;">remain</span><span> to be installed -- if you are prompted now it is to install the new keys +</span><span style="color:#bf616a;">realaravinth@myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">s password: +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Number of key(s) added: 1 +</span><span style="color:#a3be8c;"> +</span><span style="color:#a3be8c;">Now try logging into the machine, with: &quot;ssh </span><span>&#39;</span><span style="color:#bf616a;">myserver.com</span><span>&#39;</span><span style="color:#a3be8c;">&quot; +</span><span style="color:#a3be8c;">and check to make sure that only the key(s) you wanted were added. +</span></code></pre> +<h3 id="1-3-3-disable-ssh-password-authentication">1.3.3) Disable SSH password authentication<a class="zola-anchor" href="#1-3-3-disable-ssh-password-authentication" aria-label="Anchor link for: 1-3-3-disable-ssh-password-authentication" + ><span class="anchor-icon">#</span></a +> +</h3> +<blockquote> +<p><strong>NOTE: Verify you can log into your account before proceeding</strong></p> +</blockquote> +<p>Now that we have a private-key authentication setup on both the client and +the server, let's disable password authentication on the server:</p> +<p>Open <code>/etc/ssh/sshd_config</code> and add the following lines:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>PubkeyAuthentication yes +</span><span>PasswordAuthentication no +</span></code></pre> +<p>And restart the SSH server:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl restart sshd +</span></code></pre> +<h3 id="1-3-install-and-setup-fail2ban">1.3) Install and setup <code>fail2ban</code><a class="zola-anchor" href="#1-3-install-and-setup-fail2ban" aria-label="Anchor link for: 1-3-install-and-setup-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>We will be using <code>fail2ban</code> for intrusion prevention by blackiisting entities (users, bots, etc.) based on failed login attempts.</p> +<h4 id="1-3-1-install-fail2ban">1.3.1) Install <code>fail2ban</code><a class="zola-anchor" href="#1-3-1-install-fail2ban" aria-label="Anchor link for: 1-3-1-install-fail2ban" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install fail2ban +</span></code></pre> +<h4 id="1-3-2-enable-fail2ban-for-sshd">1.3.2) Enable <code>fail2ban</code> for <code>sshd</code><a class="zola-anchor" href="#1-3-2-enable-fail2ban-for-sshd" aria-label="Anchor link for: 1-3-2-enable-fail2ban-for-sshd" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="yml" style="background-color:#2b303b;color:#c0c5ce;" class="language-yml "><code class="language-yml" data-lang="yml"><span>[</span><span style="color:#a3be8c;">sshd</span><span>] +</span><span style="color:#a3be8c;">enabled = true +</span></code></pre> +<h4 id="1-3-3-configure-fail2ban-to-start-on-boot">1.3.3) Configure <code>fail2ban</code> to start on boot<a class="zola-anchor" href="#1-3-3-configure-fail2ban-to-start-on-boot" aria-label="Anchor link for: 1-3-3-configure-fail2ban-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemctl enable fail2ban +</span><span style="color:#bf616a;">$</span><span> sudo systemctl start fail2ban +</span></code></pre> +<h3 id="1-4-install-and-setup-nginx">1.4) Install and setup <code>nginx</code><a class="zola-anchor" href="#1-4-install-and-setup-nginx" aria-label="Anchor link for: 1-4-install-and-setup-nginx" + ><span class="anchor-icon">#</span></a +> +</h3> +<p><code>nginx</code> is a popular web server that can be used to serve static sites. +It is fast, stable, and easy to set up.</p> +<p>To install, run the following command:</p> +<h4 id="1-4-1-install-nginx">1.4.1) Install <code>nginx</code>:<a class="zola-anchor" href="#1-4-1-install-nginx" aria-label="Anchor link for: 1-4-1-install-nginx" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install nginx +</span></code></pre> +<h4 id="1-4-2-allow-web-traffic-open-ports-80-and-443">1.4.2) Allow web traffic: open ports <code>80</code> and <code>443</code><a class="zola-anchor" href="#1-4-2-allow-web-traffic-open-ports-80-and-443" aria-label="Anchor link for: 1-4-2-allow-web-traffic-open-ports-80-and-443" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Ports <code>80</code> is the default for HTTP and <code>443</code> for HTTPS. To serve +web traffic, we'll have to Configure <code>ufw</code> to accept traffic on them:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ufw allow 80 </span><span style="color:#65737e;"># open ports 80 HTTP traffic +</span><span style="color:#bf616a;">$</span><span> sudo ufw allow 443 </span><span style="color:#65737e;"># open ports 443 for HTTPS traffic +</span></code></pre> +<h4 id="1-4-2-configure-nginx-to-start-on-boot">1.4.2) Configure <code>nginx</code> to start on boot<a class="zola-anchor" href="#1-4-2-configure-nginx-to-start-on-boot" aria-label="Anchor link for: 1-4-2-configure-nginx-to-start-on-boot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo systemtl enable nginx </span><span style="color:#65737e;"># automatically start nginx on boot +</span><span style="color:#bf616a;">$</span><span> sudo systemtl start nginx </span><span style="color:#65737e;"># start nginx server +</span></code></pre> +<p>And verify it works:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span>&lt;head&gt; +</span><span>&lt;title&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/title&gt; +</span><span>&lt;style&gt; +</span><span> </span><span style="color:#bf616a;">body </span><span>{ +</span><span> width: 35em; +</span><span> margin: 0 auto; +</span><span> font-family: Tahoma, Verdana, Arial, sans-serif; +</span><span> } +</span><span>&lt;/style&gt; +</span><span>&lt;/head&gt; +</span><span>&lt;body&gt; +</span><span>&lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> nginx!&lt;/h1&gt; +</span><span>&lt;p&gt;If </span><span style="color:#bf616a;">you</span><span> see this page, the nginx web server is successfully installed and +</span><span style="color:#bf616a;">working.</span><span> Further configuration is required.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;For </span><span style="color:#bf616a;">online</span><span> documentation and support please refer to +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.org/</span><span>&quot;&gt;nginx.org&lt;/a&gt;.&lt;br/&gt; +</span><span style="color:#bf616a;">Commercial</span><span> support is available at +</span><span>&lt;a </span><span style="color:#bf616a;">href</span><span>=&quot;</span><span style="color:#a3be8c;">http://nginx.com/</span><span>&quot;&gt;nginx.com&lt;/a&gt;.&lt;/p&gt; +</span><span> +</span><span>&lt;p&gt;&lt;em&gt;Thank </span><span style="color:#bf616a;">you</span><span> for using nginx.&lt;/em&gt;&lt;/p&gt; +</span><span>&lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<p><code>nginx</code> is working!</p> +<h2 id="2-deploy-website">2) Deploy website<a class="zola-anchor" href="#2-deploy-website" aria-label="Anchor link for: 2-deploy-website" + ><span class="anchor-icon">#</span></a +> +</h2> +<p>For this demo, we'll deploy a single file(<code>index.html</code>) +HTML website.</p> +<h3 id="2-1-install-the-webpage-on-the-server">2.1) Install the webpage on the server<a class="zola-anchor" href="#2-1-install-the-webpage-on-the-server" aria-label="Anchor link for: 2-1-install-the-webpage-on-the-server" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>Edit <code>/var/www/html/index.html</code> and add the following HTML to it:</p> +<pre data-lang="html" style="background-color:#2b303b;color:#c0c5ce;" class="language-html "><code class="language-html" data-lang="html"><span>&lt;!</span><span style="color:#b48ead;">DOCTYPE </span><span style="color:#d08770;">html</span><span>&gt; +</span><span>&lt;</span><span style="color:#bf616a;">html</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">title</span><span>&gt;My cool website!&lt;/</span><span style="color:#bf616a;">title</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">head</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span> &lt;</span><span style="color:#bf616a;">h1</span><span>&gt;Welcome to my website! o/&lt;/</span><span style="color:#bf616a;">h1</span><span>&gt; +</span><span> &lt;/</span><span style="color:#bf616a;">body</span><span>&gt; +</span><span>&lt;/</span><span style="color:#bf616a;">html</span><span>&gt; +</span></code></pre> +<p>The webpage should now be available on localhost, and we should see it when we run the following command:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> curl localhost +</span><span>&lt;!DOCTYPE </span><span style="color:#bf616a;">html</span><span>&gt; +</span><span>&lt;html&gt; +</span><span> &lt;head&gt; +</span><span> &lt;title&gt;My </span><span style="color:#bf616a;">cool</span><span> website!&lt;/title&gt; +</span><span> &lt;/head&gt; +</span><span> &lt;body&gt; +</span><span> &lt;h1&gt;Welcome </span><span style="color:#bf616a;">to</span><span> my website! o/&lt;/h1&gt; +</span><span> &lt;/body&gt; +</span><span>&lt;/html&gt; +</span></code></pre> +<h3 id="2-2-serve-webpage-on-a-custom-domain">2.2) Serve webpage on a custom domain<a class="zola-anchor" href="#2-2-serve-webpage-on-a-custom-domain" aria-label="Anchor link for: 2-2-serve-webpage-on-a-custom-domain" + ><span class="anchor-icon">#</span></a +> +</h3> +<h4 id="2-2-1-buy-a-domain-if-you-don-t-own-one-already">2.2.1) Buy a domain if you don't own one already<a class="zola-anchor" href="#2-2-1-buy-a-domain-if-you-don-t-own-one-already" aria-label="Anchor link for: 2-2-1-buy-a-domain-if-you-don-t-own-one-already" + ><span class="anchor-icon">#</span></a +> +</h4> +<h4 id="2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record">2.2.2) Go to the domain's DNS dashboard and add the following record<a class="zola-anchor" href="#2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" aria-label="Anchor link for: 2-2-2-go-to-the-domain-s-dns-dashboard-and-add-the-following-record" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>@ A 300 &lt;your server IP address&gt; +</span></code></pre> +<h4 id="2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain">2.2.3) Setup <code>nginx</code> to serve the website at <code>http://&lt;your-domain.</code><a class="zola-anchor" href="#2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" aria-label="Anchor link for: 2-2-3-setup-nginx-to-serve-the-website-at-http-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Open <code>/etc/nginx/sites-available/your-domain</code> and add the following:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>server { +</span><span> # serve website on port 80 +</span><span> listen [::]:80; +</span><span> listen 80; +</span><span> +</span><span> # write error logs to file +</span><span> error_log /var/log/nginx/&lt;your-domain&gt;.error.log; +</span><span> # write access logs to file +</span><span> access_log /var/log/nginx/&lt;your-domain&gt;.access.log; +</span><span> +</span><span> # serve only on this domain: +</span><span> server_name &lt;your-domain&gt;; # replace me +</span><span> +</span><span> +</span><span> # use files from this directory +</span><span> root /var/www/html/; +</span><span> +</span><span> # remove .html from URL; it is cleaner this way +</span><span> rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent; +</span><span> +</span><span> # when a request is received, try the index.html in the directory +</span><span> # or $uri.html +</span><span> try_files $uri/index.html $uri.html $uri/ $uri =404; +</span><span>} +</span></code></pre> +<p>It is good practice to have all <code>nginx</code> deployment configurations in +<code>/etc/nginx/sites-available/</code> directory and link production websites to +`/etc/nginx/sites-enabled directory. Doing so allows you to +work-in-progress configurations or delete deployments without losing +the configuration files.</p> +<p>Let's enable <code>&lt;your-domain&gt;</code></p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo ln</span><span style="color:#bf616a;"> -s</span><span> /etc/nginx/sites-available/&lt;your-domain&gt; /etc/nginx/sites-available/&lt;your-domain&gt; +</span></code></pre> +<p>Verify configurations before deploying, <code>nginx</code> has a command +to do it:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -t +</span></code></pre> +<p>If there are no errors, reload <code>nginx</code> to deploy the website:</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo nginx</span><span style="color:#bf616a;"> -s</span><span> reload +</span></code></pre> +<p>Your webpage should now be accessible at <code>http://&lt;your-domain&gt;</code>!</p> +<h3 id="2-3-install-certbot-to-set-up-https">2.3) Install <code>certbot</code> to set up HTTPS<a class="zola-anchor" href="#2-3-install-certbot-to-set-up-https" aria-label="Anchor link for: 2-3-install-certbot-to-set-up-https" + ><span class="anchor-icon">#</span></a +> +</h3> +<p>HTTP is insecure. We'll have to set up SSL to serve our website using +HTTPS. To do that, we will be using <a href="https://letsencrypt.org/">Let's +Encrypt</a> a popular nonprofit certificate +authority to get our SSL certificates.</p> +<p>SSL certificates come with set lifetimes, so we renew them before they expire. The process, when done manually, is demanding: you +will have to log in every three months and renew the +certificate. If you fail or forget it, your visitors will see security +warnings on your website.</p> +<p>Thankfully, Let's Encrypt provides automation through <code>certbot</code></p> +<h4 id="2-3-1-install-certbot">2.3.1) Install <code>certbot</code>:<a class="zola-anchor" href="#2-3-1-install-certbot" aria-label="Anchor link for: 2-3-1-install-certbot" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo apt install certbot python3-certbot-nginx +</span></code></pre> +<h4 id="2-3-2-get-a-certificate-for-your-domain">2.3.2) Get a certificate for <code>&lt;your-domain&gt;</code><a class="zola-anchor" href="#2-3-2-get-a-certificate-for-your-domain" aria-label="Anchor link for: 2-3-2-get-a-certificate-for-your-domain" + ><span class="anchor-icon">#</span></a +> +</h4> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> sudo certbot</span><span style="color:#bf616a;"> --nginx -d </span><span>&lt;your-domain&gt; +</span></code></pre> +<p><code>certbot</code> will prompt you for an email ID, and ask you to accept their +terms and conditions, privacy policy, etc. Be sure to read them before +agreeing to them. It will then try to authenticate your domain ownership +using the <a href="https://en.wikipedia.org/wiki/Automatic_Certificate_Management_Environment">ACME +protocol</a>. +By configuring the DNS to point to our server and by telling <code>nginx</code> at +that domain.</p> +<p>When it has verified ownership, it will automatically issue, deploy the +certificate on <code>nginx</code> and setup redirects.</p> +<h4 id="2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals">2.3.3) Setup cronjob to automate SSL certificate renewals<a class="zola-anchor" href="#2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" aria-label="Anchor link for: 2-3-3-setup-cronjob-to-automate-ssl-certificate-renewals" + ><span class="anchor-icon">#</span></a +> +</h4> +<p>Become root and edit crontab</p> +<pre data-lang="bash" style="background-color:#2b303b;color:#c0c5ce;" class="language-bash "><code class="language-bash" data-lang="bash"><span style="color:#bf616a;">$</span><span> su +</span><span style="color:#bf616a;">crontab -e +</span></code></pre> +<p>Add the following job and exit:</p> +<pre style="background-color:#2b303b;color:#c0c5ce;"><code><span>0 */12 * * * certbot -n --nginx renew +</span></code></pre> +<p>It will attempt to renew SSL certificates every 12 hours. If a the +certificate is due for renewal, <code>certbot</code> will go through the ACME +challenge, get the new certificates and automatically deploy them for +you.</p> +<p>Now our GNU/Linux server is configured and ready to serve our website at +<code>http://&lt;your-website&gt;</code>!</p> + + + diff --git a/tags/self-hosting/index.html b/tags/self-hosting/index.html new file mode 100644 index 0000000..41f8ff2 --- /dev/null +++ b/tags/self-hosting/index.html @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + self-hosting | LibrePages: JAMstack platform with focus on privacy and speed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +