diff --git a/flake.lock b/flake.lock index 4240a48..50dd949 100644 --- a/flake.lock +++ b/flake.lock @@ -513,11 +513,11 @@ }, "nixpkgs_2": { "locked": { - "lastModified": 1731815985, - "narHash": "sha256-PgX3UFz1YESfEeGmp2HYYBc/3Vp59bPbBLtNN4VMIgI=", + "lastModified": 1731819057, + "narHash": "sha256-nfqKsQhFCakM+eIKGf/JWu/g56rOPoGny10EZN8q7R0=", "owner": "xinyangli", "repo": "nixpkgs", - "rev": "5ddf4ef59567ff1e43adacde9f677f2cbd958287", + "rev": "b2644ed7258502987ad4a70cf8959bf5a26ce26d", "type": "github" }, "original": { @@ -555,11 +555,11 @@ }, "nur": { "locked": { - "lastModified": 1731815686, - "narHash": "sha256-6HPZVrwQOZzeaW5QseyXnghK76a3aDnRoQf+L+cpNms=", + "lastModified": 1731819675, + "narHash": "sha256-GGp/rEfxRdi1BD9TlHoXxp2g9IuKDp0Jk7wYh1LacP8=", "owner": "nix-community", "repo": "NUR", - "rev": "4cde5b2ea07d8c05570d7305738a9870b1a14700", + "rev": "59740d792bea5caa547c9bc7ce366802ecfafb7f", "type": "github" }, "original": { diff --git a/home/xin/calcite.nix b/home/xin/calcite.nix index 3b3c4ea..11dd9ed 100644 --- a/home/xin/calcite.nix +++ b/home/xin/calcite.nix @@ -38,6 +38,8 @@ in remmina qq wechat-uos + wpsoffice + ttf-wps-fonts ]; # Theme diff --git a/machines/calcite/configuration.nix b/machines/calcite/configuration.nix index 60480c1..8d0100c 100644 --- a/machines/calcite/configuration.nix +++ b/machines/calcite/configuration.nix @@ -16,6 +16,7 @@ in ]; commonSettings = { + auth.enable = true; nix = { enableMirrors = true; signing.enable = true; @@ -114,13 +115,15 @@ in xdg.portal = { enable = true; extraPortals = [ - pkgs.xdg-desktop-portal-gtk pkgs.xdg-desktop-portal-gnome + pkgs.xdg-desktop-portal-gtk ]; configPackages = [ pkgs.niri ]; }; systemd.user.services.xdg-desktop-portal-gtk.after = [ "graphical-session.target" ]; + systemd.user.services.xdg-desktop-portal-gnome.after = [ "graphical-session.target" ]; + systemd.user.services.xdg-desktop-portal-gnome.wantedBy = [ "graphical-session.target" ]; services.greetd = let @@ -281,7 +284,6 @@ in # Writting zotero # onlyoffice-bin - wpsoffice config.nur.repos.linyinfeng.wemeet diff --git a/machines/dolomite/default.nix b/machines/dolomite/default.nix index 32e2425..e3bb640 100644 --- a/machines/dolomite/default.nix +++ b/machines/dolomite/default.nix @@ -58,31 +58,8 @@ in exporters.blackbox.enable = true; }; - custom.kanidm-client = { - enable = true; - uri = "https://auth.xinyang.life/"; - asSSHAuth = { - enable = true; - allowedGroups = [ "linux_users" ]; - }; - sudoers = [ "xin@auth.xinyang.life" ]; - }; - - services.openssh = { - settings = { - PasswordAuthentication = false; - KbdInteractiveAuthentication = false; - PermitRootLogin = lib.mkForce "no"; - GSSAPIAuthentication = "no"; - KerberosAuthentication = "no"; - }; - }; - services.fail2ban.enable = true; - programs.mosh.enable = true; - - security.sudo = { - execWheelOnly = true; - wheelNeedsPassword = false; + custom.commonSettings = { + auth.enable = true; }; services.sing-box = diff --git a/modules/home-manager/gui/niri.nix b/modules/home-manager/gui/niri.nix index 8eb07b6..d26bf93 100644 --- a/modules/home-manager/gui/niri.nix +++ b/modules/home-manager/gui/niri.nix @@ -84,8 +84,12 @@ in enable = true; timeouts = [ { - timeout = 900; - command = "/run/current-system/systemd/bin/systemctl suspend"; + timeout = 600; + command = ''[ "$(${pkgs.tlp}/bin/tlp-stat -m)" == "battery" ] && /run/current-system/systemd/bin/systemctl suspend''; + } + { + timeout = 1200; + command = ''${getExe pkgs.niri} msg action power-off-monitors''; } ]; events = [ diff --git a/modules/home-manager/xdg-autostart.nix b/modules/home-manager/xdg-autostart.nix new file mode 100644 index 0000000..d2127ae --- /dev/null +++ b/modules/home-manager/xdg-autostart.nix @@ -0,0 +1,96 @@ +{ + config, + pkgs, + lib, + ... +}: +let + cfg = config.xdg.autoStart; + inherit (lib) hm types; +in +{ + + options.xdg.autoStart = { + + packages = lib.mkOption { + description = '' + List of packages which should be autostarted. + + This module tries to select the package’s default desktop file, + which is either described by its .desktopItem attribute + or by its first entry of its .desktopItems attribute. + + Users who want to specifically select a certain desktop file + or who want to write their own + can make use of the {option}`xdg.autoStart.desktopItems` option. + ''; + + type = types.listOf types.package; + default = [ ]; + example = lib.literalExpression '' + with pkgs; [ + pkgs.trilium-desktop + ] + ''; + }; + + desktopItems = lib.mkOption { + description = '' + List of desktop files which should be autostarted. + + Users should prefer to use {option}`xdg.autoStart.packages` + and only use this option in case + they want to specifically + select a package’s desktop item + or want to create their own desktop item. + + Be warned, this may shadow entries of {option}`xdg.autoStart.packages`. + ''; + + type = types.attrsOf (types.unspecified); # TODO replace unspecified + default = { }; + # TODO improve example, take one where it would make sense to use this option + example = lib.literalExpression '' + { + discord = pkgs.discord.desktopItem + firefox-custom = makeDesktopItem { + exec = "firefox -P custom"; + }; + } + ''; + }; + + }; + + config = + let + # helpers + retrieveDesktopItem = ( + pkg: + if pkg ? desktopItem then + pkg.desktopItem + else if pkg ? desktopItems && pkg.desktopItems != [ ] then + builtins.head pkg.desktopItems + else + abort "package '${pkg.pname}' is missing a desktop file" + ); + emulateDesktopItem = (pkg: lib.nameValuePair pkg.pname (retrieveDesktopItem pkg)); + embedDesktopItem = ( + name: deskItem: + lib.nameValuePair "autostart/${name}.desktop" { + source = "${deskItem}/share/applications/${deskItem.name}"; + } + ); + # parse opts + desktopItemsPackages = builtins.listToAttrs (map emulateDesktopItem cfg.packages); + desktopItems = desktopItemsPackages // cfg.desktopItems; + in + { + assertions = [ + (hm.assertions.assertPlatform "xdg.autoStart" pkgs lib.platforms.linux) + ]; + + xdg.configFile = lib.attrsets.mapAttrs' embedDesktopItem desktopItems; + }; + +} diff --git a/modules/home-manager/zellij.nix b/modules/home-manager/zellij.nix index d925365..fcb8f04 100644 --- a/modules/home-manager/zellij.nix +++ b/modules/home-manager/zellij.nix @@ -26,10 +26,9 @@ in bind "Ctrl l" { MoveFocusOrTab "Right"; } bind "Ctrl j" { MoveFocus "Down"; } bind "Ctrl k" { MoveFocus "Up"; } - unbind "Alt h" "Alt l" "Alt j" "Alt k" + unbind "Alt h" "Alt l" "Alt j" "Alt k" "Alt f" } unbind "Ctrl p" "Ctrl n" - unbind "Alt f" } ''; }; diff --git a/modules/nixos/common-settings/proxy-server.nix b/modules/nixos/common-settings/proxy-server.nix new file mode 100644 index 0000000..a6b5af9 --- /dev/null +++ b/modules/nixos/common-settings/proxy-server.nix @@ -0,0 +1,165 @@ +{ + config, + lib, + pkgs, + ... +}: + +let + inherit (lib) + mkIf + mkEnableOption + mkOption + types + ; + + cfg = config.commonSettings.proxyServer; + + singTls = { + enabled = true; + server_name = config.deployment.targetHost; + key_path = config.security.acme.certs.${config.deployment.targetHost}.directory + "/key.pem"; + certificate_path = + config.security.acme.certs.${config.deployment.targetHost}.directory + "/cert.pem"; + }; + + mkSingConfig = + { uuid, password, ... }: + { + inbounds = + [ + { + tag = "sg0"; + type = "trojan"; + listen = "::"; + listen_port = 8080; + users = [ + { + name = "proxy"; + password = password; + } + ]; + tls = singTls; + } + ] + ++ lib.forEach (lib.range 6311 6314) (port: { + tag = "sg" + toString (port - 6310); + type = "tuic"; + listen = "::"; + listen_port = port; + congestion_control = "bbr"; + users = [ + { + name = "proxy"; + uuid = uuid; + password = password; + } + ]; + tls = singTls; + }); + outbounds = [ + { + type = "wireguard"; + tag = "wg-out"; + private_key = { + _secret = config.sops.secrets.wg_private_key.path; + }; + local_address = [ + "172.16.0.2/32" + { _secret = config.sops.secrets.wg_ipv6_local_addr.path; } + ]; + peers = [ + { + public_key = "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo="; + allowed_ips = [ + "0.0.0.0/0" + "::/0" + ]; + server = "162.159.192.1"; + server_port = 500; + } + ]; + } + { + type = "direct"; + tag = "direct"; + } + ]; + route = { + rules = [ + { + inbound = "sg0"; + outbound = "direct"; + } + { + inbound = "sg4"; + outbound = "direct"; + } + ]; + }; + }; +in +{ + options.commonSettings.proxyServer = { + enable = mkEnableOption "sing-box as a server"; + uuidFile = mkOption { + type = types.path; + }; + passwordFile = mkOption { + type = types.path; + }; + }; + + config = mkIf cfg.enable { + boot.kernel.sysctl = { + "net.core.default_qdisc" = "fq"; + "net.ipv4.tcp_congestion_control" = "bbr"; + }; + + networking.firewall.trustedInterfaces = [ "tun0" ]; + + sops = { + secrets = { + wg_private_key = { + owner = "root"; + sopsFile = ./secrets + "/${config.networking.hostName}.yaml"; + }; + wg_ipv6_local_addr = { + owner = "root"; + sopsFile = ./secrets + "/${config.networking.hostName}.yaml"; + }; + }; + }; + + security.acme = { + acceptTerms = true; + certs.${config.deployment.targetHost} = { + email = "me@namely.icu"; + # Avoid port conflict + listenHTTP = if config.services.caddy.enable then ":30310" else ":80"; + }; + }; + services.caddy.virtualHosts."http://${config.deployment.targetHost}:80".extraConfig = '' + reverse_proxy 127.0.0.1:30310 + ''; + + networking.firewall.allowedTCPPorts = [ + 80 + 8080 + ]; + networking.firewall.allowedUDPPorts = [ ] ++ (lib.range 6311 6314); + + custom.prometheus = { + enable = true; + exporters.blackbox.enable = true; + }; + + services.sing-box = { + enable = true; + settings = mkSingConfig { + uuid = cfg.uuidFile; + password = cfg.passwordFile; + }; + }; + }; +}