This commit is contained in:
mtgmonkey 2025-06-08 13:11:14 +00:00
commit f7d48d286a
16 changed files with 519 additions and 0 deletions

66
configuration.nix Executable file
View file

@ -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;
}

96
flake.lock generated Executable file
View file

@ -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
}

38
flake.nix Executable file
View file

@ -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
];
};
};
}

36
hardware-configuration.nix Executable file
View file

@ -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.<interface>.useDHCP`.
networking.useDHCP = lib.mkDefault true;
# networking.interfaces.ens18.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
}

26
services/blog.nix Executable file
View file

@ -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";
};
}

62
services/elmskell.nix Executable file
View file

@ -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;
};
}
];
};
};
};
}

BIN
services/elmskell/elmskell Executable file

Binary file not shown.

52
services/ferron.nix Executable file
View file

@ -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";
};
}

View file

@ -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);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<link rel="stylesheet" href="css/style.css">
<title>Ferron is installed successfully! 🥳</title>
</head>
<body>
<header>
<span class="logo"></span>
<h1>Ferron is installed successfully! 🥳</h1>
</header>
<section class="column">
<h2>If you're just visiting this website</h2>
<p>Thank you for visiting my website! It is not running yet. Contact me on Matrix @mtgmonkey:calitabby.net for a shoutout!</p>
<p><strong>Ferron probably has nothing to do with this website or its content, it just provides the
software for the website to run.</strong> If you have issues with this website, contact the
administrator of the website, not Ferron.</p>
</section>
<section class="column">
<h2>If you're an administrator of this website</h2>
<p>This page means that the web server's installation is successful. You can now add contents of the website to
the webroot directory (<i>/var/www/ferron</i> if installed using Ferron installer for GNU/Linux or via
Docker, or <i>%SystemDrive%\ferron\wwwroot</i> if installed using Ferron installer for Windows).</p>
<p>You can configure your web server according to <a href="https://www.ferronweb.org/docs">Ferron's
documentation.</a></p>
<p><strong>Thank you for installing Ferron!</strong></p>
</section>
<div class="clearfix"></div>
</body>
</html>

7
services/mattermost.nix Executable file
View file

@ -0,0 +1,7 @@
{
services.mattermost = {
enable = true;
siteUrl = "https://chat.mtgmonkey.net";
port = 9780;
};
}

23
services/rgit.nix Executable file
View file

@ -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";
};
};
}

4
ssh-pub-keys.nix Normal file
View file

@ -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''
]