init: public

This commit is contained in:
2025-04-13 15:09:14 +08:00
parent 5995c2050b
commit 50247d94e8
253 changed files with 12964 additions and 567 deletions

26
config/base.nix Normal file
View File

@@ -0,0 +1,26 @@
{ lib, hostname, ... }:
{
environment.etc.issue.text = "\\e{lightcyan}\\S\\e{reset} Login (\\l)\n\n";
networking.hostName = hostname;
system.stateVersion = "24.11";
systemd.services."systemd-machine-id-commit".enable = lib.mkForce false;
my = {
home = {
# Nicely reload system units when changing configs
systemd.user.startServices = "sd-switch";
home.stateVersion = "24.11";
};
xdg.enable = true;
persist = {
nixosDirs = [
"/root"
"/var"
];
nixosFiles = [
"/etc/machine-id"
];
};
};
}

View File

@@ -0,0 +1,15 @@
{ ... }:
{
services.open-webui = {
enable = true;
host = "127.0.0.1";
port = 8089;
};
services.caddy.virtualHosts."ai.imxyy.top" = {
extraConfig = ''
reverse_proxy :8089 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,11 @@
{ ... }:
{
services.caddy = {
enable = true;
email = "acme@imxyy.top";
};
security.acme = {
acceptTerms = true;
defaults.email = "acme@imxyy.top";
};
}

View File

@@ -0,0 +1,38 @@
{ config, ... }:
{
services.postgresql.ensureUsers = [
{
name = "coder";
ensureDBOwnership = true;
}
];
services.postgresql.ensureDatabases = [ "coder" ];
virtualisation.oci-containers = {
containers = {
coder = {
image = "ghcr.io/coder/coder:latest";
environment = {
CODER_ACCESS_URL = "https://coder.imxyy.top";
CODER_HTTP_ADDRESS = "0.0.0.0:8086";
CODER_PG_CONNECTION_URL = "postgresql://coder:coderdatabase@127.0.0.1/coder?sslmode=disable";
};
extraOptions = [
"--network=host"
"--group-add=${toString config.users.groups.podman.gid}"
];
volumes = [
"/var/lib/coder:/home/coder/.config"
"/var/run/docker.sock:/var/run/docker.sock"
];
ports = [ "8086:8086" ];
};
};
};
services.caddy.virtualHosts."coder.imxyy.top" = {
extraConfig = ''
reverse_proxy :8086 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,26 @@
{ ... }:
{
imports = [
./nixos.nix
./hardware.nix
./home.nix
./virt.nix
./docker.nix
./minecraft.nix
./samba.nix
./net.nix
./caddy.nix
./nextcloud.nix
./mail.nix
./gitea.nix
./vault.nix
./homepage.nix
./code.nix
./yesplaymusic.nix
./ai.nix
./grafana.nix
./note.nix
./matrix.nix
./minio.nix
];
}

View File

@@ -0,0 +1,9 @@
{ lib, ... }:
{
virtualisation.oci-containers.backend = lib.mkForce "podman";
virtualisation.podman = {
enable = true;
dockerCompat = true;
dockerSocket.enable = true;
};
}

View File

@@ -0,0 +1,46 @@
{ ... }:
{
services.caddy.virtualHosts."git.imxyy.top" = {
extraConfig = ''
reverse_proxy :8082 {
header_up X-Real-IP {remote_host}
}
'';
};
services.gitea = {
enable = true;
appName = "imxyy_soope_'s Gitea";
user = "git";
group = "git";
mailerPasswordFile = "/var/lib/gitea/smtp_password";
stateDir = "/mnt/nas/gitea";
settings = {
globalSection = {
LANDING_PAGE = "explore";
};
server = {
DOMAIN = "git.imxyy.top";
HTTP_ADDR = "127.0.0.1";
HTTP_PORT = 8082;
ROOT_URL = "https://git.imxyy.top/";
SSH_PORT = 2222;
};
service = {
REGISTER_MANUAL_CONFIRM = true;
};
};
};
services.openssh.ports = [
22
2222
];
users = {
users.git = {
isNormalUser = true;
description = "git user";
group = "git";
home = "/mnt/nas/gitea";
};
groups.git = { };
};
}

View File

@@ -0,0 +1,45 @@
{ pkgs, ... }:
{
services.grafana = {
enable = true;
settings = {
server = {
http_addr = "0.0.0.0";
http_port = 8090;
domain = "grafana.imxyy.top";
};
};
};
services.prometheus = {
enable = true;
package = pkgs.stable.prometheus;
port = 8091;
exporters = {
node = {
enable = true;
port = 8092;
enabledCollectors = [
"systemd"
"zfs"
];
};
};
scrapeConfigs = [
{
job_name = "node";
static_configs = [
{
targets = [ "127.0.0.1:8092" ];
}
];
}
];
};
services.caddy.virtualHosts."grafana.imxyy.top" = {
extraConfig = ''
reverse_proxy :8090 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,99 @@
{
config,
lib,
pkgs,
...
}:
{
boot.initrd.availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
boot.initrd.kernelModules = [ "amdgpu" ];
boot.kernelModules = [ "kvm-amd" ];
boot.kernelPackages = lib.mkForce pkgs.stable.linuxKernel.packages.linux_zen;
boot.extraModulePackages = [ ];
boot.tmp.useTmpfs = true;
boot.supportedFilesystems = [ "zfs" ];
boot.zfs = {
extraPools = [ "data" ];
forceImportRoot = false;
};
services.zfs.autoScrub.enable = true;
services.btrfs.autoScrub.enable = true;
networking.hostId = "10ca95b4";
fileSystems."/" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=root"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=nix"
];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=persist"
];
neededForBoot = true;
};
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/disk/by-uuid/c7889c5c-c5b6-4e3c-9645-dfd49c2e84d0 /btrfs_tmp
mkdir -p /btrfs_tmp/old_roots
if [[ -e /btrfs_tmp/root ]]; then
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +14); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/32AA-2998";
fsType = "vfat";
};
# 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 false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

View File

@@ -0,0 +1,37 @@
{ lib, ... }:
{
my.home = {
programs.zsh = {
shellAliases = {
proxy_on = lib.mkForce "export http_proxy=http://127.0.0.1:7890 https_proxy=http://127.0.0.1:7890 all_proxy=socks://127.0.0.1:7891";
};
sessionVariables = {
no_proxy = "192.168.3.0/24";
};
};
};
my = {
cmd.all.enable = true;
coding.editor.neovim.enable = true;
coding.misc.enable = true;
coding.langs.lua.enable = true;
persist = {
enable = true;
homeDirs = [
"workspace"
"Virt"
".ssh"
".local/state"
".local/share"
".local/share/nvim"
".cache"
".ollama"
];
nixosDirs = [
"/etc/ssh"
];
};
};
}

View File

@@ -0,0 +1,19 @@
{ ... }:
{
virtualisation.oci-containers = {
containers = {
sun-panel = {
image = "hslr/sun-panel:latest";
volumes = [
"/var/lib/sun-panel:/app/conf"
];
ports = [ "8085:3002" ];
};
};
};
services.caddy.virtualHosts."home.imxyy.top" = {
extraConfig = ''
reverse_proxy :8085
'';
};
}

View File

@@ -0,0 +1,54 @@
{ pkgs, ... }:
{
services.roundcube = {
enable = true;
hostName = "mail.imxyy.top";
plugins = [
"contextmenu"
"persistent_login"
];
package = pkgs.roundcube.withPlugins (
plugins: with plugins; [
contextmenu
persistent_login
]
);
extraConfig = ''
# starttls needed for authentication, so the fqdn required to match
# the certificate
$config['imap_conn_options'] = [
'ssl' => [
'verify_peer_name' => false,
],
];
$config['imap_host'] = "tls://mail10.serv00.com";
$config['imap_user'] = "%u";
$config['imap_pass'] = "%p";
$config['smtp_conn_options'] = [
'ssl' => [
'verify_peer_name' => false,
],
];
$config['smtp_host'] = "tls://mail10.serv00.com";
$config['smtp_user'] = "%u";
$config['smtp_pass'] = "%p";
'';
};
services.nginx.virtualHosts."mail.imxyy.top" = {
listen = [
{
addr = "0.0.0.0";
port = 8087;
}
];
forceSSL = false;
enableACME = false;
};
services.caddy.virtualHosts."mail.imxyy.top" = {
extraConfig = ''
reverse_proxy :8087 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,47 @@
{ ... }:
{
services.matrix-synapse = {
enable = true;
settings = {
server_name = "matrix.imxyy.top";
public_baseurl = "https://matrix.imxyy.top";
listeners = [
{
port = 8094;
bind_addresses = [ "127.0.0.1" ];
type = "http";
tls = false;
x_forwarded = true;
resources = [
{
names = [
"client"
"federation"
];
compress = true;
}
];
}
];
turn_uris = [ "turns:vkvm.imxyy.top:5349" ];
turn_shared_secret = "ac779a48c03bb451839569d295a29aa6ab8c264277bec2df9c9c7f5e22936288";
turn_user_lifetime = "1h";
database_type = "psycopg2";
database_args.database = "matrix-synapse";
};
extraConfigFiles = [
"/var/lib/matrix-synapse/secret"
];
};
services.caddy.virtualHosts."matrix.imxyy.top" = {
extraConfig = ''
reverse_proxy :8094
handle_path /_matrix {
reverse_proxy :8094
}
handle_path /_synapse/client {
reverse_proxy :8094
}
'';
};
}

View File

@@ -0,0 +1,19 @@
{ lib, pkgs, ... }:
{
systemd.services."fabric1.20.6" = {
description = "fabric 1.20.6 minecraft server";
wantedBy = [ "multi-user.target" ];
after = [ "network.target" ];
serviceConfig = {
WorkingDirectory = "/opt/minecraft/fabric1.20.6";
ExecStart = "${lib.getExe' pkgs.openjdk21 "java"} -Xms1G -Xmx5G -jar fabric-server-mc.1.20.6-loader.0.15.11-launcher.1.0.1.jar";
Restart = "always";
RestartSec = "10s";
};
};
my.persist = {
nixosDirs = [
"/opt/minecraft"
];
};
}

View File

@@ -0,0 +1,26 @@
{ config, sopsRoot, ... }:
{
sops.secrets.minio-env = {
sopsFile = sopsRoot + /minio.env;
format = "dotenv";
};
services.minio = {
enable = true;
listenAddress = ":9000";
consoleAddress = ":9001";
region = "cn-south-gz";
configDir = "/mnt/nas/minio/config";
dataDir = [
"/mnt/nas/minio/data"
];
rootCredentialsFile = config.sops.secrets.minio-env.path;
};
services.caddy.virtualHosts."minio.imxyy.top" = {
extraConfig = ''
handle_path /* {
reverse_proxy :9000
}
'';
};
}

View File

@@ -0,0 +1,645 @@
{
config,
lib,
pkgs,
username,
sopsRoot,
...
}:
{
boot.kernelParams = [
"biosdevname=0"
"net.ifnames=0"
];
networking = {
useDHCP = lib.mkForce false;
dhcpcd = {
wait = "background";
IPv6rs = true;
extraConfig = ''
interface mac0
noipv4
'';
};
interfaces = {
eth0.wakeOnLan.enable = true;
eth1.wakeOnLan.enable = true;
mac0 = {
useDHCP = true;
ipv4.addresses = [
{
address = "192.168.3.2";
prefixLength = 24;
}
];
};
};
macvlans."mac0" = {
interface = "eth0";
mode = "bridge";
};
defaultGateway = {
address = "192.168.3.1";
interface = "mac0";
};
nameservers = [
"192.168.3.1"
];
firewall.enable = false;
nftables = {
enable = true;
flushRuleset = true;
ruleset = ''
table inet firewall {
set LANv4 {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
set tcp_ports {
type inet_service
flags interval
elements = {
http,
https,
2222,
25565
}
}
chain prerouting {
type filter hook prerouting priority mangle; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain output {
type filter hook output priority 100; policy accept;
ip daddr @LANv4 accept
ip6 daddr @LANv6 accept
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip protocol { icmp, igmp } accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
tcp dport 2222 ct state new limit rate 15/minute counter accept
tcp dport @tcp_ports counter accept
}
chain forward {
type filter hook forward priority 0; policy accept;
}
chain nat {
type nat hook postrouting priority 0; policy accept;
ip saddr 192.168.3.0/24 masquerade
}
}
'';
};
};
services.openssh = {
enable = true;
settings = {
# PermitRootLogin = "yes";
PermitRootLogin = "prohibit-password";
PasswordAuthentication = true;
};
};
users.users.root.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5"
];
users.users.${username}.openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOEFLUkyeaK8ZPPZdVNEmtx8zvoxi7xqS2Z6oxRBuUPO imxyy@imxyy-nix"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKqza/3b6a9JxsNxytHF5GPe4gQhbLrKxAPyZ0GpfVQt imxyy-hisense-pad"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK8pivvE8PMtsOxmccfNhH/4KehDKhBfUfJbQZxo/SZT imxyy-ace5"
];
sops.secrets.dae-imxyy-nix-server = {
sopsFile = sopsRoot + /dae-imxyy-nix-server.dae;
format = "binary";
};
services.dae = {
enable = true;
configFile = config.sops.secrets.dae-imxyy-nix-server.path;
};
systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = {
sopsFile = sopsRoot + /mihomo.yaml;
format = "yaml";
key = "";
};
systemd.services.mihomo.after = [ "sops-nix.service" ];
services.mihomo = {
enable = true;
configFile = config.sops.secrets.mihomo.path;
webui = pkgs.metacubexd;
};
sops.secrets.frp-env = {
sopsFile = sopsRoot + /frp.env;
format = "dotenv";
};
systemd.services.frp.serviceConfig.EnvironmentFile = [
config.sops.secrets.frp-env.path
];
services.frp = {
enable = true;
role = "client";
settings = {
serverAddr = "vkvm.imxyy.top";
serverPort = 7000;
auth.token = "{{ .Envs.FRP_AUTH_TOKEN }}";
proxies = [
{
name = "nextcloud-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "nextcloud-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "nextcloud.imxyy.top" ];
}
{
name = "oidc-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "oidc-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "oidc.imxyy.top" ];
}
{
name = "headscale-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "headscale.imxyy.top" ];
}
{
name = "headscale-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "headscale.imxyy.top" ];
}
{
name = "mail-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "mail-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "mail.imxyy.top" ];
}
{
name = "gitea-ssh";
type = "tcp";
localIP = "127.0.0.1";
localPort = 2222;
remotePort = 2222;
}
{
name = "gitea-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "git.imxyy.top" ];
}
{
name = "gitea-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "git.imxyy.top" ];
}
{
name = "vault-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "vault-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "vault.imxyy.top" ];
}
{
name = "home-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "home.imxyy.top" ];
}
{
name = "home-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "home.imxyy.top" ];
}
{
name = "coder-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "coder-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "coder.imxyy.top" ];
}
{
name = "music-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "music.imxyy.top" ];
}
{
name = "music-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "music.imxyy.top" ];
}
{
name = "ai-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "ai.imxyy.top" ];
}
{
name = "ai-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "ai.imxyy.top" ];
}
{
name = "grafana-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "grafana.imxyy.top" ];
}
{
name = "grafana-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "grafana.imxyy.top" ];
}
{
name = "note-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "note.imxyy.top" ];
}
{
name = "note-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "note.imxyy.top" ];
}
{
name = "siyuan-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "siyuan-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "sy.imxyy.top" ];
}
{
name = "matrix-http";
type = "http";
localIP = "127.0.0.1";
localPort = 80;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "matrix-https";
type = "https";
localIP = "127.0.0.1";
localPort = 443;
customDomains = [ "matrix.imxyy.top" ];
}
{
name = "minecraft";
type = "tcp";
localIP = "127.0.0.1";
localPort = 25565;
remotePort = 25565;
}
];
};
};
services.tailscale = {
enable = true;
useRoutingFeatures = "both";
extraSetFlags = [ "--accept-dns=false" ];
};
services.headscale = {
enable = true;
address = "0.0.0.0";
port = 8080;
settings = {
logtail.enabled = false;
server_url = "https://headscale.imxyy.top";
dns = {
base_domain = "tailnet.imxyy.top";
extra_records = [
{
"name" = "home.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "nextcloud.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "mail.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "git.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "vault.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "mc.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "home.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "coder.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
{
"name" = "music.imxyy.top";
"type" = "A";
"value" = "100.64.0.2";
}
];
};
ip_prefixes = "100.64.0.0/10";
derp.paths = [
(toString (
pkgs.writeText "derp.yaml" ''
regions:
900:
regionid: 900
regioncode: custom-tok
regionname: imxyy_soope_ Tokyo
nodes:
- name: 900a
regionid: 900
hostname: vkvm.imxyy.top
# 901:
# regionid: 901
# regioncode: custom-cn
# regionname: imxyy_soope_ Hu Bei
# nodes:
# - name: 901a
# regionid: 901
# hostname: ry.imxyy.top
# derpport: 1443
''
))
];
derp.urls = lib.mkForce [ ];
oidc = {
only_start_if_oidc_is_available = true;
issuer = "https://oidc.imxyy.top";
client_id = "https://headscale.imxyy.top";
allowed_domains = [
"imxyy.top"
"*.imxyy.top"
];
client_secret = "";
expiry = 0;
extra_params.domain_hint = "imxyy.top";
strip_email_domain = true;
};
};
};
systemd.services."headscale" = {
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
};
after = [
"podman-obligator.service"
];
requires = [
"podman-obligator.service"
];
};
sops.secrets.et-imxyy-nix-server = {
sopsFile = sopsRoot + /et-imxyy-nix-server.toml;
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier" = {
enable = true;
script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix-server.path}";
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
path = with pkgs; [
easytier
iproute2
bash
];
};
virtualisation.oci-containers = {
containers = {
obligator = {
image = "anderspitman/obligator:latest";
volumes = [
"/var/lib/obligator:/data"
"/var/lib/obligator:/api"
];
ports = [ "8081:1616" ];
cmd = [
"-storage-dir"
"/data"
"-api-socket-dir"
"/api"
"-root-uri"
"https://oidc.imxyy.top"
"-port"
"1616"
];
};
};
};
services.caddy.virtualHosts."headscale.imxyy.top" = {
extraConfig = ''
reverse_proxy :8080 {
header_up X-Real-IP {remote_host}
}
'';
};
services.caddy.virtualHosts."oidc.imxyy.top" = {
extraConfig = ''
reverse_proxy :8081 {
header_up X-Real-IP {remote_host}
}
'';
};
systemd.services.ddns-go =
let
ddns-go = pkgs.buildGoModule rec {
pname = "ddns-go";
version = "6.6.7";
src = pkgs.fetchFromGitHub {
owner = "jeessy2";
repo = "ddns-go";
rev = "v${version}";
hash = "sha256-Ejoe6e9GFhHxQ9oIBDgDRQW9Xx1XZK+qSAXiRXLdn+c=";
};
meta.mainProgram = "ddns-go";
vendorHash = "sha256-XZii7gV3DmTunYyGYzt5xXhv/VpTPIoYKbW4LnmlAgs=";
doCheck = false;
};
in
{
description = "Go Dynamic DNS";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
serviceConfig = {
ExecStart = "${lib.getExe ddns-go} -l :9876 -f 10 -cacheTimes 180 -c /var/lib/ddns-go/config.yaml";
Restart = "always";
RestartSec = 120;
};
};
services.dnsmasq =
let
subDomains = [
"home"
"nextcloud"
"mail"
"git"
"vault"
"coder"
"headscale"
"oidc"
"mc"
"music"
"ai"
];
in
{
enable = true;
resolveLocalQueries = false;
settings = {
server = [
"120.53.53.53"
"223.5.5.5"
];
address = map (sub: "/${sub}.imxyy.top/192.168.3.2") subDomains ++ [
"/imxyy-nix-server/192.168.3.2"
"/imxyy-cloudwin/192.168.3.4"
"/printer.home/192.168.3.53"
];
};
};
}

View File

@@ -0,0 +1,143 @@
{
lib,
pkgs,
hostname,
...
}:
let
nextcloud = "nextcloud.${imxyy}";
imxyy = "imxyy.top";
in
{
environment.systemPackages = with pkgs; [
exiftool
ffmpeg
rclone
];
services.nextcloud = {
enable = true;
package = pkgs.nextcloud31;
extraApps = {
inherit (pkgs.nextcloud31.packages.apps)
bookmarks
previewgenerator
spreed
notes
registration
;
};
extraAppsEnable = true;
hostName = nextcloud;
home = "/mnt/nas/nextcloud";
https = true;
nginx.recommendedHttpHeaders = true;
caching.redis = true;
configureRedis = true;
database.createLocally = true;
config = {
dbtype = "pgsql";
adminpassFile = toString (pkgs.writeText "nextcloud-pass" "admin12345!");
adminuser = "admin";
};
settings.trusted_domains = [
hostname
"192.168.3.2"
"10.0.0.1"
];
phpExtraExtensions =
all: with all; [
pdlib
];
maxUploadSize = "16G";
phpOptions = {
"opcache.enable" = 1;
"opcache.enable_cli" = 1;
"opcache.interned_strings_buffer" = 8;
"opcache.max_accelerated_files" = 10000;
"opcache.memory_consumption" = 128;
"opcache.save_comments" = 1;
"opcache.revalidate_freq" = 1;
memory_limit = lib.mkForce "2G";
};
poolSettings = {
pm = "dynamic";
"pm.max_children" = "12";
"pm.min_spare_servers" = "6";
"pm.max_spare_servers" = "12";
};
};
services.nginx.virtualHosts."nextcloud.imxyy.top" = {
listen = [
{
addr = "0.0.0.0";
port = 8084;
}
];
};
/*
services.caddy.virtualHosts.":80" = {
extraConfig = ''
redir https://{host}{uri}
'';
};
services.caddy.virtualHosts.":443" = {
extraConfig =
let
path = "/var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/nextcloud.imxyy.top";
in
''
reverse_proxy :8084
tls ${path}/nextcloud.imxyy.top.crt ${path}/nextcloud.imxyy.top.key
'';
};
*/
services.caddy.virtualHosts."nextcloud.imxyy.top" = {
extraConfig = ''
reverse_proxy :8084 {
header_up X-Real-IP {remote_host}
}
'';
};
/*
systemd.timers."kopia" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "kopia.service";
};
};
*/
systemd.services."kopia" = {
script = ''
${pkgs.kopia}/bin/kopia snapshot create /mnt/nas/share
${pkgs.kopia}/bin/kopia snapshot create /mnt/nas/nextcloud/data
'';
serviceConfig = {
Type = "oneshot";
User = "nextcloud";
};
};
systemd.timers."nextcloud-cronjobs" = {
wantedBy = [ "timers.target" ];
timerConfig = {
OnCalendar = "daily";
Persistent = true;
Unit = "nextcloud-cronjobs.service";
};
};
systemd.services."nextcloud-cronjobs" = {
script = ''
/run/current-system/sw/bin/nextcloud-occ preview:pre-generate
'';
serviceConfig = {
Type = "oneshot";
User = "nextcloud";
};
};
}

View File

@@ -0,0 +1,15 @@
{ ... }:
{
services.nginx = {
enable = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;
clientMaxBodySize = "0";
};
security.acme = {
acceptTerms = true;
defaults.email = "acme@imxyy.top";
};
}

View File

@@ -0,0 +1,32 @@
{
lib,
config,
username,
sopsRoot,
...
}:
{
boot.loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
grub.enable = false;
timeout = 0;
};
hardware.bluetooth.enable = true;
hardware.bluetooth.powerOnBoot = true;
systemd.services.nix-daemon = {
environment.TMPDIR = "/var/cache/nix";
serviceConfig.CacheDirectory = "nix";
};
environment.variables.NIX_REMOTE = "daemon";
sops.secrets.imxyy-nix-server-hashed-password = {
sopsFile = sopsRoot + /imxyy-nix-server-hashed-password.txt;
format = "binary";
};
users.users.${username}.hashedPasswordPath =
lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
users.users.root.hashedPassword = lib.mkForce config.sops.secrets.imxyy-nix-server-hashed-password.path;
}

View File

@@ -0,0 +1,61 @@
{
config,
sopsRoot,
...
}:
{
sops.secrets = {
flatnote-env = {
sopsFile = sopsRoot + /flatnote.env;
format = "dotenv";
};
siyuan-env = {
sopsFile = sopsRoot + /siyuan.env;
format = "dotenv";
};
};
virtualisation.oci-containers = {
containers = {
flatnotes = {
image = "dullage/flatnotes:latest";
volumes = [
"/mnt/nas/flatnotes/data:/data"
];
environmentFiles = [
"${config.sops.secrets.flatnote-env.path}"
];
ports = [ "8093:8080" ];
};
siyuan = {
image = "apkdv/siyuan-unlock:v3.1.24";
volumes = [
"/mnt/nas/siyuan/workspace:/workspace"
"/mnt/nas/siyuan:/home/siyuan"
];
cmd = [
"--workspace=/workspace"
];
environment = {
PUID = "0";
PGID = "0";
};
environmentFiles = [
"${config.sops.secrets.siyuan-env.path}"
];
ports = [ "8095:6806" ];
};
};
};
services.caddy.virtualHosts = {
"note.imxyy.top" = {
extraConfig = ''
reverse_proxy :8093
'';
};
"sy.imxyy.top" = {
extraConfig = ''
reverse_proxy :8095
'';
};
};
}

View File

@@ -0,0 +1,36 @@
{ ... }:
{
services.samba = {
enable = true;
nsswins = true;
settings = {
global = {
security = "user";
"netbios name" = "NAS";
};
share = {
path = "/mnt/nas/share";
browseable = "yes";
"read only" = "no";
"guest ok" = "no";
"create mask" = "0664";
"directory mask" = "0775";
"force user" = "nextcloud";
"force group" = "nextcloud";
};
};
};
services.samba-wsdd.enable = true;
# ensure dir exists
systemd.tmpfiles.rules = [
"d /mnt/nas/share 0775 nextcloud nextcloud - -"
];
users = {
users.nas = {
isNormalUser = true;
home = "/var/empty";
description = "nas user";
group = "nextcloud";
};
};
}

View File

@@ -0,0 +1,31 @@
{ config, sopsRoot, ... }:
{
sops.secrets.vaultwarden-env = {
sopsFile = sopsRoot + /vaultwarden.env;
format = "dotenv";
};
services.postgresql.ensureUsers = [
{
name = "vaultwarden";
ensureDBOwnership = true;
}
];
services.postgresql.ensureDatabases = [ "vaultwarden" ];
services.vaultwarden = {
enable = true;
dbBackend = "postgresql";
config = {
ROCKET_ADDRESS = "127.0.0.1";
ROCKET_PORT = 8083;
DOMAIN = "https://vault.imxyy.top";
};
environmentFile = "${config.sops.secrets.vaultwarden-env.path}";
};
services.caddy.virtualHosts."vault.imxyy.top" = {
extraConfig = ''
reverse_proxy :8083 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,28 @@
{ lib, ... }:
let
# T400
gpuIDs = [
"8086:56a0" # A770
"10de:1f82" # 1650
"10de:10fa" # 1650
"10de:1fb2" # T400
];
in
{
boot = {
initrd.kernelModules = [
"vfio_pci"
"vfio"
"vfio_iommu_type1"
];
kernelParams = [
"pcie_acs_override=downstream,multifunction"
"amd_iommu=on"
"vfio-pci.ids=${lib.concatStringsSep "," gpuIDs}"
];
};
virtualisation.spiceUSBRedirection.enable = true;
my.virt.enable = true;
}

View File

@@ -0,0 +1,24 @@
{ ... }:
{
virtualisation.oci-containers.containers."YesPlayMusic" = {
image = "git.imxyy.top/imxyy1soope1/yesplaymusic:latest";
environment = {
"NODE_TLS_REJECT_UNAUTHORIZED" = "0";
};
volumes = [
"/etc/localtime:/etc/localtime:ro"
];
ports = [
"8088:80/tcp"
];
log-driver = "journald";
};
services.caddy.virtualHosts."music.imxyy.top" = {
extraConfig = ''
reverse_proxy :8088 {
header_up X-Real-IP {remote_host}
}
'';
};
}

View File

@@ -0,0 +1,7 @@
{ ... }:
{
imports = [
./nixos.nix
./home.nix
];
}

View File

@@ -0,0 +1,13 @@
{ ... }:
{
my.home.programs.zsh.shellAliases = {
localproxy_on = "export http_proxy=http://192.168.128.1:7890 https_proxy=http://192.168.128.1:7890 all_proxy=socks://192.168.128.1:7890";
};
my = {
coding.all.enable = true;
cmd.misc.enable = true;
xdg.enable = true;
cmd.media.all.enable = true;
desktop.media.all.enable = true;
};
}

View File

@@ -0,0 +1,17 @@
{ username, nixos-wsl, ... }:
{
imports = [
nixos-wsl.nixosModules.wsl
];
wsl.enable = true;
wsl.defaultUser = "${username}";
services.openssh = {
enable = true;
settings = {
# Forbid root login through SSH.
PermitRootLogin = "no";
PasswordAuthentication = true;
};
};
}

View File

@@ -0,0 +1,10 @@
{ ... }:
{
imports = [
./nixos.nix
./hardware.nix
./home.nix
./virt.nix
./net.nix
];
}

View File

@@ -0,0 +1,165 @@
{
config,
lib,
pkgs,
username,
...
}:
{
boot = {
initrd = {
kernelModules = [ "amdgpu" ];
availableKernelModules = [
"xhci_pci"
"ahci"
"nvme"
"usbhid"
"usb_storage"
"sd_mod"
];
verbose = false;
};
kernelPackages = lib.mkForce pkgs.linuxKernel.packages.linux_zen;
kernelModules = [ "kvm-amd" ];
tmp.useTmpfs = true;
kernel.sysctl = {
"fs.file-max" = 9223372036854775807;
};
resumeDevice = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
kernelParams = [
"resume_offset=6444127"
# "quiet"
# "splash"
# "log_level=3"
];
consoleLogLevel = 3;
/*
plymouth = {
enable = true;
theme = "bgrt";
themePackages = [ pkgs.nixos-bgrt-plymouth ];
};
*/
};
fileSystems."/" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=root"
];
};
fileSystems."/nix" = {
device = "/dev/disk/by-uuid/843c36ae-f6d0-46a1-b5c7-8ab569e1e63f";
fsType = "btrfs";
options = [ "compress=zstd" ];
};
fileSystems."/persistent" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=persistent"
];
neededForBoot = true;
};
fileSystems."/swap" = {
device = "/dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c";
fsType = "btrfs";
options = [
"compress=zstd"
"subvol=swap"
];
neededForBoot = true;
};
boot.initrd.postDeviceCommands = lib.mkAfter ''
mkdir /btrfs_tmp
mount /dev/disk/by-uuid/0404de0a-9c4d-4c98-b3e5-b8ff8115f36c /btrfs_tmp
mkdir -p /btrfs_tmp/old_roots
if [[ -e /btrfs_tmp/root ]]; then
timestamp=$(date --date="@$(stat -c %Y /btrfs_tmp/root)" "+%Y-%m-%-d_%H:%M:%S")
mv /btrfs_tmp/root "/btrfs_tmp/old_roots/$timestamp"
fi
delete_subvolume_recursively() {
IFS=$'\n'
for i in $(btrfs subvolume list -o "$1" | cut -f 9- -d ' '); do
delete_subvolume_recursively "/btrfs_tmp/$i"
done
btrfs subvolume delete "$1"
}
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +14); do
delete_subvolume_recursively "$i"
done
btrfs subvolume create /btrfs_tmp/root
umount /btrfs_tmp
'';
fileSystems."/boot" = {
device = "/dev/disk/by-uuid/B7DC-E9AC";
fsType = "vfat";
};
fileSystems."/home/${username}/Documents" = {
device = "/dev/disk/by-uuid/a4e37dcd-764a-418c-aa1c-484f1fbd4bbe";
fsType = "ext4";
};
fileSystems."/home/${username}/Downloads" = {
device = "/dev/disk/by-uuid/18717cb4-49ac-40fa-95d4-29523a458dd0";
fsType = "ext4";
};
fileSystems."/home/${username}/Videos" = {
device = "/dev/disk/by-uuid/b67bbeab-58bc-4814-b5e3-08404e78b25e";
fsType = "ext4";
};
fileSystems."/home/${username}/Pictures" = {
device = "/dev/disk/by-uuid/a31bfe7e-cc17-4bd2-af74-ae5de9be35d3";
fsType = "ext4";
};
fileSystems."/home/${username}/Music" = {
device = "//192.168.3.2/share/imxyy_soope_/Music";
fsType = "cifs";
options = [
"username=nas"
"password=nasshare"
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"
"nodev"
"nofail"
"uid=1000"
"gid=100"
"vers=3"
"rw"
];
};
swapDevices = [
{
device = "/swap/swapfile";
size = 32 * 1024;
}
];
networking.useDHCP = lib.mkDefault false;
hardware.enableRedistributableFirmware = lib.mkDefault true;
hardware.cpu.amd.updateMicrocode = config.hardware.enableRedistributableFirmware;
nixpkgs.hostPlatform = lib.mkForce "x86_64-linux";
}

View File

@@ -0,0 +1,215 @@
{
config,
lib,
pkgs,
username,
...
}:
{
my.home = {
home.packages = with pkgs; [
localsend
rclone
wpsoffice-cn
wps-office-fonts
evince
# siyuan-unlock
anki
ayugram-desktop
telegram-desktop
signal-desktop
cinny-desktop
discord
qq
gnome-clocks
wineWowPackages.waylandFull
pavucontrol
pamixer
];
programs.zsh = {
shellAliases = {
cageterm = "cage -m DP-2 -s -- alacritty -o font.size=20";
cagefoot = "cage -m DP-2 -s -- foot --font=monospace:size=20";
cagekitty = "cage -m DP-2 -s -- kitty -o font_size=20";
};
sessionVariables = {
no_proxy = "192.168.3.0/24";
PATH = "/home/${username}/bin:$PATH";
};
profileExtra = ''
if [ `tty` = "/dev/tty1" -a $XDG_RUNTIME_DIR ]; then
echo 'Starting Niri...'
exec uwsm start niri-uwsm.desktop
elif [ `tty` = "/dev/tty6" ]; then
clear
fi
'';
};
programs.niri.settings.outputs = {
DP-2 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
position = {
x = 0;
y = 0;
};
};
DP-3 = {
enable = true;
mode = {
width = 2560;
height = 1440;
refresh = 75.033;
};
scale = 1.25;
};
};
};
my = {
autologin = {
enable = true;
user = "${username}";
ttys = [
1
6
];
};
gpg.enable = true;
cmd.all.enable = true;
coding.all.enable = true;
desktop.all.enable = true;
desktop.wm.dwm.enable = lib.mkForce false;
desktop.browser.librewolf.enable = lib.mkForce false;
i18n.fcitx5.enable = true;
xdg = {
enable = true;
defaultApplications =
let
browser = [ "chromium-browser.desktop" ];
editor = [ "codium.desktop" ];
imageviewer = [ "org.gnome.Shotwell-Viewer.desktop" ];
in
{
"inode/directory" = [ "nemo.desktop" ];
"application/pdf" = [ "evince.desktop" ];
"text/*" = editor;
"application/json" = editor;
"text/html" = editor;
"text/xml" = editor;
"application/xml" = editor;
"application/xhtml+xml" = editor;
"application/xhtml_xml" = editor;
"application/rdf+xml" = editor;
"application/rss+xml" = editor;
"application/x-extension-htm" = editor;
"application/x-extension-html" = editor;
"application/x-extension-shtml" = editor;
"application/x-extension-xht" = editor;
"application/x-extension-xhtml" = editor;
"x-scheme-handler/about" = browser;
"x-scheme-handler/ftp" = browser;
"x-scheme-handler/http" = browser;
"x-scheme-handler/https" = browser;
"x-scheme-handler/unknown" = browser;
"audio/*" = imageviewer;
"video/*" = imageviewer;
"image/*" = imageviewer;
"image/gif" = imageviewer;
"image/jpeg" = imageviewer;
"image/png" = imageviewer;
"image/webp" = imageviewer;
};
extraBookmarks =
let
homedir = config.my.home.home.homeDirectory;
in
[
"file://${homedir}/Documents/%E7%8F%AD%E7%BA%A7%E4%BA%8B%E5%8A%A1 "
"file://${homedir}/NAS NAS"
"file://${homedir}/NAS/imxyy_soope_ NAS imxyy_soope_"
"file://${homedir}/NAS/imxyy_soope_/OS NAS OS"
];
};
persist = {
enable = true;
homeDirs = [
".android"
"Android"
".ssh"
"bin"
"workspace"
"WineApps"
"Virt"
".cache"
".local/state"
".local/share/Anki2"
".local/share/dooit"
".local/share/nvim"
".local/share/shotwell"
".local/share/Steam"
".local/share/SteamOS"
".local/share/Trash"
".local/share/cheat.sh"
".local/share/Kingsoft"
".local/share/oss.krtirtho.spotube"
".local/share/AyuGramDesktop"
".local/share/TelegramDesktop"
".local/share/cinny"
".config/Signal"
".config/discord"
".config/QQ"
".config/Kingsoft"
".config/dconf"
".config/gh"
".config/pulse"
".config/chromium"
".config/go-musicfox/db"
".config/tmux/plugins"
".config/pip"
".config/obs-studio"
".config/libreoffice"
".config/Moonlight Game Streaming Project"
".config/sunshine"
];
nixosDirs = [
"/etc/ssh"
];
homeFiles = [
".config/mpd/mpd.db" # requires bindfs
".config/go-musicfox/cookie"
".hmcl.json"
];
nixosFiles = [
"/etc/davfs2/secrets"
];
};
};
}

