{ config, pkgs, lib, ... }:
{
imports = [
../modules/server
../modules/server/dns
../modules/server/irc
../modules/server/cgit
../modules/server/ftp
../modules/server/nginx
../modules/server/tor
../modules/server/xmpp
../modules/server/spectrum
../modules/users
];
boot.initrd.availableKernelModules = [ "xen_blkfront" ];
fileSystems = {
"/" = { device = "rpool/root"; fsType = "zfs"; neededForBoot = true; };
"/boot" = { device = "/dev/disk/by-partlabel/boot"; fsType = "ext4"; };
"/nix" = { device = "rpool/nix"; fsType = "zfs"; neededForBoot = true; };
"/var" = { device = "rpool/var"; fsType = "zfs"; };
"/home/qyliss" = { device = "rpool/home/qyliss"; fsType = "zfs"; };
"/root" = { device = "rpool/home/root"; fsType = "zfs"; };
};
systemd.enableEmergencyMode = false;
boot.zfs.devNodes = "/dev";
swapDevices = [
{ device = "/dev/disk/by-uuid/49f18b74-5f6e-4e61-b569-f7cc9dc5c600"; }
];
nix.maxJobs = 2;
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "nodev";
boot.loader.grub.configurationLimit = 2;
boot.supportedFilesystems = [ "zfs" ];
networking.hostName = "atuin";
networking.hostId = "238d1961";
networking.domain = "qyliss.net";
networking.interfaces.eth0 = {
ipv4.addresses = [
{ address = "85.119.82.108"; prefixLength = 21; }
];
ipv6.addresses = [
{ address = "2001:ba8:1f1:f0bc::2"; prefixLength = 64; }
];
};
networking.defaultGateway = "85.119.80.1";
networking.defaultGateway6 = { address = "2001:ba8:1f1:f0bc::1"; };
networking.dhcpcd.enable = false;
networking.firewall.allowedTCPPorts = [ 80 443 6697 ];
networking.firewall.extraCommands = ''
iptables -t nat -A POSTROUTING -s10.100.0.0/24 -j MASQUERADE
'';
boot.kernelPackages = pkgs.linuxPackages;
boot.kernelParams = [ "zfs.zfs_arc_max=356515840" ];
networking.nat.enable = true;
networking.nat.externalInterface = "eth0";
networking.nat.internalInterfaces = [ "wg0" ];
networking.firewall.allowedUDPPorts = with config; [
networking.wireguard.interfaces.wg0.listenPort
];
networking.wireguard.interfaces = {
wg0 = {
ips = [ "10.172.171.1" ];
listenPort = 51820;
privateKeyFile = "/var/lib/wireguard/wg0/private";
peers = [
{
publicKey = "oQZ3fcb9LsnQj8sDYLHf1+hodnW4XEhsM0rNBgHROz8=";
allowedIPs = [ "10.172.171.2/32" ];
}
{
publicKey = "lu4ZxYq7qpkmIt8z0Q/wb5Y0Wc3fa0ui9wOWn/+xYxI=";
allowedIPs = [ "10.172.171.3/32" ];
}
{
publicKey = "ugHG/NOqM/9hde9EmWpu7XsCpjT3WQbjLK99IGHtdjQ=";
allowedIPs = [ "10.13.12.0/24" ];
endpoint = "95.216.98.55:51820";
}
];
};
};
security.acme.acceptTerms = true;
security.acme.email = "hi@alyssa.is";
security.acme.certs =
with lib;
let
coalesce = maybe: default: if maybe == null then default else maybe;
toAttrs = val: if isList val then genAttrs val (_: null) else val;
vhostDomains = mapAttrsToList
(name: { serverName, ... }: coalesce serverName name)
config.services.nginx.virtualHosts;
domains = {
"qyliss.net" = {};
"spectrum-os.org" = { extraDomains = [ "spectrumos.org" ]; };
};
in
mapAttrs (
domain:
{ postRun ? "systemctl reload nginx.service"
, webroot ? "/var/lib/acme/acme-challenge"
, group ? "tls"
, allowKeysForGroup ? true
, extraDomains ? {}
, ...
} @ value:
let
extraDomainsFromVhosts =
toAttrs (filter (hasSuffix ".${domain}") vhostDomains);
in
value // {
inherit postRun webroot group allowKeysForGroup;
extraDomains = extraDomainsFromVhosts // (toAttrs extraDomains);
}
) domains;
users.groups.tls.members = [ "nginx" ];
users.users.qyliss.home = "/home/qyliss";
services.cgit.instances.qyliss = {
vhost = "git.qyliss.net";
config = pkgs.writeText "cgit.conf" ''
clone-prefix=https://git.qyliss.net
css=/cgit.css
enable-blame=1
enable-commit-graph=1
enable-follow-links=1
enable-git-config=1
enable-index-owner=0
enable-log-filecount=1
enable-log-linecount=1
remove-suffix=1
root-desc=Alyssa Ross's personal Git repositories
root-title=git.qyliss.net
snapshots=all
about-filter=${pkgs.cgit}/lib/cgit/filters/about-formatting.sh
source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py
virtual-root=/
scan-path=/home/qyliss/git
'';
};
services.nginx.virtualHosts =
let
vhosts = {
"znc.qyliss.net".locations."/".proxyPass = "http://127.0.0.1:6667/";
"spectrumos.org".locations."/".return = "301 https://spectrum-os.org/";
"www.spectrum-os.org".locations."/".return = "301 https://spectrum-os.org/";
"www.spectrumos.org".locations."/".return = "301 https://spectrum-os.org/";
"spectrum-os.org".locations = {
"/".root = "/home/spectrum/www";
"= /git/cgit.css".alias = cgitCss.outPath;
"= /lists/archives/public-inbox.css".alias = publicInboxCss.outPath;
"/lists/archives".proxyPass = "http://unix:/run/public-inbox-httpd.sock:/lists/archives";
"= /lists/archives".return = "301 /lists/archives/";
};
default = {
serverName = null;
default = true;
enableACME = false;
useACMEHost = "qyliss.net";
locations."/".return = "https://alyssa.is/";
locations."/dns-query".proxyPass = "http://[::1]:4448/";
};
"git.qyliss.net" = {
locations = {
"= /cgit.css".alias = cgitCss.outPath;
};
};
};
publicInboxCss = pkgs.runCommand "216light.css" {} ''
unpackFile ${pkgs.public-inbox.src}
cp */contrib/css/216light.css $out
'';
cgitCss = pkgs.runCommand "cgit-extra.css" {
licenseHeader = ''
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License v2 as published
* by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* See .
*/
'';
# Adapted from
# ,
# distributed as a Larger Work under a Secondary License,
# as permitted by the terms of the
# Mozilla Public License Version 2.0.
extraCss = ''
* { line-height: 1.25em; }
article {
font-family: sans-serif;
max-width: 70ch;
margin-left: auto;
margin-right: auto;
}
div#cgit {
margin: auto;
font-family: monospace;
-moz-tab-size: 4;
tab-size: 4;
display: table;
}
div#cgit table#header {
margin-left: auto;
margin-right: auto;
}
div#cgit table#header td.logo {
display: none;
}
div#cgit table#header td.main {
font-size: 1em;
font-weight: bold;
}
div#cgit table#header td.sub {
border-top: none;
}
div#cgit table.tabs {
margin-left: auto;
margin-right: auto;
border-bottom: none;
}
div#cgit div.content {
border-bottom: none;
min-width: 108ch;
}
div#cgit div.content div#summary {
display: table;
margin-left: auto;
margin-right: auto;
}
div#cgit div.notes {
border: none;
background: transparent;
padding: 0;
}
div#cgit table.list {
margin-left: auto;
margin-right: auto;
}
div#cgit table.list th a {
color: inherit;
}
div#cgit table.list tr:nth-child(even) {
background: inherit;
}
div#cgit table.list tr:hover {
background: inherit;
}
div#cgit table.list tr.nohover-highlight:hover:nth-child(even) {
background: inherit;
}
div#cgit table.list td:last-child {
width: 0;
}
div#cgit div.footer {
font-size: 1em;
margin-top: 0;
}
div#cgit table.blob td.linenumbers:nth-last-child(3) {
display: none;
}
div#cgit table.blob td.linenumbers a:target {
color: goldenrod;
text-decoration: underline;
outline: none;
}
'';
passAsFile = [ "licenseHeader" "extraCss" ];
} ''
cat $licenseHeaderPath ${pkgs.cgit}/cgit/cgit.css $extraCssPath > $out
'';
in
lib.mapAttrs (
_: { forceSSL ? true, enableACME ? true, ... } @ args:
args // { inherit forceSSL enableACME; }
)
vhosts;
users.groups.spectrum.members = [ "qyliss" ];
system.activationScripts.spectrum-home = lib.stringAfter [ "users" ] ''
install -g spectrum -m 2775 -d /home/spectrum
install -g spectrum -m 0775 -d /home/spectrum/git
'';
environment.systemPackages = with pkgs; [ cgit git ];
services.nginx.appendConfig = ''
stream {
server {
listen 6697 ssl;
ssl_certificate /var/lib/acme/qyliss.net/fullchain.pem;
ssl_certificate_key /var/lib/acme/qyliss.net/key.pem;
proxy_pass 127.0.0.1:6667;
}
}
'';
services.tor.relay.accountingMax = "50 GBytes";
services.tor.relay.accountingStart = "day 12:00";
services.tor.extraConfig = ''
ORPort [2001:ba8:1f1:f0bc::2]:${toString config.services.tor.relay.port}
'';
system.stateVersion = "18.03";
}