# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, pkgs, ... }:

{
  imports = [
    ../common-cli.nix
    ./hardware-configuration.nix
    ./users.nix
    ./services.nix
  ];

  nix.settings.trusted-users = [ "root" "paul" ];

  boot = {
    loader = {
      systemd-boot.enable = true;
      efi.canTouchEfiVariables = true;
    };

    supportedFilesystems = [ "zfs" ];

    tmp.useTmpfs = true;

    kernel.sysctl."net.ipv6.conf.all.forwarding" = true;
  };

  documentation.nixos.enable = false;

  services.zfs = {
    autoSnapshot.enable = true;
    autoScrub = {
      enable = true;
      interval = "monthly";
    };
  };

  hardware.usbWwan.enable = true;

  # eno1 -> VLAN100 -> Internet
  # eno2 -> LAN
  # eno3 -> Legacy client DHCP
  # eno4 -> Pas utilisé

  networking = {
    hostName = "loutreos"; # Define your hostname.
    hostId = "7e66e347";

    hosts = {
      "127.0.0.1" = [ "gitea.nyanlout.re" ];
    };

    useNetworkd = true;
    useDHCP = false;

    vlans = {
      bouygues = {
        id = 100;
        interface = "eno1";
      };
    };

    interfaces = {
      bouygues = {
        # Adresse MAC BBox ? https://lafibre.info/remplacer-bbox/informations-de-connexion-ftth/msg598303/#msg598303
        macAddress = "E8:AD:A6:21:73:68";
        useDHCP = true;
      };
      eno2 = {
        ipv4.addresses = [
          { address = "10.30.0.1"; prefixLength = 16; }
        ];
      };
      enp0s21u1.useDHCP = true;
    };

    # NAT bouygues <-> eno2
    nat = {
      enable = true;
      externalInterface = "bouygues";
      # Permet d'utiliser le SNAT plus rapide au lieu de MASQUERADE
      # externalIP = "0.0.0.0";
      internalIPs = [ "10.30.0.0/16" ];
      internalInterfaces = [ "eno2" ];
      forwardPorts = [
        { destination = "10.30.0.1:22"; proto = "tcp"; sourcePort = 8443;}
        { destination = "10.30.135.35:25565"; proto = "tcp"; sourcePort = 25565; loopbackIPs=[ "195.36.180.44" ];}
      ];
    };

    firewall = {
      enable = true;
      allowedTCPPorts = [ 80 443 ];
      allowedUDPPorts = [ ];
      interfaces.eno2 = {
        allowedTCPPorts = [
          111 2049 4000 4001 4002 # NFS
          3483 9000 9090 # Slimserver
          1935 # RTMP
        ];
        allowedUDPPorts = [
          111 2049 4000 4001 4002 # NFS
          3483 # Slimserver
          67 # DHCP
        ];
      };
      extraCommands = ''
        ip6tables -w -D FORWARD -j loutreos-forward 2>/dev/null || true
        ip6tables -w -F loutreos-forward 2>/dev/null || true
        ip6tables -w -X loutreos-forward 2>/dev/null || true
        ip6tables -w -N loutreos-forward
        ip6tables -A loutreos-forward -m state --state RELATED,ESTABLISHED -j ACCEPT
        ip6tables -A loutreos-forward -j ACCEPT -i eno2
        ip6tables -A loutreos-forward -j nixos-fw-log-refuse
        ip6tables -w -A FORWARD -j loutreos-forward

        # Redirect local network request from server external IP to internal IP
        # Make the server available even without internet access
        iptables -t nat -D PREROUTING -s 10.30.0.0/16 -d 176.180.172.105 -j DNAT --to 10.30.0.1 || true
        iptables -t nat -A PREROUTING -s 10.30.0.0/16 -d 176.180.172.105 -j DNAT --to 10.30.0.1
      '';
      # remove refs to nixos-fw-log-refuse before restarting firewall
      # prevents "ressource busy" errors
      extraStopCommands = ''
        ip6tables -D loutreos-forward -j nixos-fw-log-refuse 2>/dev/null || true
      '';
    };
  };

  systemd.network.networks = {
    "40-bouygues" = {
      dhcpV4Config.RouteMetric = 1;
      dhcpV6Config = {
        DUIDRawData = "00:03:00:01:E8:AD:A6:21:73:68";
        WithoutRA = "solicit";
      };
      ipv6AcceptRAConfig.DHCPv6Client = true;
      networkConfig = {
        KeepConfiguration = "dhcp-on-stop";
        IPv6AcceptRA = true;
        DHCPPrefixDelegation = true;
      };
      dhcpPrefixDelegationConfig.SubnetId = "0";
    };
    "40-eno1".linkConfig.RequiredForOnline = "no";
    "40-eno2" = {
      networkConfig = {
        IPv6SendRA = true;
        DHCPPrefixDelegation = true;
        DHCPServer = true;
      };
      dhcpServerConfig = {
        # MIN = 10.30.100.0
        #PoolOffset = 25500;
        # MAX = 10.30.200.0
        #PoolSize = 25500;
        EmitRouter = true;
        EmitDNS = true;
        DNS = [
          "1.1.1.1"
          "1.0.0.1"
        ];
      };
      dhcpServerStaticLeases = [
        # IPMI
        {
          dhcpServerStaticLeaseConfig = {
            Address = "10.30.1.1";
            MACAddress = "ac:1f:6b:4b:01:15";
          };
        }
        # paul-fixe
        {
          dhcpServerStaticLeaseConfig = {
            Address = "10.30.50.1";
            MACAddress = "b4:2e:99:ed:24:26";
          };
        }
        # salonled
        {
          dhcpServerStaticLeaseConfig = {
            Address = "10.30.40.1";
            MACAddress = "e0:98:06:85:e9:ce";
          };
        }
        # miroir-bleu
        {
          dhcpServerStaticLeaseConfig = {
            Address = "10.30.40.2";
            MACAddress = "e0:98:06:86:38:fc";
          };
        }
        # miroir-orange
        {
          dhcpServerStaticLeaseConfig = {
            Address = "10.30.40.3";
            MACAddress = "50:02:91:78:be:be";
          };
        }
      ];
      ipv6SendRAConfig = {
        EmitDNS = true;
        DNS = [
          "2606:4700:4700::1111"
          "2606:4700:4700::1001"
        ];
      };
    };
    "40-enp0s21u1".dhcpV4Config.RouteMetric = 1024;
  };

  nixpkgs.overlays = [
    (import ../../overlays/transmission.nix)
  ];

  services.openssh = {
    enable = true;
    settings = {
      PermitRootLogin = "no";
      PasswordAuthentication = false;
      X11Forwarding = true;
    };
  };

  users = {
    groups.autossh = { };
    users.autossh = {
      home = "/home/autossh";
      createHome = true;
      group = "autossh";
      isSystemUser = true;
    };
  };

  # Options explanations
  # -N                              disable shell
  # -R 0.0.0.0:2222:127.0.0.1:22    redirect SSH port on VPS server on port 2222
  # -R 127.0.0.1:2525:127.0.0.1:25  redirect SMTP port on VPS port 2525
  services.autossh.sessions = [
    {
      extraArguments = "-N -R 0.0.0.0:2222:127.0.0.1:22 loutre@vps772619.ovh.net";
      monitoringPort = 20000;
      name = "backup-ssh-reverse";
      user = "autossh";
    }
  ];

  virtualisation.podman.enable = true;

  security.sudo.wheelNeedsPassword = false;

  system.stateVersion = "18.03";
}