[~] BACK



~~ HIY (III) ~~

** WEBSERVER **

[HOW] | [20230227] | [0] | [0x17]




After the structure and the requirements have been clarified, it's now time to go to the terminal. NixOS is running on the Hetzner box and is basically waiting to do something. So let's give it what it wants and build the NGINX server for the domains including TLS/SSL. In principle, three domains should run on the server. Of course, the NERDBUDE, the Click! Clack! Hack! and of course the Damn Fine Keyboards. Before the move, these websites were anchored in the NERDBUDE file tree. This should of course no longer be the case, but the websites should be hosted completely independently of each other. To do this, the CCH! and the DFK must of course be scraped out of the NERDBUDE in advance. I've done that - so now I have three independent website structures and I can get started.

WEBSITESTRUCTURE


First, all the HTML files have to be put on the server. I think the default directory for this is /var/www/$websitename/. So the individual structures are pushed onto the server via scp. Of course, $websitename is replaced with the actual domain name - so /var/www/clickclackhack/. Yeah - the content is already there. Now we just have to tell NGINX that the content is there too.

CONFIGURATION.NIX

The configuration is usually quite simple and done quickly. However, I made a mistake. My brain is still trained to configure tools in individual config files. But we don't do that under NixOS and, conveniently, there are also error messages that tell you that everything is "read-only". At some point my brain will remember that we want to define everything in configuration.nix. So let's go into configuratio.nix. Basically, the functioning configuration.nix looks like this. Don't worry, I'll go through it step by step.


configuration.nix
    { config, pkgs, ... }:
    let release = "nixos-21.11";
    in  {
      imports = [
        ./hardware-configuration.nix
    		})
    
        ];
    
    ### WEB SERVER
    
     services.nginx = {
    	enable = true;
    	virtualHosts."damnfinekeyboards.com" = {
    		enableACME = true;
    		forceSSL = true;
    		root = "/var/www/damnfinekeyboards/";
    		};
    	virtualHosts."nerdbude.com" = {
    		enableACME = true;
    		forceSSL = true;
    		root = "/var/www/nerdbude/";
    		};
    	virtualHosts."clickclackhack.de" = {
    		enableACME = true;
    		forceSSL = true;
    		root = "/var/www/clickclackhack/";
    		};
    	};
    	};
    
      security.acme.acceptTerms = true;
      security.acme.certs = {
    	"testbude.space".email = "post@testbude.space";
    	"damnfinekeyboards.com".email = "info@damnfinekeyboards.com";
    	"www.damnfinekeyboards.com".email = "info@damnfinekeyboards.com";
    	"nerdbude.com".email = "post@nerdbude.com";
    	"www.nerdbude.com".email = "post@nerdbude.com";
    	"clickclackhack.de".email = "info@clickclackhack.de";
    	"www.clickclackhack.de".email = "info@clickclackhack.de";
    	};
    
      boot.cleanTmpDir = true;
      zramSwap.enable = true;
      networking.hostName = "nb-main";
      networking.domain = "";
      services.openssh.enable = true;
      networking.firewall = {
    	enable = true;
    	allowedTCPPorts = [ 22 25 80 443 ];
    	allowedUDPPortRanges = [
    	  { from = 4000; to = 4007; }
    	  { from = 8000; to = 8010; }
            ];
    };
    
    ### SSH CERT FOR REMOTE ACCESS
    
      users.users.root.openssh.authorizedKeys.keys = [
        "ssh-rsa XXX"
      ];
    
    ### TOOLCHAIN
    
      environment.systemPackages = with pkgs; [
    
    	vim
    	git
    	unzip
    	openssl
    	goaccess
    	chkrootkit
    	service-wrapper
      ];
    }
  


That's it. The complete config. OK, let's go through the stuff.
At the very beginning is the usual NixOS config and the linked external hardware-configuration.nix - I'll skip that part and start at the bottom. In the lower part of the configuration.nix you will find the tools that we want to install on the server or should install so that everything works. I decided to keep the whole thing clear and minimalistic. The fewer tools that run on the server, the less surface they offer for attack. The tools that run on the server are the following:


configuration.nix
    ### TOOLCHAIN
    
      environment.systemPackages = with pkgs; [
    
    	vim
    	git
    	unzip
    	openssl
    	goaccess
    	chkrootkit
    	service-wrapper
      ];
  


