Title: Making a home NAS using NixOS
       Author: Solène
       Date: 18 October 2020
       Tags: nixos linux nas
       Description: 
       
       Still playing with [NixOS](https://nixos.org/), I wanted to experience
       how difficult it would be to write a NixOS configuration file to
       turn a computer into a simple NAS with basics features: samba
       storage, dlna server and auto suspend/resume.
       
       What is [NixOS](https://nixos.org/features.html)? As a reminder for
       some and introduction to the others, NixOS is a Linux distribution
       built by the Nix package manager, which make it very different than
       any other operating system out there, except
       [Guix](https://guix.gnu.org/)
       which has a similar approach with their own package manager written
       in Scheme.
       
       NixOS uses a declarative configuration approach along with lot of
       others features derived from Nix. What's big here is you no longer
       tweak anything in `/etc` or install packages, you can define the
       working state of the system in one configuration file. This system
       is a totally different beast than the others OS and require some
       time to understand how it work. Good news though, **everything**
       is documented in the man page `configuration.nix`, from fstab
       configuration to users managements or how to enable samba!
       
       Here is the `/etc/nixos/configuration.nix` file on my NAS.
       
       It enables ssh server, samba, minidlna and vnstat. Set up a user
       with my ssh public key. Ready to work.
       
       Using `rtcwake` command (Linux specific), it's possible to put
       the system into standby mode and schedule an auto resume after
       some time. This is triggered by a cron job at 01h00.
       
           { config, pkgs, ... }:
           {
             # include stuff related to hardware, auto generated at install
             imports = [ ./hardware-configuration.nix ];
             boot.loader.grub.device = "/dev/sda";
       
             networking.interfaces.enp3s0.ipv4.addresses = [ {
               address = "192.168.42.150";
               prefixLength = 24;
             } ];
             networking.defaultGateway = "192.168.42.1";
             networking.nameservers = [ "192.168.42.231" ];
       
             i18n.defaultLocale = "fr_FR.UTF-8";
             console = { font = "Lat2-Terminus16"; keyMap = "fr"; };
             time.timeZone = "Europe/Paris";
       
             environment.systemPackages = with pkgs; [
               kakoune vnstat borgbackup utillinux
             ];
       
             networking.firewall.enable = false;
       
             services.openssh.enable = true;
             services.vnstat.enable = true;
       
             services.cron.systemCronJobs = [
                 "0 1 * * * root rtcwake -m mem --date +6h"
             ]; 
       
             services.samba.enable = true;
             services.samba.enableNmbd = true;
             services.samba.extraConfig = ''
                   workgroup = WORKGROUP
                   server string = Samba Server
                   server role = standalone server
                   log file = /var/log/samba/smbd.%m
                   max log size = 50
                   dns proxy = no
                   map to guest = Bad User
               '';
             services.samba.shares = {
                 public = {
                     path = "/home/public";
                     browseable = "yes";
                     "writable" = "yes";
                     "guest ok" = "yes";
                     "public" = "yes";
                     "force user" = "share";
                   };
                };
       
             services.minidlna.enable = true;
             services.minidlna.announceInterval = 60;
             services.minidlna.friendlyName = "Rorqual";
             services.minidlna.mediaDirs = ["A,/home/public/Musique/"
       "V,/home/public/Videos/"];
       
             # note that tmpfiles are not necesserarly temporary if you don't
             # set an expire time. Trick given on irc by someone I forgot the
       name..
             systemd.tmpfiles.rules = [ "d /home/public 0755 share users" ];
       
             users.users.solene = {
               isNormalUser = true;
               extraGroups = [ "wheel" "sudo" ];
               openssh.authorizedKeys.keys = [
                     "ssh-ed25519
       AAAAC3NzaC1lZDI1NTE5AAAAIOIZKLFQXVM15viQXHYRjGqE4LLfvETMkjjgSz0mzMzS
       personal"
                     "ssh-ed25519
       AAAAC3NzaC1lZDI1NTE5AAAAIOIZKLFQXVM15vAQXBYRjGqE6L1fvETMkjjgSz0mxMzS
       pro"
               ];
             };
       
             # I prefer a dedicated one than "nobody"
             # can't log into it
             users.users.share= {
               isNormalUser = false;
             };
           }