View File

@@ -0,0 +1,136 @@
{
config,
lib,
pkgs,
sopsRoot,
...
}:
{
boot.kernelParams = [
"biosdevname=0"
"net.ifnames=0"
];
networking = {
useDHCP = lib.mkForce false;
dhcpcd = {
wait = "background";
IPv6rs = true;
extraConfig = ''
interface eth0
noipv4
'';
};
interfaces = {
eth0 = {
useDHCP = lib.mkForce true;
wakeOnLan.enable = true;
macAddress = "3C:7C:3F:7C:D3:9D";
ipv4 = {
addresses = [
{
address = "192.168.3.3";
prefixLength = 24;
}
];
};
};
};
defaultGateway = {
address = "192.168.3.1";
interface = "eth0";
};
nameservers = [
"192.168.3.2"
];
firewall.enable = false;
nftables = {
enable = true;
flushRuleset = true;
ruleset = ''
table inet firewall {
set LANv4 {
type ipv4_addr
flags interval
elements = { 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16 }
}
set LANv6 {
type ipv6_addr
flags interval
elements = { fd00::/8, fe80::/10 }
}
chain output {
type filter hook output priority 100; policy accept;
}
chain input {
type filter hook input priority 0; policy drop;
iif lo accept
ct state invalid drop
ct state established,related accept
ip saddr @LANv4 accept
ip6 saddr @LANv6 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
}
'';
};
};
sops.secrets.dae-imxyy-nix = {
sopsFile = sopsRoot + /dae-imxyy-nix.dae;
format = "binary";
};
services.dae = {
enable = true;
configFile = config.sops.secrets.dae-imxyy-nix.path;
};
systemd.services.dae.after = [ "sops-nix.service" ];
sops.secrets.mihomo = {
sopsFile = sopsRoot + /mihomo.yaml;
format = "yaml";
key = "";
};
systemd.services.mihomo.after = [ "sops-nix.service" ];
services.mihomo = {
enable = true;
configFile = config.sops.secrets.mihomo.path;
webui = pkgs.metacubexd;
};
services.tailscale.enable = true;
sops.secrets.et-imxyy-nix = {
sopsFile = sopsRoot + /et-imxyy-nix.toml;
format = "binary";
};
environment.systemPackages = [ pkgs.easytier ];
systemd.services."easytier" = {
enable = true;
script = "easytier-core -c ${config.sops.secrets.et-imxyy-nix.path}";
serviceConfig = {
Restart = lib.mkOverride 500 "always";
RestartMaxDelaySec = lib.mkOverride 500 "1m";
RestartSec = lib.mkOverride 500 "100ms";
RestartSteps = lib.mkOverride 500 9;
User = "root";
};
wantedBy = [ "multi-user.target" ];
after = [
"network.target"
"sops-nix.service"
];
path = with pkgs; [
easytier
iproute2
bash
];
};
}

View File

@@ -0,0 +1,319 @@
{
lib,
pkgs,
username,
...
}:
let
btreset = pkgs.writeScriptBin "btreset" ''
#!${lib.getExe pkgs.python3}
import subprocess
import os
import sys
SYM = "BT"
def action(line: str) -> bool:
if line.find(SYM) == -1:
return False
temp = line.split(" ")
bus = temp[1]
device = temp[3][:-1]
subprocess.run(["${lib.getExe usbreset}", f"/dev/bus/usb/{bus}/{device}"])
return True
if __name__ == "__main__":
if os.path.exists("/tmp/.btreseted") and len(sys.argv) == 1 and "-f" not in sys.argv[1:]:
exit(0)
res_byte = subprocess.check_output("/run/current-system/sw/bin/lsusb")
res = res_byte.decode()
lst = res.split("\n")
if any(tuple(map(action, lst))):
with open("/tmp/.btreseted", "w"):
...
'';
usbreset = pkgs.writeCBin "usbreset" ''
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>
int main(int argc, char **argv)
{
const char *filename;
int fd;
int rc;
if (argc != 2) {
fprintf(stderr, "Usage: usbreset device-filename\n");
return 1;
}
filename = argv[1];
fd = open(filename, O_WRONLY);
if (fd < 0) {
perror("Error opening output file");
return 1;
}
printf("Resetting USB device %s\n", filename);
rc = ioctl(fd, USBDEVFS_RESET, 0);
if (rc < 0) {
perror("Error in ioctl");
return 1;
}
printf("Reset successful\n");
close(fd);
return 0;
}
'';
in
{
security.pam.loginLimits = [
{
domain = "*";
type = "soft";
item = "nofile";
value = "524288";
}
];
systemd.services.btreset = {
script = lib.getExe btreset;
wantedBy = [ "multi-user.target" ];
serviceConfig.Type = "oneshot";
};
boot.kernelParams = [
"usbcore.autosuspend=-1" # Avoid usb autosuspend (for usb bluetooth adapter)
"fsck.mode=skip"
];
boot.loader = {
efi.canTouchEfiVariables = true;
systemd-boot.enable = true;
grub.enable = false;
timeout = 0;
};
hardware.graphics.enable = true;
hardware.graphics.enable32Bit = true;
systemd.services.nix-daemon = {
environment.TMPDIR = "/var/cache/nix";
serviceConfig.CacheDirectory = "nix";
};
environment.variables.NIX_REMOTE = "daemon";
# services.pipewire.enable = false;
security.rtkit.enable = true;
services.pipewire = {
enable = true;
# alsa.enable = true;
# alsa.support32Bit = true;
# pulse.enable = true;
alsa.enable = false;
alsa.support32Bit = false;
pulse.enable = false;
audio.enable = false;
configPackages = [
/*
(pkgs.writeTextDir "share/pipewire/media-session.d/bluez-monitor.conf" ''
rules = [
{
actions = {
update-props = {
bluez5.autoswitch-profile = true;
}
}
}
]
'')
*/
];
};
services.pipewire.wireplumber.extraConfig = {
/*
"10-bluez" = {
"monitor.bluez.properties" = {
"bluez5.enable-sbc-xq" = true;
"bluez5.enable-msbc" = true;
"bluez5.enable-hw-volume" = true;
"bluez5.roles" = [
"hsp_hs"
"hsp_ag"
"hfp_hf"
"hfp_ag"
];
};
};
*/
/*
"11-bluetooth-policy" = {
"wireplumber.settings" = {
"bluetooth.autoswitch-to-headset-profile" = false;
};
};
*/
};
services.pulseaudio = {
enable = true;
support32Bit = true;
package = pkgs.pulseaudioFull;
extraConfig = ''
load-module module-switch-on-connect
unload-module module-suspend-on-idle
'';
};
hardware.bluetooth = {
enable = true;
powerOnBoot = true;
settings = {
General.Enable = "Source,Sink,Media,Socket";
};
};
users.extraUsers.${username}.extraGroups = [ "audio" ];
fonts = {
enableDefaultPackages = false;
fontDir.enable = true;
packages = with pkgs; [
noto-fonts
noto-fonts-cjk-sans
noto-fonts-emoji
jetbrains-mono
nerd-fonts.symbols-only
];
fontconfig.defaultFonts = {
serif = [
"Noto Serif CJK SC"
"Noto Serif"
"Symbols Nerd Font"
"Noto Color Emoji"
];
sansSerif = [
"Noto Sans CJK SC"
"Noto Sans"
"Symbols Nerd Font"
"Noto Color Emoji"
];
monospace = [
"JetBrains Mono"
"Noto Sans Mono CJK SC"
"Symbols Nerd Font Mono"
"Noto Color Emoji"
];
emoji = [ "Noto Color Emoji" ];
};
};
services.printing.enable = true;
services.keyd = {
enable = true;
keyboards.default.settings = {
main = {
capslock = "overload(control, esc)";
home = "end";
};
shift = {
home = "home";
};
control = {
delete = "print";
};
};
};
services.gvfs.enable = true;
virtualisation.waydroid.enable = true;
programs.wireshark.enable = true;
programs.wireshark.package = pkgs.wireshark;
users.users.${username}.extraGroups = [ "wireshark" ];
services.sunshine = {
enable = true;
autoStart = true;
capSysAdmin = true;
applications.apps = [
{
name = "Desktop";
image-path = "desktop.png";
}
];
};
services.openssh = {
enable = true;
settings = {
# Forbid root login through SSH.
PermitRootLogin = null;
PasswordAuthentication = true;
};
};
environment.systemPackages = [
pkgs.rclone
btreset
];
fileSystems =
let
config = pkgs.writeText "rclone.conf" ''
[Nextcloud]
type = webdav
url = https://192.168.3.2/remote.php/dav/files/imxyy_soope_
vendor = nextcloud
user = imxyy_soope_
pass = C2UUiMyPoynWWKS9kf_Fr8rcoXxgUswPYi4s
[NAS]
type = smb
host = 192.168.3.2
user = nas
pass = O74S6-7jDFykwCvZ8vuIxohh00Ty7XJF
'';
in
{
"/home/${username}/Nextcloud" = {
device = "Nextcloud:";
fsType = "rclone";
options = [
"nodev"
"nofail"
"allow_other"
"args2env"
"config=${toString config}"
"uid=1000"
"gid=100"
"rw"
"no-check-certificate"
"vfs-cache-mode=full"
];
};
"/home/${username}/NAS" = {
device = "//192.168.3.2/share";
fsType = "cifs";
options = [
"username=nas"
"password=nasshare"
"x-systemd.automount,noauto,x-systemd.idle-timeout=60,x-systemd.device-timeout=5s,x-systemd.mount-timeout=5s"
"nodev"
"nofail"
"uid=1000"
"gid=100"
"vers=3"
"rw"
];
};
};
}

View File

@@ -0,0 +1,35 @@
{
"version": 1,
"rules": [
{
"domain": [
"cm.steampowered.com",
"ol.epicgames.com",
"csgo.wmsj.cn",
"dota2.wmsj.cn",
"wmsjsteam.com",
"dl.steam.clngaa.com",
"dl.steam.ksyna.com",
"gstore.val.manlaxy.com",
"st.dl.bscstorage.net",
"st.dl.eccdnx.com",
"st.dl.pinyuncloud.com",
"steampipe.steamcontent.tnkjmec.com",
"steampowered.com.8686c.com",
"steamstatic.com.8686c.com",
"steambroadcast.akamaized.net",
"steamcdn-a.akamaihd.net",
"steamcommunity-a.akamaihd.net",
"steamstore-a.akamaihd.net",
"steamusercontent-a.akamaihd.net",
"steamuserimages-a.akamaihd.net"
],
"domain_suffix": [
".steamcontent.com",
".steamserver.net",
".steamchina.com"
],
"invert": false
}
]
}

View File

@@ -0,0 +1,12 @@
{
...
}:
{
hardware.graphics.enable = true;
virtualisation.spiceUSBRedirection.enable = true;
my.virt = {
enable = true;
moonlight.enable = true;
};
}