commit f7d48d286ab11e6abb5453cef30382bf907d869c Author: mtgmonkey Date: Sun Jun 8 13:11:14 2025 +0000 init diff --git a/configuration.nix b/configuration.nix new file mode 100755 index 0000000..925556d --- /dev/null +++ b/configuration.nix @@ -0,0 +1,66 @@ +{pkgs, ...}: let + ssh-pub-keys = import ./ssh-pub-keys.nix; +in { + imports = [ + ./hardware-configuration.nix + ]; + + boot.tmp.cleanOnBoot = true; + networking.hostName = "server"; + networking.domain = ""; + networking.firewall = { + enable = true; + allowedTCPPorts = [80 443]; + }; + boot.loader.grub.devices = ["nodev"]; + + services.openssh = { + enable = true; + allowSFTP = false; + ports = [5522]; + settings = { + PermitRootLogin = "no"; + PasswordAuthentication = false; + KbdInteractiveAuthentication = true; + }; + extraConfig = '' + AllowTcpForwarding no + AllowAgentForwarding no + MaxAuthTries 3 + MaxSessions 4 + TCPKeepAlive no + ''; + }; + + services.fail2ban = { + enable = true; + maxretry = 10; + bantime-increment.enable = true; + }; + + users.users.mtgmonkey = { + isNormalUser = true; + description = "mtgmonkey"; + extraGroups = ["wheel"]; + openssh.authorizedKeys.keys = ssh-pub-keys; + }; + + users.users.git = { + isSystemUser = true; + group = "git"; + description = "git"; + home = "/var/lib/git-server"; + createHome = true; + packages = [pkgs.git]; + shell = pkgs.bash; + openssh.authorizedKeys.keys = ssh-pub-keys; + }; + + users.groups.git = {}; + + system.stateVersion = "23.11"; + + nix.settings.experimental-features = ["nix-command" "flakes"]; + + nix.settings.allow-import-from-derivation = true; +} diff --git a/flake.lock b/flake.lock new file mode 100755 index 0000000..a7ed9d2 --- /dev/null +++ b/flake.lock @@ -0,0 +1,96 @@ +{ + "nodes": { + "elmskell-blog": { + "inputs": { + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1749377392, + "narHash": "sha256-h9XPJ30WwPelj9U5lfwxePs8Mb408egKFszG635StGY=", + "ref": "refs/heads/master", + "rev": "255615b8389f480c4ea3ce647f9d2ed792916c08", + "revCount": 6, + "type": "git", + "url": "file:///var/lib/git-server/blog.git" + }, + "original": { + "type": "git", + "url": "file:///var/lib/git-server/blog.git" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1749143949, + "narHash": "sha256-QuUtALJpVrPnPeozlUG/y+oIMSLdptHxb3GK6cpSVhA=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "d3d2d80a2191a73d1e86456a751b83aa13085d7d", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-unstable", + "type": "indirect" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1749373575, + "narHash": "sha256-/3nvhGaUMG1A6zG185QHyTFR2fMiyffxU7VdMYk5qj0=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "6a8d437617048567166f83b32d07ba73aeb2d125", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "release-25.05", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1714253743, + "narHash": "sha256-mdTQw2XlariysyScCv2tTE45QSU9v/ezLcHJ22f0Nxc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "58a1abdbae3217ca6b702f03d3b35125d88a2994", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "noshell": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1717396029, + "narHash": "sha256-NPIhvnTYkJZqTY+aabbZ6CAaMAgG6IISvh7GZo1MTfQ=", + "owner": "viperML", + "repo": "noshell", + "rev": "4d194d838a50ea106cd0e47c024e47afc154ab42", + "type": "github" + }, + "original": { + "owner": "viperML", + "repo": "noshell", + "type": "github" + } + }, + "root": { + "inputs": { + "elmskell-blog": "elmskell-blog", + "nixpkgs": "nixpkgs_2", + "noshell": "noshell" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100755 index 0000000..f882e40 --- /dev/null +++ b/flake.nix @@ -0,0 +1,38 @@ +{ + description = "server flake"; + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/release-25.05"; + noshell.url = "github:viperML/noshell"; + elmskell-blog.url = "git+file:///var/lib/git-server/blog.git"; + }; + + outputs = { + self, + nixpkgs, + noshell, + elmskell-blog, + ... + }: let + system = "x86_64-linux"; + in { + nixosConfigurations."server" = nixpkgs.lib.nixosSystem { + inherit system; + specialArgs = { + inherit self; + inherit system; + inherit elmskell-blog; + }; + modules = [ + ./services/elmskell.nix + ./services/ferron.nix + ./services/rgit.nix + # ./services/mattermost.nix + + noshell.nixosModules.default + {programs.noshell.enable = true;} + + ./configuration.nix + ]; + }; + }; +} diff --git a/hardware-configuration.nix b/hardware-configuration.nix new file mode 100755 index 0000000..7b6e945 --- /dev/null +++ b/hardware-configuration.nix @@ -0,0 +1,36 @@ +# Do not modify this file! It was generated by ‘nixos-generate-config’ +# and may be overwritten by future invocations. Please make changes +# to /etc/nixos/configuration.nix instead. +{ config, lib, pkgs, modulesPath, ... }: + +{ + imports = + [ (modulesPath + "/profiles/qemu-guest.nix") + ]; + + boot.initrd.availableKernelModules = [ "ata_piix" "uhci_hcd" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = + { device = "/dev/disk/by-uuid/6b481376-9716-4559-946b-62097c2380f1"; + fsType = "ext4"; + }; + + fileSystems."/efi" = + { device = "systemd-1"; + fsType = "autofs"; + }; + + swapDevices = [ ]; + + # Enables DHCP on each ethernet and wireless interface. In case of scripted networking + # (the default) this is the recommended approach. When using systemd-networkd it's + # still possible to use this option, but it's recommended to use it in conjunction + # with explicit per-interface declarations with `networking.interfaces..useDHCP`. + networking.useDHCP = lib.mkDefault true; + # networking.interfaces.ens18.useDHCP = lib.mkDefault true; + + nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux"; +} diff --git a/services/blog.nix b/services/blog.nix new file mode 100755 index 0000000..7ff9d9a --- /dev/null +++ b/services/blog.nix @@ -0,0 +1,26 @@ +{ + elmskell-blog, + lib, + pkgs, + ... +}: let + ferron-conf-nix = { + global = { + secure = false; + wwwroot = "${elmskell-blog.packages.x86_64-linux.default}/wwwroot"; + }; + }; +in { + systemd.services.ferron = { + serviceConfig = { + Type = "simple"; + ExecStart = "${lib.getExe pkgs.ferron} --config=/etc/ferron.yaml"; + RemainAfterExit = true; + }; + }; + + environment.etc."ferron.yaml" = { + source = (pkgs.formats.yaml {}).generate "" ferron-conf-nix; + mode = "644"; + }; +} diff --git a/services/elmskell.nix b/services/elmskell.nix new file mode 100755 index 0000000..86d154b --- /dev/null +++ b/services/elmskell.nix @@ -0,0 +1,62 @@ +{pkgs, ...}: let + botPolicies-nix = { + dnsbl = false; + status_codes = { + CHALLENGE = 200; + DENY = 200; + }; + bots = [ + { + name = "catch-everything"; + user_agent_regex = ".*"; + action = "CHALLENGE"; + } + ]; + }; +in { + services.anubis = { + instances.elmskell = { + enable = true; + settings = { + BIND = "[::1]:9080"; + BIND_NETWORK = "tcp"; + DIFFICULTY = 4; + METRICS_BIND = "[::1]:9081"; + METRICS_BIND_NETWORK = "tcp"; + POLICY_FNAME = "/etc/anubis/elmskell.botPolicies.yaml"; + TARGET = "http://localhost:8080"; + }; + }; + }; + + environment.etc."anubis/elmskell.botPolicies.yaml" = { + source = (pkgs.formats.yaml {}).generate "" botPolicies-nix; + mode = "644"; + }; + + systemd.services.elmskell = { + serviceConfig = { + Type = "simple"; + ExecStart = "/etc/nixos/services/elmskell/elmskell"; + RemainAfterExit = true; + }; + }; + services.tor = { + enable = true; + enableGeoIP = false; + relay.onionServices = { + elmskell = { + version = 3; + map = [ + { + port = 80; + target = { + addr = "127.0.0.1"; + port = 8080; + }; + } + ]; + }; + }; + }; +} diff --git a/services/elmskell/elmskell b/services/elmskell/elmskell new file mode 100755 index 0000000..3474c1d Binary files /dev/null and b/services/elmskell/elmskell differ diff --git a/services/ferron.nix b/services/ferron.nix new file mode 100755 index 0000000..7efce7c --- /dev/null +++ b/services/ferron.nix @@ -0,0 +1,52 @@ +{ + elmskell-blog, + lib, + pkgs, + ... +}: let + ferron-conf-nix = { + global = { + secure = true; + enableAutomaticTLS = true; + automaticTLSContactCacheDirectory = "/etc/ferron/contactCacheDir"; + useAutomaticTLSHTTPChallenge = true; + disableProxyCertificateVerification = true; + loadModules = ["rproxy"]; + }; + hosts = [ + { + domain = "mtgmonkey.net"; + proxyTo = "http://localhost:9080/"; + } + { + domain = "blog.mtgmonkey.net"; + proxyTo = "http://localhost:9181/"; + } + { + domain = "git.mtgmonkey.net"; + proxyTo = "http://localhost:8000/"; + } + { + domain = "chat.mtgmonkey.net"; + proxyTo = "http://localhost:9780/"; + } + { + domain = "www.mtgmonkey.net"; + proxyTo = "http://localhost:9080/"; + } + ]; + }; +in { + systemd.services.ferron = { + serviceConfig = { + Type = "simple"; + ExecStart = "${lib.getExe pkgs.ferron} --config=/etc/ferron.yaml"; + RemainAfterExit = true; + }; + }; + + environment.etc."ferron.yaml" = { + source = (pkgs.formats.yaml {}).generate "" ferron-conf-nix; + mode = "644"; + }; +} diff --git a/services/ferron/wwwroot/css/style.css b/services/ferron/wwwroot/css/style.css new file mode 100755 index 0000000..0d1ca1d --- /dev/null +++ b/services/ferron/wwwroot/css/style.css @@ -0,0 +1,73 @@ +html, +body { + margin: 0; + padding: 0; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + background-color: #ffffff; + color: #0f172a; +} + +body { + margin: 2em auto; + padding: 1em; + box-sizing: border-box; + width: 100%; + max-width: 1280px; +} + +header { + text-align: center; +} + +.logo { + display: inline-block; + background-image: url(../img/logo.png); + background-size: 100%; + width: 160px; + height: 53.875px; +} + +.column { + width: 50%; + padding: 0.75em; + box-sizing: border-box; + float: left; +} + +.clearfix { + display: table; + clear: both; +} + +h1 { + font-size: 2.5em; +} + +a { + color: #ff4400; +} + +@media screen and (max-width: 512px) { + h1 { + font-size: 2em; + } + + .column { + float: none; + width: 100%; + padding: 0; + } +} + +@media screen and (prefers-color-scheme: dark) { + + html, + body { + background-color: #0c0a09; + color: #e1e7ef; + } + + .logo { + background-image: url(../img/logo-dark.png); + } +} \ No newline at end of file diff --git a/services/ferron/wwwroot/favicon.ico b/services/ferron/wwwroot/favicon.ico new file mode 100755 index 0000000..30a32fb Binary files /dev/null and b/services/ferron/wwwroot/favicon.ico differ diff --git a/services/ferron/wwwroot/img/logo-dark.png b/services/ferron/wwwroot/img/logo-dark.png new file mode 100755 index 0000000..768d509 Binary files /dev/null and b/services/ferron/wwwroot/img/logo-dark.png differ diff --git a/services/ferron/wwwroot/img/logo.png b/services/ferron/wwwroot/img/logo.png new file mode 100755 index 0000000..3661415 Binary files /dev/null and b/services/ferron/wwwroot/img/logo.png differ diff --git a/services/ferron/wwwroot/index.html b/services/ferron/wwwroot/index.html new file mode 100755 index 0000000..8490996 --- /dev/null +++ b/services/ferron/wwwroot/index.html @@ -0,0 +1,36 @@ + + + + + + + + + Ferron is installed successfully! 🥳 + + + +
+ +

Ferron is installed successfully! 🥳

+
+
+

If you're just visiting this website

+

Thank you for visiting my website! It is not running yet. Contact me on Matrix @mtgmonkey:calitabby.net for a shoutout!

+

Ferron probably has nothing to do with this website or its content, it just provides the + software for the website to run. If you have issues with this website, contact the + administrator of the website, not Ferron.

+
+
+

If you're an administrator of this website

+

This page means that the web server's installation is successful. You can now add contents of the website to + the webroot directory (/var/www/ferron if installed using Ferron installer for GNU/Linux or via + Docker, or %SystemDrive%\ferron\wwwroot if installed using Ferron installer for Windows).

+

You can configure your web server according to Ferron's + documentation.

+

Thank you for installing Ferron!

+
+
+ + + diff --git a/services/mattermost.nix b/services/mattermost.nix new file mode 100755 index 0000000..603bedb --- /dev/null +++ b/services/mattermost.nix @@ -0,0 +1,7 @@ +{ + services.mattermost = { + enable = true; + siteUrl = "https://chat.mtgmonkey.net"; + port = 9780; + }; +} diff --git a/services/rgit.nix b/services/rgit.nix new file mode 100755 index 0000000..96c628e --- /dev/null +++ b/services/rgit.nix @@ -0,0 +1,23 @@ +{ + virtualisation.docker = { + enable = true; + }; + virtualisation.oci-containers.backend = "docker"; + virtualisation.oci-containers.containers.rgit = { + image = "ghcr.io/w4/rgit:main"; + ports = [ + "8000:8000" + ]; + volumes = [ + "/var/lib/git-server:/git:ro" + ]; + cmd = [ + "[::]:8000" + "/git" + "-d /tmp/rgit-cache.db" + ]; + environment = { + REFRESH_INTERVAL = "5m"; + }; + }; +} diff --git a/ssh-pub-keys.nix b/ssh-pub-keys.nix new file mode 100644 index 0000000..2559ea3 --- /dev/null +++ b/ssh-pub-keys.nix @@ -0,0 +1,4 @@ +[ + ''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC379hc2EHmqvpA1LF2tDAxTyR3GGPdnuFTSJ9zgFxHKgCbraOMgDVDNeRWdJ3JrvBk+qI5yBvPaTTgLTS5iN6HbdmyerILkoszBX62u21vTIW4YfIS0VlNSZ0c1HUPZQsdSQNAYTlHKFVRXK1LtY6PMmEBok2O9KdymyXQqUkcrUj3JiCF2pPPUV4TXSoaBmt7IiuVHP+mLKyYW7YojwwHxVRHM1tYRvYVVCLM7oOgKV5IXlSAM4n27LS1ynx3SzG4oq8jYApPkdjSO4FkyqSFiM+FXYarucsMC78y9vN4CVB20vznn2Rcnk8FLZB+BZb8EioNJ7Mhyk3Ooa5fqMGjPFCmxFGzFDcRkcqCNj2/GwfMcNWtiCgFpb2pa3WW/suW1PXd4YSYuBUzkuK0A8Qh16rSmGTBQoIKTVGiCB6hW9vtxECDgEBNfnNaHYNaKwSyBrOq9iXJR3PAHINNw01CbW5/Bn8bdcggAkQXdiEhVLo2+XqAtUfsWlo4L1ndMZ0= mtgmonkey@nixos'' + ''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCyhHmoEAQ+LMnt1h8hk/e6By5YC/ujJU1/p7mqvq4qvC/JcH231bJKPW4n8YPDxLMdQSD/qZlEgAMnBIz8GtRcJznI+VjM9Qfq3+oJ8vvgG+9ZA8nqdTInj8q+vSJ2SMUZCW6kBfeG7Jx2fTMN8OGylWvwv8qLyawxc1bFkkm9j6BptzP0DSR4EeJvDNccYvcASvINHhqDOtEdCGMtmJE5NQ47KdtS4qWnCNKc2fvPPIyJcMtr8/hihrB0iOfxTqeuPWyLsal1sEKraxAqORsapudqHip6rsaTizhG48ZVUP8XHiL8gUI7qhc8sb6PxWBhALllGteVKQK9kzSerqaM7P6goZ7kw+WfZW4eQbto0GJCK8pDgmErQP5Uk3IsJSptJKc9foW2qkcoXY+2ABjQXhCUUXGyS2Gq8rp7AZ/Oh1zP67SGeee2F266BN799/jAym5awYUo2GGhh2LFGuADcnDKKQ5et/zQ6l1+4UH97JdDxNdQLf0rcdQ7TqC2Zuc= mtgmonkey@server'' +]