summaryrefslogtreecommitdiff
path: root/os/kay
diff options
context:
space:
mode:
authorsinanmohd <sinan@sinanmohd.com>2024-06-01 19:25:59 +0530
committersinanmohd <sinan@sinanmohd.com>2024-06-01 19:26:13 +0530
commit8febb2fad131dc1ff42a2c667b26b013d64c17b8 (patch)
treecf33b3a20def6ab7836a037b5195cc617647fa9c /os/kay
parent5c48d5ad41221dbfa186701ba40404bd2571c242 (diff)
repo: ./nixos -> ./os
Diffstat (limited to 'os/kay')
-rw-r--r--os/kay/configuration.nix18
-rw-r--r--os/kay/hardware-configuration.nix39
-rw-r--r--os/kay/modules/acme.nix23
-rw-r--r--os/kay/modules/cgit.nix33
-rw-r--r--os/kay/modules/dendrite.nix108
-rw-r--r--os/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone14
-rw-r--r--os/kay/modules/dns/ddns.nix44
-rw-r--r--os/kay/modules/dns/default.nix137
-rw-r--r--os/kay/modules/dns/sinanmohd.com.zone46
-rw-r--r--os/kay/modules/hurricane.nix115
-rw-r--r--os/kay/modules/iperf3.nix10
-rw-r--r--os/kay/modules/mail.nix110
-rw-r--r--os/kay/modules/matrix-sliding-sync.nix18
-rw-r--r--os/kay/modules/network.nix82
-rw-r--r--os/kay/modules/router.nix43
-rw-r--r--os/kay/modules/sftp.nix44
-rw-r--r--os/kay/modules/sshfwd.nix29
-rw-r--r--os/kay/modules/wireguard.nix57
-rw-r--r--os/kay/modules/www.nix134
-rw-r--r--os/kay/secrets.yaml47
20 files changed, 1151 insertions, 0 deletions
diff --git a/os/kay/configuration.nix b/os/kay/configuration.nix
new file mode 100644
index 0000000..24cc246
--- /dev/null
+++ b/os/kay/configuration.nix
@@ -0,0 +1,18 @@
+{ ... }:
+
+{
+ imports = [
+ ../common/configuration.nix
+ ./hardware-configuration.nix
+
+ ./modules/network.nix
+ ./modules/www.nix
+ ./modules/sftp.nix
+ ./modules/acme.nix
+ ./modules/mail.nix
+ ./modules/dns
+ ./modules/sshfwd.nix
+ ];
+
+ boot.consoleLogLevel = 3;
+}
diff --git a/os/kay/hardware-configuration.nix b/os/kay/hardware-configuration.nix
new file mode 100644
index 0000000..5e2efdf
--- /dev/null
+++ b/os/kay/hardware-configuration.nix
@@ -0,0 +1,39 @@
+{ modulesPath, ... }:
+
+{
+ imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
+
+ boot = {
+ loader = {
+ systemd-boot.enable = true;
+ efi.canTouchEfiVariables = true;
+ };
+
+ kernelModules = [ "kvm-intel" ];
+ blacklistedKernelModules = [ "nouveau" ];
+ initrd.availableKernelModules = [
+ "xhci_pci"
+ "ehci_pci"
+ "ahci"
+ "usb_storage"
+ "usbhid"
+ "sd_mod"
+ ];
+ };
+
+ fileSystems = {
+ "/" = {
+ device = "/dev/disk/by-uuid/2eeacf49-c51e-4229-bd4a-ae437014725f";
+ fsType = "ext4";
+ };
+ "/boot" = {
+ device = "/dev/disk/by-uuid/A902-90BB";
+ fsType = "vfat";
+ };
+ "/hdd" = {
+ device = "/dev/disk/by-uuid/c941edb4-e393-4254-bbef-d1b3728290e9";
+ fsType = "ext4";
+ options = [ "nofail" ];
+ };
+ };
+}
diff --git a/os/kay/modules/acme.nix b/os/kay/modules/acme.nix
new file mode 100644
index 0000000..f4ded0a
--- /dev/null
+++ b/os/kay/modules/acme.nix
@@ -0,0 +1,23 @@
+{ config, pkgs, ... }: let
+ email = config.userdata.email;
+ domain = config.userdata.domain;
+
+ environmentFile =
+ pkgs.writeText "acme-dns" "RFC2136_NAMESERVER='[2001:470:ee65::1]:53'";
+in {
+ security.acme = {
+ acceptTerms = true;
+ defaults.email = email;
+
+ certs.${domain} = {
+ inherit domain;
+ extraDomainNames = [ "*.${domain}" ];
+
+ dnsProvider = "rfc2136";
+ dnsPropagationCheck = false; # local DNS server
+
+ inherit environmentFile;
+ group = config.services.nginx.group;
+ };
+ };
+}
diff --git a/os/kay/modules/cgit.nix b/os/kay/modules/cgit.nix
new file mode 100644
index 0000000..f8fb25c
--- /dev/null
+++ b/os/kay/modules/cgit.nix
@@ -0,0 +1,33 @@
+{ config, pkgs, ... }:
+
+let
+ domain = config.userdata.domain;
+ user = config.userdata.name;
+in
+{
+ environment.systemPackages = with pkgs; [
+ luajitPackages.luaossl
+ lua52Packages.luaossl
+ ];
+
+ services.cgit."git.${domain}" = {
+ enable = true;
+ nginx.virtualHost = "git.${domain}";
+ scanPath = "/var/lib/git";
+ settings = {
+ project-list = "/var/lib/git/project.list";
+ remove-suffix = 1;
+ enable-commit-graph = 1;
+ root-title = "${user}'s git repository";
+ root-desc = "how do i learn github anon";
+ source-filter = "${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py";
+ about-filter = "${pkgs.cgit}/lib/cgit/filters/about-formatting.sh";
+ readme = ":README.md";
+ footer = "";
+ enable-blame = 1;
+ clone-url = "https://git.${domain}/$CGIT_REPO_URL";
+ enable-log-filecount = 1;
+ enable-log-linecount = 1;
+ };
+ };
+}
diff --git a/os/kay/modules/dendrite.nix b/os/kay/modules/dendrite.nix
new file mode 100644
index 0000000..8277e21
--- /dev/null
+++ b/os/kay/modules/dendrite.nix
@@ -0,0 +1,108 @@
+{ config, lib, pkgs, ... }:
+
+let
+ domain = config.userdata.domain;
+ database = {
+ connection_string = "postgres:///dendrite?host=/run/postgresql";
+ max_open_conns = 90;
+ max_idle_conns = 5;
+ conn_max_lifetime = -1;
+ };
+in
+{
+ sops.secrets."matrix-${domain}/key" = {};
+
+ services = {
+ postgresql = {
+ enable = true;
+ package = with pkgs; postgresql_15;
+ settings = {
+ log_timezone = config.time.timeZone;
+ listen_addresses = lib.mkForce "";
+ };
+ ensureDatabases = [ "dendrite" ];
+ ensureUsers = [{
+ name = "dendrite";
+ ensureDBOwnership = true;
+ }];
+ authentication = lib.mkForce "local all all trust";
+ };
+
+ dendrite = {
+ enable = true;
+ loadCredential = [
+ "private_key:${config.sops.secrets."matrix-${domain}/key".path}"
+ ];
+
+ settings = {
+ sync_api.search = {
+ enable = true;
+ index_path = "/var/lib/dendrite/searchindex";
+ };
+ global = {
+ server_name = domain;
+ private_key = "$CREDENTIALS_DIRECTORY/private_key";
+ trusted_third_party_id_servers = [
+ "matrix.org"
+ "vector.im"
+ ];
+ inherit database;
+ };
+ logging = [{
+ type = "std";
+ level = "warn";
+ }];
+ mscs = {
+ inherit database;
+ mscs = [ "msc2836" ];
+ };
+ sync_api = {
+ inherit database;
+ real_ip_header = "X-Real-IP";
+ };
+ media_api = {
+ inherit database;
+ dynamic_thumbnails = true;
+ max_file_size_bytes = 12800000000;
+ };
+ federation_api = {
+ inherit database;
+ send_max_retries = 8;
+ key_perspectives = [{
+ server_name = "matrix.org";
+ keys = [
+ {
+ key_id = "ed25519:auto";
+ public_key = "Noi6WqcDj0QmPxCNQqgezwTlBKrfqehY1u2FyWP9uYw";
+ }
+ {
+ key_id = "ed25519:a_RXGa";
+ public_key = "l8Hft5qXKn1vfHrg3p4+W8gELQVo8N13JkluMfmn2sQ";
+ }
+ ];
+ }];
+ };
+
+ app_service_api = {
+ inherit database;
+ };
+ room_server = {
+ inherit database;
+ };
+ push_server = {
+ inherit database;
+ };
+ relay_api = {
+ inherit database;
+ };
+ key_server = {
+ inherit database;
+ };
+ user_api = {
+ account_database = database;
+ device_database = database;
+ };
+ };
+ };
+ };
+}
diff --git a/os/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone b/os/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone
new file mode 100644
index 0000000..69b3524
--- /dev/null
+++ b/os/kay/modules/dns/5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone
@@ -0,0 +1,14 @@
+$ORIGIN 5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.
+$TTL 2d
+
+@ IN SOA ns1.sinanmohd.com. sinan.sinanmohd.com. (
+ 2024020400 ; serial
+ 2h ; refresh
+ 5m ; retry
+ 1d ; expire
+ 5m ) ; nx ttl
+
+ IN NS ns1.sinanmohd.com.
+
+1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR ns1.sinanmohd.com.
+7.3.3.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0 IN PTR mail.sinanmohd.com.
diff --git a/os/kay/modules/dns/ddns.nix b/os/kay/modules/dns/ddns.nix
new file mode 100644
index 0000000..e6e417a
--- /dev/null
+++ b/os/kay/modules/dns/ddns.nix
@@ -0,0 +1,44 @@
+{ pkgs, ... }: {
+ services.pppd.script = {
+ "02-ddns-ipv4" = {
+ runtimeInputs = with pkgs; [ coreutils knot-dns ];
+ type = "ip-up";
+
+ text = ''
+ cat <<- EOF | knsupdate
+ server 2001:470:ee65::1
+ zone sinanmohd.com.
+
+ update delete sinanmohd.com. A
+ update add sinanmohd.com. 180 A $4
+
+ update delete mail.sinanmohd.com. A
+ update add mail.sinanmohd.com. 180 A $4
+
+ send
+ EOF
+ '';
+ };
+
+ "02-ddns-ipv6" = {
+ runtimeInputs = with pkgs; [ coreutils knot-dns iproute2 gnugrep ];
+ type = "ipv6-up";
+
+ text = ''
+ while ! ipv6="$(ip -6 addr show dev "$1" scope global | grep -o '[0-9a-f:]*::1')"; do
+ sleep 0.2
+ done
+
+ cat <<- EOF | knsupdate
+ server 2001:470:ee65::1
+ zone sinanmohd.com.
+
+ update delete sinanmohd.com. AAAA
+ update add sinanmohd.com. 180 AAAA $ipv6
+
+ send
+ EOF
+ '';
+ };
+ };
+}
diff --git a/os/kay/modules/dns/default.nix b/os/kay/modules/dns/default.nix
new file mode 100644
index 0000000..1146cc3
--- /dev/null
+++ b/os/kay/modules/dns/default.nix
@@ -0,0 +1,137 @@
+{ config, pkgs, ... }: let
+ listen_addr = "2001:470:ee65::1";
+
+ acmeSOA = pkgs.writeText "acmeSOA" ''
+ $TTL 2d
+
+ @ IN SOA ns1.sinanmohd.com. sinan.sinanmohd.com. (
+ 2024020505 ; serial
+ 2h ; refresh
+ 5m ; retry
+ 1d ; expire
+ 5m ) ; nx ttl
+
+ IN NS ns1.sinanmohd.com.
+ '';
+in {
+ imports = [ ./ddns.nix ];
+
+ networking.firewall = {
+ allowedTCPPorts = [ 53 ];
+ allowedUDPPorts = [ 53 ];
+ };
+
+ sops.secrets.dns = {
+ owner = config.systemd.services.knot.serviceConfig.User;
+ group = config.systemd.services.knot.serviceConfig.Group;
+ };
+
+ services.knot = {
+ enable = true;
+ keyFiles = [ config.sops.secrets.dns.path ];
+
+ settings = {
+ server.listen = listen_addr;
+
+ remote = [
+ {
+ id = "ns1.he.net";
+ address = [ "2001:470:100::2" "216.218.130.2" ];
+ via = "2001:470:ee65::1";
+ }
+ {
+ id = "m.gtld-servers.net";
+ address = [ "2001:501:b1f9::30" "192.55.83.30" ];
+ }
+ ];
+
+ submission = [{
+ id = "gtld-servers.net";
+ parent = "m.gtld-servers.net";
+ }];
+
+ policy = [{
+ id = "gtld-servers.net";
+ algorithm = "ecdsap384sha384";
+ ksk-lifetime = "365d";
+ ksk-submission = "gtld-servers.net";
+ }];
+
+ # generate TSIG key with keymgr -t name
+ acl = [
+ {
+ id = "ns1.he.net";
+ key = "ns1.he.net";
+ address = [ "2001:470:600::2" "216.218.133.2" ];
+ action = "transfer";
+ }
+ {
+ id = "localhost";
+ address = [ listen_addr ];
+ update-type = [ "A" "AAAA" ];
+ action = "update";
+ }
+ {
+ id = "acme";
+ address = [ listen_addr ];
+ update-type = [ "TXT" ];
+ action = "update";
+ }
+ ];
+
+ mod-rrl = [{
+ id = "default";
+ rate-limit = 200;
+ slip = 2;
+ }];
+
+ template = [
+ {
+ id = "default";
+ semantic-checks = "on";
+ global-module = "mod-rrl/default";
+ }
+ {
+ id = "master";
+ semantic-checks = "on";
+
+ dnssec-signing = "on";
+ dnssec-policy = "gtld-servers.net";
+
+ notify = [ "ns1.he.net" ];
+ acl = [ "ns1.he.net" "localhost" ];
+
+ zonefile-sync = "-1";
+ zonefile-load = "difference";
+ }
+ {
+ id = "acme";
+ semantic-checks = "on";
+ acl = [ "acme" ];
+
+ zonefile-sync = "-1";
+ zonefile-load = "difference";
+ journal-content = "changes";
+ }
+ ];
+
+ zone = [
+ {
+ domain = "sinanmohd.com";
+ file = ./sinanmohd.com.zone;
+ template = "master";
+ }
+ {
+ domain = "_acme-challenge.sinanmohd.com";
+ file = acmeSOA;
+ template = "acme";
+ }
+ {
+ domain = "5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa";
+ file = ./5.6.e.e.0.7.4.0.1.0.0.2.ip6.arpa.zone;
+ }
+ ];
+ };
+ };
+
+}
diff --git a/os/kay/modules/dns/sinanmohd.com.zone b/os/kay/modules/dns/sinanmohd.com.zone
new file mode 100644
index 0000000..0409efc
--- /dev/null
+++ b/os/kay/modules/dns/sinanmohd.com.zone
@@ -0,0 +1,46 @@
+$ORIGIN sinanmohd.com.
+$TTL 2d
+
+@ IN SOA ns1 hostmaster (
+ 2024022700 ; serial
+ 2h ; refresh
+ 5m ; retry
+ 1d ; expire
+ 5m ) ; nx ttl
+
+ IN NS ns1
+ IN NS ns2.he.net.
+ IN NS ns3.he.net.
+ IN NS ns4.he.net.
+ IN NS ns5.he.net.
+
+ 30 IN A 127.0.0.1
+ 30 IN AAAA ::1
+
+ IN MX 10 mail
+
+ IN TXT "v=spf1 mx -all"
+_dmarc IN TXT "v=DMARC1; p=reject; rua=mailto:reports@sinanmohd.com; ruf=mailto:reports@sinanmohd.com; adkim=s; aspf=s"
+
+ed25519._domainkey IN TXT "v=DKIM1; k=ed25519; p=EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU="
+rsa._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4HEqO63fSC0cUnJt9vAQBssTkPfT4QefmAK/1BtAIRIOdGakf7PI7p3A1ETgwfYxuHj7BUSzUtESsHMThbhB1Wko79+AR+5ZBDBmD8CE0dOnZfzeG8xIaGfYkaL4gana6YZWiBT2oi/CimJfc22wacF01SufOs4R8cDpy4BZIgDD/zfF4bFTORQ0vMSJQJkp1zdQelERDU5CEezgxgVYgoSmdEpgkhc23PJSyj4Z7hA69N0amsb3cVVrfVXcYvSqTK3S2vLLA89ws4CUjCCpUW40gVIP8QP6CqTL76936Oo7OVWgmV3Sn3wa8FMN6IATY+fbMlrdOMsPY5PauJyEoQIDAQAB"
+
+ns1 IN AAAA 2001:470:ee65::1
+
+mail 30 IN A 127.0.0.1
+mail IN AAAA 2001:470:ee65::1337
+smtp IN CNAME @
+imap IN CNAME @
+mta-sts IN CNAME @
+
+_mta-sts IN TXT "v=STSv1; id=2024022500"
+_smtp._tls IN TXT "v=TLSRPTv1; rua=mailto:reports@sinanmohd.com"
+
+www IN CNAME @
+git IN CNAME @
+bin IN CNAME @
+static IN CNAME @
+
+lia IN A 65.0.3.127
+
+_acme-challenge IN NS ns1
diff --git a/os/kay/modules/hurricane.nix b/os/kay/modules/hurricane.nix
new file mode 100644
index 0000000..9e22bf5
--- /dev/null
+++ b/os/kay/modules/hurricane.nix
@@ -0,0 +1,115 @@
+{ config, pkgs, lib, ... }:
+
+let
+ iface = "hurricane";
+ remote = "216.218.221.42";
+
+ clinet = "2001:470:35:72a::2";
+ server = "2001:470:35:72a::1";
+
+ prefix64 = "2001:470:36:72a::/64";
+ prefix48 = "2001:470:ee65::/48";
+
+ makeAddr = prefix: host: let
+ split = lib.strings.splitString "/" prefix;
+ in {
+ address = "${lib.head split}${host}";
+ prefixLength = lib.toInt (lib.last split);
+ };
+in
+{
+ networking = {
+ sits.${iface} = {
+ inherit remote;
+ ttl = 225;
+ };
+ interfaces.${iface} = {
+ mtu = 1440; # 1460(ppp0) - 20
+ ipv6.addresses = [
+ {
+ address = clinet;
+ prefixLength = 64;
+ }
+
+ (makeAddr prefix64 "1")
+ (makeAddr prefix48 "1")
+ (makeAddr prefix48 "1337")
+ ];
+ };
+
+ iproute2 = {
+ enable = true;
+ rttablesExtraConfig = "200 hurricane";
+ };
+
+ firewall.extraCommands =
+ "iptables -A INPUT --proto 41 --source ${remote} --jump ACCEPT";
+ };
+
+ sops.secrets = {
+ "hurricane/username" = {};
+ "hurricane/update_key" = {};
+ "hurricane/tunnel_id" = {};
+ };
+
+ systemd.services."network-route-${iface}" = {
+ description = "Routing configuration of ${iface}";
+ wantedBy = [
+ "network-setup.service"
+ "network.target"
+ ];
+ before = [ "network-setup.service" ];
+ bindsTo = [ "network-addresses-hurricane.service" ];
+ after = [ "network-pre.target" "network-addresses-hurricane.service" ];
+ # restart rather than stop+start this unit to prevent the
+ # network from dying during switch-to-configuration.
+ stopIfChanged = false;
+
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ };
+
+ path = [ pkgs.iproute2 ];
+ script = ''
+ echo -n "adding route"
+
+ ip -6 rule add from ${clinet}/64 table hurricane || exit 1
+ ip -6 rule add from ${prefix64} table hurricane || exit 1
+ ip -6 rule add from ${prefix48} table hurricane || exit 1
+
+ ip -6 route add default via ${server} dev hurricane table hurricane || exit 1
+ '';
+ preStop = ''
+ echo -n "deleting route"
+
+ ip -6 route del default via ${server} dev hurricane table hurricane || exit 1
+
+ ip -6 rule del from ${prefix48} table hurricane || exit 1
+ ip -6 rule del from ${prefix64} table hurricane || exit 1
+ ip -6 rule del from ${clinet}/64 table hurricane || exit 1
+ '';
+ };
+
+
+ services.pppd.script."01-${iface}" = {
+ runtimeInputs = with pkgs; [ curl coreutils iproute2 iputils ];
+ text = ''
+ wan_ip="$4"
+ username="$(cat ${config.sops.secrets."hurricane/username".path})"
+ update_key="$(cat ${config.sops.secrets."hurricane/update_key".path})"
+ tunnel_id="$(cat ${config.sops.secrets."hurricane/tunnel_id".path})"
+
+ auth_url="https://$username:$update_key@ipv4.tunnelbroker.net/nic/update?hostname=$tunnel_id"
+ until curl --silent "$auth_url"; do
+ sleep 1
+ done
+
+ while [ ! -e /sys/class/net/${iface} ]; do
+ sleep 1 # make sure ${iface} is up
+ done
+
+ ip tunnel change ${iface} local "$wan_ip" mode sit
+ '';
+ };
+}
diff --git a/os/kay/modules/iperf3.nix b/os/kay/modules/iperf3.nix
new file mode 100644
index 0000000..901a93d
--- /dev/null
+++ b/os/kay/modules/iperf3.nix
@@ -0,0 +1,10 @@
+{ ... }:
+
+{
+ services.iperf3 = {
+ enable = true;
+
+ bind = "10.0.0.1";
+ openFirewall = true;
+ };
+}
diff --git a/os/kay/modules/mail.nix b/os/kay/modules/mail.nix
new file mode 100644
index 0000000..79e4019
--- /dev/null
+++ b/os/kay/modules/mail.nix
@@ -0,0 +1,110 @@
+{ config, ... }: let
+ ipv6 = "2001:470:ee65::1337";
+ domain = config.userdata.domain;
+
+ username = config.userdata.name;
+ secret = "$argon2i$v=19$m=4096,t=3,p=1$SWV5aWU3YWUgZWFTNm9oc28gTGFvdDdlRG8ga2FTaWVjaDYgYWV0aDFHb28$O/sDv7oy9wUxFjvKoxB5o8ZnPvjYJo9DjX0C/AZQFF0";
+ email = [
+ "${username}@${domain}"
+ "official@${domain}"
+
+ "postmaster@${domain}"
+ "hostmaster@${domain}"
+ ];
+
+ credentials_directory = "/run/credentials/stalwart-mail.service";
+in {
+ networking.firewall.allowedTCPPorts = [
+ 25 # smto
+ 465 # submission
+ 587 # submissions
+ 993 # imap ssl
+ 4190 # managesieve
+ ];
+
+ security.acme.certs.${domain}.postRun = "systemctl restart stalwart-mail.service";
+ sops.secrets = {
+ "mail.${domain}/dkim_rsa" = {};
+ "mail.${domain}/dkim_ed25519" = {};
+ };
+
+ services.stalwart-mail = {
+ enable = true;
+ loadCredential = [
+ "dkim_rsa:${config.sops.secrets."mail.${domain}/dkim_rsa".path}"
+ "dkim_ed25519:${config.sops.secrets."mail.${domain}/dkim_ed25519".path}"
+
+ "cert:${config.security.acme.certs.${domain}.directory}/fullchain.pem"
+ "key:${config.security.acme.certs.${domain}.directory}/key.pem"
+ ];
+
+ settings = {
+ macros = {
+ host = "mail.${domain}";
+ default_domain = domain;
+ default_directory = "in-memory";
+ default_store = "sqlite";
+ };
+
+ queue.outbound = {
+ ip-strategy = "ipv6_then_ipv4";
+ source-ip.v6 = "['${ipv6}']";
+ tls.starttls = "optional";
+ };
+ server.listener = {
+ smtp.bind = [ "[${ipv6}]:25" "0.0.0.0:25" ];
+ jmap.bind = [ "[::]:8034" ];
+ };
+
+ signature = {
+ rsa = {
+ private-key = "file://${credentials_directory}/dkim_rsa";
+ selector = "rsa";
+ set-body-length = true;
+ };
+ ed25519 = {
+ public-key = "EHk924AruF9Y0Xaf009rpRl+yGusjmjT1Zeho67BnDU=";
+ private-key = "file://${credentials_directory}/dkim_ed25519";
+ domain = "%{DEFAULT_DOMAIN}%";
+ selector = "ed25519";
+ headers = [ "From" "To" "Date" "Subject" "Message-ID" ];
+ algorithm = "ed25519-sha256";
+ canonicalization = "relaxed/relaxed";
+ set-body-length = true;
+ report = true;
+ };
+ };
+
+ certificate."default" = {
+ cert = "file://${credentials_directory}/cert";
+ private-key = "file://${credentials_directory}/key";
+ };
+
+ storage.blob = "fs";
+ store = {
+ fs.disable = false;
+ sqlite.disable = false;
+ };
+
+ directory."in-memory" = {
+ type = "memory";
+ options.subaddressing = true;
+
+ principals = [
+ {
+ inherit email;
+ inherit secret;
+ name = username;
+ type = "admin";
+ }
+ { # for mta-sts & dmarc reports
+ email = "reports${domain}";
+ inherit secret;
+ name = "reports";
+ type = "individual";
+ }
+ ];
+ };
+ };
+ };
+}
diff --git a/os/kay/modules/matrix-sliding-sync.nix b/os/kay/modules/matrix-sliding-sync.nix
new file mode 100644
index 0000000..ebdc34d
--- /dev/null
+++ b/os/kay/modules/matrix-sliding-sync.nix
@@ -0,0 +1,18 @@
+{ config, ... }:
+
+let
+ domain = config.userdata.domain;
+in
+{
+ sops.secrets."matrix-${domain}/sliding_sync" = {};
+
+ services.matrix-sliding-sync = {
+ enable = true;
+ environmentFile = config.sops.secrets."matrix-${domain}/sliding_sync".path;
+
+ settings = {
+ SYNCV3_LOG_LEVEL = "warn";
+ SYNCV3_SERVER = "http://127.0.0.1:${toString config.services.dendrite.httpPort}";
+ };
+ };
+}
diff --git a/os/kay/modules/network.nix b/os/kay/modules/network.nix
new file mode 100644
index 0000000..929fb1b
--- /dev/null
+++ b/os/kay/modules/network.nix
@@ -0,0 +1,82 @@
+{ config, ... }:
+
+let
+ inetVlan = 722;
+ voipVlan = 1849;
+ wanInterface = "enp4s0";
+ nameServer = "1.0.0.1";
+in
+{
+ imports = [
+ ./router.nix
+ ./hurricane.nix
+ ];
+
+ sops.secrets = {
+ "ppp/chap-secrets" = {};
+ "ppp/pap-secrets" = {};
+ "ppp/username" = {};
+ };
+
+ networking = let
+ voipVlanIface = "voip";
+ in {
+ vlans = {
+ wan = {
+ id = inetVlan;
+ interface = wanInterface;
+ };
+ ${voipVlanIface} = {
+ id = voipVlan;
+ interface = wanInterface;
+ };
+ };
+
+ interfaces.${voipVlanIface}.useDHCP = true;
+ dhcpcd.extraConfig = ''
+ interface ${voipVlanIface}
+ ipv4only
+ nogateway
+ '';
+ };
+
+ services = {
+ dnsmasq = {
+ enable = true;
+ settings = {
+ server = [ nameServer ];
+ bind-interfaces = true;
+ };
+ };
+
+ pppd = {
+ enable = true;
+
+ config = ''
+ plugin pppoe.so
+ debug
+
+ nic-wan
+ defaultroute
+ ipv6 ::1,
+ noauth
+
+ persist
+ lcp-echo-adaptive
+ lcp-echo-interval 1
+ lcp-echo-failure 5
+ '';
+
+ peers.bsnl = {
+ enable = true;
+ autostart = true;
+ configFile = config.sops.secrets."ppp/username".path;
+ };
+
+ secret = {
+ chap = config.sops.secrets."ppp/chap-secrets".path;
+ pap = config.sops.secrets."ppp/pap-secrets".path;
+ };
+ };
+ };
+}
diff --git a/os/kay/modules/router.nix b/os/kay/modules/router.nix
new file mode 100644
index 0000000..2254c3b
--- /dev/null
+++ b/os/kay/modules/router.nix
@@ -0,0 +1,43 @@
+{ ... }:
+
+let
+ lanInterface = "enp0s20u1";
+ wanInterface = "ppp0";
+ subnet = "10.0.0.0";
+ prefix = 24;
+ host = "10.0.0.1";
+ leaseRangeStart = "10.0.0.100";
+ leaseRangeEnd = "10.0.0.254";
+in
+{
+ imports = [
+ ./wireguard.nix
+ ./iperf3.nix
+ ];
+
+ networking = {
+ nat = {
+ enable = true;
+ externalInterface = wanInterface;
+ internalInterfaces = [ lanInterface ];
+ };
+ interfaces."${lanInterface}" = {
+ ipv4.addresses = [{
+ address = host;
+ prefixLength = prefix;
+ }];
+ };
+ firewall = {
+ allowedUDPPorts = [ 53 67 ];
+ allowedTCPPorts = [ 53 ];
+ extraCommands = ''
+ iptables -t nat -I POSTROUTING 1 -s ${subnet}/${toString prefix} -o ${wanInterface} -j MASQUERADE
+ '';
+ };
+ };
+
+ services.dnsmasq.settings = {
+ dhcp-range = [ "${leaseRangeStart},${leaseRangeEnd}" ];
+ interface = [ lanInterface ];
+ };
+}
diff --git a/os/kay/modules/sftp.nix b/os/kay/modules/sftp.nix
new file mode 100644
index 0000000..bbe055e
--- /dev/null
+++ b/os/kay/modules/sftp.nix
@@ -0,0 +1,44 @@
+{ config, ... }:
+
+let
+ storage = "/hdd/users";
+ user = config.userdata.name;
+ pubKeys = config.users.users.${user}.openssh.authorizedKeys.keys;
+in
+{
+ users = {
+ groups."sftp".members = [];
+
+ users."sftp" = {
+ group = "sftp";
+ shell = "/run/current-system/sw/bin/nologin";
+ isNormalUser = true;
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFmA1dyV+o9gfoxlbVG0Y+dn3lVqdFs5fMqfxyNc5/Lr sftp@cez"
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDCbgjAfyDNtLNyOS+sfLirYtfEAkGqV54LOwabpWkvf sftp@veu"
+ ] ++ pubKeys;
+ };
+
+ users."nazer" = {
+ group = "sftp";
+ shell = "/run/current-system/sw/bin/nologin";
+ isNormalUser = true;
+ openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICV09w9Ovk9wk4Bhn/06iOn+Ss8lK3AmQAl8+lXHRycu nazu@pc"
+ ];
+ };
+ };
+
+ services.openssh.extraConfig = ''
+ Match Group sftp
+ # chroot dir should be owned by root
+ # and sub dirs by %u
+ ChrootDirectory ${storage}/%u
+ ForceCommand internal-sftp
+
+ PermitTunnel no
+ AllowAgentForwarding no
+ AllowTcpForwarding no
+ X11Forwarding no
+ '';
+}
diff --git a/os/kay/modules/sshfwd.nix b/os/kay/modules/sshfwd.nix
new file mode 100644
index 0000000..d70b893
--- /dev/null
+++ b/os/kay/modules/sshfwd.nix
@@ -0,0 +1,29 @@
+{ ... }: let
+ group = "sshfwd";
+in {
+ networking.firewall.allowedTCPPorts = [ 2222 ];
+
+ users = {
+ groups.${group}.members = [];
+
+ users."lia" = {
+ inherit group;
+ isSystemUser = true;
+
+ openssh.authorizedKeys.keys
+ = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAe7fJlh9L+9JSq0+hK7jNZjszmZqNXwzqcZ+zx0yJyU lia" ];
+ };
+ };
+
+ services.openssh.extraConfig = ''
+ Match Group ${group}
+ ForceCommand echo 'this account is only usable for remote forwarding'
+ PermitTunnel no
+ AllowAgentForwarding no
+ X11Forwarding no
+
+ AllowTcpForwarding remote
+ GatewayPorts clientspecified
+ PermitListen *:2222
+ '';
+}
diff --git a/os/kay/modules/wireguard.nix b/os/kay/modules/wireguard.nix
new file mode 100644
index 0000000..578a86a
--- /dev/null
+++ b/os/kay/modules/wireguard.nix
@@ -0,0 +1,57 @@
+{ config, ... }:
+
+let
+ wgInterface = "wg";
+ wanInterface = "ppp0";
+ subnet = "10.0.1.0";
+ prefix = 24;
+ port = 51820;
+in
+{
+ sops.secrets."misc/wireguard" = {};
+
+ networking = {
+ nat = {
+ enable = true;
+ externalInterface = wanInterface;
+ internalInterfaces = [ wgInterface ];
+ };
+ firewall = {
+ allowedUDPPorts = [ port ];
+ extraCommands = ''
+ iptables -t nat -I POSTROUTING 1 -s ${subnet}/${toString prefix} -o ${wanInterface} -j MASQUERADE
+ '';
+ };
+
+ wireguard.interfaces.${wgInterface} = {
+ ips = [ "10.0.1.1/${toString prefix}" ];
+ listenPort = port;
+ mtu = 1380; # 1460 (ppp0) - 80
+ privateKeyFile = config.sops.secrets."misc/wireguard".path;
+
+ peers = [
+ { # cez
+ publicKey = "IcMpAs/D0u8O/AcDBPC7pFUYSeFQXQpTqHpGOeVpjS8=";
+ allowedIPs = [ "10.0.1.2/32" ];
+ }
+ { # veu
+ publicKey = "bJ9aqGYD2Jh4MtWIL7q3XxVHFuUdwGJwO8p7H3nNPj8=";
+ allowedIPs = [ "10.0.1.3/32" ];
+ }
+ { # dad
+ publicKey = "q70IyOS2IpubIRWqo5sL3SeEjtUy2V/PT8yqVExiHTQ=";
+ allowedIPs = [ "10.0.1.4/32" ];
+ }
+ { # shambai
+ publicKey = "YYDlp/bNKkqFHAhdgaZ2SSEMnIjKTqPTK7Ju6O9/1gY=";
+ allowedIPs = [ "10.0.1.5/32" ];
+ }
+ ];
+ };
+ };
+
+ services.dnsmasq.settings = {
+ no-dhcp-interface = wgInterface;
+ interface = [ wgInterface ];
+ };
+}
diff --git a/os/kay/modules/www.nix b/os/kay/modules/www.nix
new file mode 100644
index 0000000..3891bf6
--- /dev/null
+++ b/os/kay/modules/www.nix
@@ -0,0 +1,134 @@
+{ config, pkgs, lib, ... }:
+
+let
+ domain = config.userdata.domain;
+ fscusat = "fscusat.org";
+ mark = "themark.ing";
+ storage = "/hdd/users/sftp/shr";
+in
+{
+ imports = [
+ ./dendrite.nix
+ ./matrix-sliding-sync.nix
+ ./cgit.nix
+ ];
+
+ security.acme.certs.${domain}.postRun = "systemctl reload nginx.service";
+ networking.firewall = {
+ allowedTCPPorts = [ 80 443 ];
+ allowedUDPPorts = [ 443 ];
+ };
+
+ services.nginx = {
+ enable = true;
+ package = pkgs.nginxQuic;
+ enableQuicBPF = true;
+
+ recommendedTlsSettings = true;
+ recommendedZstdSettings = true;
+ recommendedOptimisation = true;
+ recommendedGzipSettings = true;
+ recommendedProxySettings = true;
+ recommendedBrotliSettings = true;
+ eventsConfig = "worker_connections 1024;";
+
+ virtualHosts = let
+ defaultOpts = {
+ quic = true;
+ http3 = true;
+ forceSSL = true;
+ useACMEHost = domain;
+ };
+ in {
+ "${domain}" = defaultOpts // {
+ default = true;
+ globalRedirect = "www.${domain}";
+
+ extraConfig = ''
+ client_max_body_size ${toString
+ config.services.dendrite.settings.media_api.max_file_size_bytes
+ };
+ '';
+
+ locations = {
+ "/.well-known/matrix/server".return = ''
+ 200 '{ "m.server": "${domain}:443" }'
+ '';
+
+ "/.well-known/matrix/client".return = ''
+ 200 '${builtins.toJSON {
+ "m.homeserver".base_url = "https://${domain}";
+ "org.matrix.msc3575.proxy".url = "https://${domain}";
+ }}'
+ '';
+
+ "/_matrix".proxyPass = "http://127.0.0.1:${toString
+ config.services.dendrite.httpPort
+ }";
+
+ "/_matrix/client/unstable/org.matrix.msc3575/sync".proxyPass =
+ "http://${config.services.matrix-sliding-sync.settings.SYNCV3_BINDADDR}";
+ };
+ };
+
+ "www.${domain}" = defaultOpts // {
+ root = "/var/www/${domain}";
+ };
+
+ "git.${domain}" = defaultOpts;
+
+ "bin.${domain}" = defaultOpts // {
+ root = "${storage}/bin";
+ locations."= /".return = "307 https://www.${domain}";
+ };
+
+ "static.${domain}" = defaultOpts // {
+ root = "${storage}/static";
+ locations."= /".return = "301 https://www.${domain}";
+ };
+
+ "${fscusat}" = defaultOpts // {
+ useACMEHost = null;
+ enableACME = true;
+
+ globalRedirect = "www.${fscusat}";
+ };
+ "www.${fscusat}" = defaultOpts // {
+ useACMEHost = null;
+ enableACME = true;
+
+ locations."/" = {
+ return = "200 '<h1>under construction</h1>'";
+ extraConfig = "add_header Content-Type text/html;";
+ };
+ };
+
+ "${mark}" = defaultOpts // {
+ useACMEHost = null;
+ enableACME = true;
+
+ globalRedirect = "www.${mark}";
+ };
+ "www.${mark}" = defaultOpts // {
+ useACMEHost = null;
+ enableACME = true;
+
+ locations."/" = {
+ return = "200 '<h1>under construction, see you soon</h1>'";
+ extraConfig = "add_header Content-Type text/html;";
+ };
+ };
+
+ "mta-sts.${domain}" = defaultOpts // {
+ locations."= /.well-known/mta-sts.txt".return = ''200 "${
+ lib.strings.concatStringsSep "\\n" [
+ "version: STSv1"
+ "mode: enforce"
+ "mx: mail.${domain}"
+ "max_age: 86400"
+ ]
+ }"'';
+ };
+ };
+ };
+}
diff --git a/os/kay/secrets.yaml b/os/kay/secrets.yaml
new file mode 100644
index 0000000..47be11b
--- /dev/null
+++ b/os/kay/secrets.yaml
@@ -0,0 +1,47 @@
+ppp:
+ chap-secrets: ENC[AES256_GCM,data:oTwucN94iWIzrCCAQySpkG+uEBERmEjXfoPm6piook8bS/q3kCd/DQ==,iv:IC1Ii+rnTvFa0F2bi0fnEAEO7XWV7Wues9T+28bhDnc=,tag:239vrwVzeTIVCIw8U30jtg==,type:str]
+ pap-secrets: ENC[AES256_GCM,data:S72mx8AP8MDWrYZ3TIOnwoKcVWiUzms1ZpckghHjjFcWhW5orOjPOA==,iv:4kNHSZ3+FMA9ROLEgrU38IWd+MBt+vf8CV3WGHkRCCc=,tag:rBtSZH8i7fE7fJhRRda7eA==,type:str]
+ username: ENC[AES256_GCM,data:GzRdyvnRKSS8iH+RuFU9g6zxXhxl0DeWWkAyF3sefZc0QQ==,iv:yTRruKpMda4N2J3Z8MEesrFxqV4g1usbYoxTeKlWf4M=,tag:8h9cpYn2Zy/32+2HJ76dFw==,type:str]
+hurricane:
+ username: ENC[AES256_GCM,data:pe3igN9AIbc1,iv:stBkppjkDC9nvV/fHaEtfs6KskoiqqEKxCp/KC+Xxeo=,tag:pH5CJXOOp/is7dQmt6wlog==,type:str]
+ update_key: ENC[AES256_GCM,data:wwd+QWTgKEqstY5d2eWBnWJYq2EisTTaa/Ow4WwBNkyh5FYP+7PEyg==,iv:b93JvsfWppqlJtZxGAa3xbXgLEFs0A5Seq5pNjTnRW4=,tag:+W1t1M+Mm4LopVbcI1x+eg==,type:str]
+ tunnel_id: ENC[AES256_GCM,data:WUDOxjmA,iv:W8k0pyrAQz+UWtm76uvmzodJ2lZG4ioxrVMWjX1kIVM=,tag:2Q25MXzlptg/rc0HQ1k6rg==,type:str]
+dns: ENC[AES256_GCM,data:Pa6Oo7UFDqo5ZN+eyz9MKy0p4KU1ePTpWQ+R8PuSFO9JjFt/I86ru/qSKyymIzhJcjj5hXMT2LPjk4MH8BWaO39ACsPDSD09xA6e1GO0rvsvtB9cffuz/GnfveyHmev+7xzdriD4IHqINPE=,iv:zuSfHnmxrjFCX3DJSRxLDs/3IVBRnkn3crar1pCW1EU=,tag:rZ0TlMMsOCF3Shunx8PnfA==,type:str]
+matrix-sinanmohd.com:
+ key: ENC[AES256_GCM,data:xsSYua3g+ySUVBtfVZ2uZR4761MC5LeJGxmcgf+dWb5+tBSmgzAQL9FFcl7GLzhTmvlq13lARUr599wShS/C9IyMVGOOT9A8hxLFF9Kak64hmM7ERGrwbmzBY1mdTtvibJqzHaeybUVIMbDagczF54zpjDGLmdC5V84wduPFCndSA5FW+4Hhqw==,iv:KJtqrGNPgMDR6Sg/fOUzVAiwnPZwve9wpVfDQPc4g/c=,tag:E2jlbt5WbRA9wu16Lr69Bg==,type:str]
+ sliding_sync: ENC[AES256_GCM,data:ubFeb/OgYYHaIHVky6KS3icORbpqf7PO3p8bONA8mwG8vU1LB0TDqVm6vQTa8G9pe96JzJ8+IAgSZafG9PaEJc/Bpj53aWRFO3HEV0Pj,iv:P8VD8utVEwNoeQEZUdS2R9GuDe20nKiXYCfKJl0Id3E=,tag:VksV/4IaKN0C2g/alw6r4Q==,type:str]
+mail.sinanmohd.com:
+ dkim_rsa: ENC[AES256_GCM,data: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,iv:dPnpNUPSDiq5C14YzDM2K4mFHNRFgc6p+X3Zu33OH60=,tag:MhgfV3z1wcbAfpwZmVWczw==,type:str]
+ dkim_ed25519: ENC[AES256_GCM,data:bberg3vGG9M3iPH1aLA+wIU6KNnxHRZxpGU5zT5Gqo9lohQa1wBDXCwsP0JaSfg56dhh9ZxF5HFd4V0nUzL6QMIeiExGkZmtdluaqki3fwFCssILch9pWOuM71Q1d7vi1eIN5PrAuX+6m8bmQBd1JIR+Kbz8dQ==,iv:C7wEFU7/xCh8LzyKXHSzgTX/L9OkmGWTnl5A94GLogw=,tag:j+sYtzzGN9guWa6T+ZUzbw==,type:str]
+ sinan: ENC[AES256_GCM,data:F3lhwjf6dZpDSmU=,iv:TCIzQeUBqgjqc+/z3Hh1tYpm3OeLGLpVUDeo6ufP7/4=,tag:TXUI8noaK5jyLpo8D+94jQ==,type:str]
+misc:
+ wireguard: ENC[AES256_GCM,data:kbUtxJv3xSmikJWgtu87TSo5N8tUb2BiH3dH3oOV36waYyXI3bp2aBeAl1k=,iv:yB4UIyMDNRS+JmSnt9XuBhNRTLz+k0FqkK4ofjosRto=,tag:BDSD9SfQuQppKT4+6Cu65w==,type:str]
+sops:
+ kms: []
+ gcp_kms: []
+ azure_kv: []
+ hc_vault: []
+ age:
+ - recipient: age1q5sfy74d53n6jxlgsc2zrsz4wcl9d830nxuagc3wfmdkrrp55ckq9ev6nv
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA2T3NSZ09xUDg5Q2VKM3FB
+ RXNwNTJrVkxScHR2eksrVlZQMFduOGRFT1RFClhQK2xTWXBUMzdlektSWFhHNDBN
+ bEMxelVjK1owZHczMVV3MWI2WlU2TncKLS0tIEovSk1uMnlvWFBya1YxNjArQTdh
+ Unk0a0tvR3VZQmtIU3RZSWNnazZJZTgKe0mjQHEkagnftc2zEbza863dSlnPOM6Q
+ 0Me0paRmqzsYBizp12SHjaXYiXFpvEeGmOVOMoGvD8UzTa+V5klS0w==
+ -----END AGE ENCRYPTED FILE-----
+ - recipient: age15989j5lkkf2kn5wa2p6qc8wlxjjksc63k5ync8rz8t4e87394pzqm7h4rm
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5NDVlc2crekF2b1lVZnZM
+ YU95N3lRWFhUUzczV1h4eUU0dHdSbWdpWVhZCmREdmFDSzRzY3pZUHpERkhCK1FS
+ cmxRam1vZ2U0dHBYc3hJWG9CRW13bzgKLS0tIFBpMFFXYTZDT09mTTJkWDhoYWVr
+ OXgwSml4bkc1dnloNUFsRGFFcXFHc2cK26l2eiKbZUkogmAXoha6HTUs3YFKixYz
+ bTkpKKyOAIIin3YM975wwvkCuWNG4tbnHBHQFh5JGK2OEyLDXuV7Pg==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2024-02-25T04:23:28Z"
+ mac: ENC[AES256_GCM,data:SUFBHKTM2tQHX1Xtta3spl/GaaNrIAcNrLFzKzqb2ki3FhXnLLYu0wD+IBxuj1nxICn9TDprHFdcDenfFPV1mYWtmXLmWMeDcIGKXedYex2nakdlIYngGiLkEseuehft46YtoEqLJVksBFoLKmywRi+/ZGux/heSIyD14Toxb3Q=,iv:dqYGObF1SV3VBxSZtrggRdD1ROqvlp7tn8xLdNuDxx4=,tag:N/4L6NgIqYKQ8IbpFGru2g==,type:str]
+ pgp: []
+ unencrypted_suffix: _unencrypted
+ version: 3.8.1