I think the list is self-explanatory. Vim as a text editor, git as a version management tool, unzip if something needs to be unpacked, openssl for SSL certificate stuff, goaccess is a pretty cool tool for live log analysis, chkrootkit as a tool for checking whether there are rootkits on the server. The reason for this is as follows: As soon as a server goes online somewhere, there are a few shady characters who start messing with it. There was also strange activity on the $NB_MAIN (that's what the Hetzner box is called, by the way) right on top of the installation. service-wrapper is the interface adapter for systemctl commands. [EDIT] fleaz gave me the tip that "nginx" does not need to be installed additionally via the "systemPackages" because the configuration.nix takes care of installing NGINX together with the NGINX configuration. So it is completely unnecessary at this point.
The tools are installed. Now let's move on to the NGINX configuration.

NGINX


NGINX is our web server. It takes care of linking the content, i.e. the .html files of the website, with the domains and also generates SSL certificates for them. The linking to the domains happens in this section:


configuration.nix
     services.nginx = {
    	enable = true;
    	virtualHosts."nerdbude.com" = {
        enableACME = true;
    		forceSSL = true;
    		root = "/var/www/nerdbude/";
    		};
  


The first two lines start NGINX as a web server.
The website is initialized with "virtualHosts." and basic parameters are also specified here. So that NGINX also knows which domain should point to which content, we also specify the website as a parameter, i.e. virtualHosts."nerbude.com". Under this virtual host we also specify the instruction for generating the SSL certificates. This is regulated by enableACME = true; and so that only SSL is used we also add forceSSL = true;. Finally, we define the path to the .html files with root = "/var/www/nerdbude/";. This is basically enough for NGINX to deliver the website. The redundancy of the websites for the versions with and without "www" does not need to be a "virtualHosts" entry. A redirect from one version to the other is sufficient here. [Thanks fleaz!] Since SSL still requires a contact email, we include it in the following section:


configuration.nix
      security.acme.acceptTerms = true;
      security.acme.certs = {
    	"nerdbude.com".email = "post@nerdbude.com";
    	"www.nerdbude.com".email = "post@nerdbude.com";
    	};
  


These are the basic configurations for the domains including SSL certificates. NixOS generates the SSL certificates completely automatically. It can take a while until they are recognized; for me it took between 10 and 15 minutes. So it's totally bearable. Now we should give NGINX a few general parameters.


configuration.nix
      boot.cleanTmpDir = true;
      zramSwap.enable = true;
      networking.hostName = "nb-main";
      networking.domain = "";
      services.openssh.enable = true;
      networking.firewall = {
    	enable = true;
    	allowedTCPPorts = [ 22 25 80 443 ];
    	allowedUDPPortRanges = [
    	  { from = 4000; to = 4007; }
    	  { from = 8000; to = 8010; }
            ];
    };
    
    ### SSH CERT FOR REMOTE ACCESS
    
      users.users.root.openssh.authorizedKeys.keys = [
        "ssh-rsa XXX"
      ];
  


Firstly, we activate the SSH access with services.openssh.enable = true; and activate the firewall and open a few ports. This happens here and is relatively self-explanatory:


configuration.nix
      networking.firewall = {
    	enable = true;
    	allowedTCPPorts = [ 22 25 80 443 ];
    	allowedUDPPortRanges = [
    	  { from = 4000; to = 4007; }
    	  { from = 8000; to = 8010; }
            ];
    };
  


The firewall is activated with enable = true; and under allowedTCPPorts = [ 22 25 80 443 ]; we tell the firewall the ports it should allow through. Finally, we leave our SSH key in the configuration.nix and send it to the server via SSH.


configuration.nix
      users.users.root.openssh.authorizedKeys.keys = [
        "ssh-rsa XXX"
      ];
  


The SSH key comes from the installation of NixOS that I described HERE. You can of course store other keys here. Of course you have to replace XXX with your key. After you have carried out the obligatory nixos-rebuild switch your web server should be running. The next part is about the domains themselves. They still need to be forwarded to your server.

BONUS: 301 REDIRECT


Currently, clickclackhack.de and damnfinekeyboards.com are already running on the NixOS server. However, NERDBUDE is not. The simple reason for this is that the podcast feed is in the NERDBUDE structure. If I were to simply move now, your podcatchers would no longer receive any new episodes. That's why the feed gets a 301 redirect that tells all clients that the feed has permanently moved to a new address. The whole thing is regulated by the .htaccess file, which is stored in the structure with the old provider. The .htaccess looks like this:


.htaccess
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^podcast/feed/feed.xml https://www.clickclackhack.de/feed/feed.xml [L,R=301]
    </IfModule>
  


As soon as a client (browser, feed reader, podcatcher) wants to access the feed, it is told to please use the new one. I'll let it run for a while so that everyone gets the new feed and when that's finished, the NERDBUDE will finally move to the NixOS server.

On the NixOS server we set up something similar for the "www" redirect (if anyone of you knows how to integrate this into the configuration.nix, write to me and I'll include it here):

.htaccess
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^https://www.clickclackhack.de https://clickclackhack.de [L,R=301]
    </IfModule>
  


PARTS:
[01] - Intro
[02] - Requirements
[03] - Webserver
[04] - Mailserver



EDIT:
[2023-02-27] - remove nginx from systempackages / redirect websites [fleaz]
[~] BACK