diff options
Diffstat (limited to 'modules')
34 files changed, 1555 insertions, 1737 deletions
diff --git a/modules/nixfiles/chromium.nix b/modules/nixfiles/chromium.nix index 337acc8..20b5347 100644 --- a/modules/nixfiles/chromium.nix +++ b/modules/nixfiles/chromium.nix @@ -11,24 +11,16 @@ in { config = mkIf cfg.enable { hm = { - home = { - # sessionVariables.BROWSER = mkOverride 300 "chromium"; - - packages = with pkgs; [profile-cleaner]; - }; + home.packages = with pkgs; [profile-cleaner]; programs.chromium = { enable = true; package = pkgs.chromium; - extensions = - [ - {id = "cjpalhdlnbpafiamejdnhcphjbkeiagm";} # UBlock Origin - ] - ++ optional config.nixfiles.modules.kde.enable { - id = "cimiefiiaegbelhefglklhhakcgmhkai"; # KDE Plasma Integration - }; + extensions = [ + {id = "cjpalhdlnbpafiamejdnhcphjbkeiagm";} # Unblock Origin + ]; }; }; diff --git a/modules/nixfiles/common/documentation.nix b/modules/nixfiles/common/documentation.nix index 7f819a8..6e15aec 100644 --- a/modules/nixfiles/common/documentation.nix +++ b/modules/nixfiles/common/documentation.nix @@ -8,6 +8,15 @@ with lib; { config = mkMerge [ (mkIf this.isHeadful { + hm.manual = { + html.enable = false; + json.enable = false; + # FIXME Temporary workaround. + # https://github.com/nix-community/home-manager/issues/3342 + # https://github.com/NixOS/nixpkgs/issues/196651 + manpages.enable = false; + }; + documentation = { enable = true; diff --git a/modules/nixfiles/common/home-manager.nix b/modules/nixfiles/common/home-manager.nix index 91f6705..7ce872b 100644 --- a/modules/nixfiles/common/home-manager.nix +++ b/modules/nixfiles/common/home-manager.nix @@ -10,21 +10,16 @@ with lib; { (mkAliasOptionModule ["hm"] ["home-manager" "users" my.username]) ]; + hm = { + news.display = "silent"; + home = {inherit (config.system) stateVersion;}; + }; + home-manager = { backupFileExtension = "bak"; useUserPackages = true; useGlobalPkgs = true; verbose = true; - - users = - mapListToAttrs (_: { - home = { - inherit (config.system) stateVersion; - }; - }) [ - "root" - my.username - ]; }; system.extraDependencies = [inputs.home-manager]; diff --git a/modules/nixfiles/common/locale.nix b/modules/nixfiles/common/locale.nix index 34a738b..5f0d5ae 100644 --- a/modules/nixfiles/common/locale.nix +++ b/modules/nixfiles/common/locale.nix @@ -1,6 +1,15 @@ {lib, ...}: with lib; { - i18n.defaultLocale = mkDefault "en_GB.UTF-8"; + i18n = { + defaultLocale = mkDefault "en_GB.UTF-8"; + supportedLocales = [ + "C.UTF-8/UTF-8" + "en_GB.UTF-8/UTF-8" + "en_US.UTF-8/UTF-8" + "ja_JP.UTF-8/UTF-8" + "ru_RU.UTF-8/UTF-8" + ]; + }; time.timeZone = mkDefault "Europe/Moscow"; diff --git a/modules/nixfiles/common/security.nix b/modules/nixfiles/common/security.nix index 30b4276..09c5da1 100644 --- a/modules/nixfiles/common/security.nix +++ b/modules/nixfiles/common/security.nix @@ -26,23 +26,4 @@ with lib; { ''; }; }; - - # Remove this later. - # imports = ["${inputs.nixpkgs-pr-please}/nixos/modules/security/please.nix"]; - # security.please = { - # enable = true; - # settings.root = { - # name = my.username; - # target = "root"; - # rule = ".*"; - # require_pass = false; - # }; - # settings.root_edit = { - # name = my.username; - # type = "edit"; - # target = "root"; - # rule = ".*"; - # require_pass = false; - # }; - # }; } diff --git a/modules/nixfiles/emacs/default.nix b/modules/nixfiles/emacs/default.nix index 41ef523..732cab5 100644 --- a/modules/nixfiles/emacs/default.nix +++ b/modules/nixfiles/emacs/default.nix @@ -47,10 +47,6 @@ in { pyflakes # :lang python python-lsp-server # :lang (python +lsp) ])) - python3Packages.black - python3Packages.isort - python3Packages.pyflakes - python3Packages.python-lsp-server asmfmt # :editor format bash-language-server # :lang (sh +lsp) clang-tools # :lang (cc +lsp) :editor format @@ -60,6 +56,7 @@ in { dockerfile-language-server # :tools (docker +lsp) editorconfig # :tools editorconfig fd # doom! + gdb # :tools debugger gnuplot # :lang (org +gnuplot) gnutls # doom! gomodifytags # :lang go @@ -77,6 +74,7 @@ in { html-tidy # :lang web jre # :lang plantuml json-language-server # :lang (json +lsp) + lldb # :tools debugger lua-language-server # :lang (lua +lsp) nix-language-server # :lang (nix +lsp) nixfmt # :lang nix :editor format @@ -84,6 +82,7 @@ in { nodePackages.lua-fmt # :lang lua :editor format nodePackages.prettier # :editor format nodePackages.stylelint # :lang web + nodejs # :tools debugger pandoc # :lang org markdown latex pinentry-emacs # doom! pre-commit # :tools magit @@ -94,6 +93,7 @@ in { shfmt # :lang sh :editor format sqlite # :lang (org +roam2) :tools lookup texlive.combined.scheme-full # :lang org tex + unzip # :tools debugger wordnet # :tools (lookup +dictionary +offline) xclip # :app everywhere xdotool # :app everywhere @@ -113,6 +113,8 @@ in { concatMapStringsSep ":" (x: "${x}/bin") extraBins }")) + (setq custom-file (file-name-concat doom-emacs-dir "custom.el")) + (setq doom-font (font-spec :family "${config.fontScheme.monospaceFont.family}" :size ${toString config.fontScheme.monospaceFont.size}) doom-unicode-font doom-font) diff --git a/modules/nixfiles/emacs/doom/init.el b/modules/nixfiles/emacs/doom/init.el index 718d5cb..1bf1ca2 100644 --- a/modules/nixfiles/emacs/doom/init.el +++ b/modules/nixfiles/emacs/doom/init.el @@ -79,11 +79,11 @@ :lang (cc +lsp +tree-sitter) - common-lisp + ;; (common-lisp +lsp +tree-sitter) ;; (csharp +lsp +tree-sitter) data - dhall - emacs-lisp + ;; (dhall +lsp +tree-sitter) + (emacs-lisp +lsp +tree-sitter) (go +lsp +tree-sitter) ;; graphql (haskell +lsp +tree-sitter) @@ -91,29 +91,23 @@ (javascript +lsp +tree-sitter) json (latex +lsp +tree-sittter) - (lua +lsp +tree-sitter) - markdown + ;; (lua +lsp +tree-sitter) + (markdown +lsp +tree-sitter) (nix +lsp) - (org +hugo - +journal - +noter - +pandoc - +pomodoro - +present - +roam2) + (org +pandoc +roam2) plantuml (python +lsp +tree-sitter) ;; (racket +lsp +tree-sitter) ;; rst - (rust +lsp +tree-sitter) - ;; (scheme +racket) + ;; (rust +lsp +tree-sitter) + ;; (scheme +lsp +tree-sitter +racket) (sh +lsp +tree-sitter) - (web +lsp +tree-sitter) + web yaml - (zig +lsp +tree-sitter) + ;; (zig +lsp +tree-sitter) :email - (mu4e +org) + mu4e :app calendar diff --git a/modules/nixfiles/endlessh-go.nix b/modules/nixfiles/endlessh-go.nix index 56c415e..9ceb4e4 100644 --- a/modules/nixfiles/endlessh-go.nix +++ b/modules/nixfiles/endlessh-go.nix @@ -9,9 +9,6 @@ with lib; let cfg = config.nixfiles.modules.endlessh-go; in { - # Remove this later. - imports = ["${inputs.nixpkgs-pr-endlessh-go}/nixos/modules/services/security/endlessh-go.nix"]; - options.nixfiles.modules.endlessh-go.enable = mkEnableOption "endlessh-go"; config = let diff --git a/modules/nixfiles/firefox/default.nix b/modules/nixfiles/firefox/default.nix index 6dde7c3..d04adfd 100644 --- a/modules/nixfiles/firefox/default.nix +++ b/modules/nixfiles/firefox/default.nix @@ -1,5 +1,6 @@ { config, + inputs, lib, pkgs, ... @@ -11,41 +12,266 @@ in { config = mkIf cfg.enable { hm = { - home = { - # sessionVariables.BROWSER = mkOverride 200 "firefox"; - - packages = with pkgs; [ - (writeShellScriptBin "firefox-vanilla" '' - ${config.hm.programs.firefox.package}/bin/firefox -p vanilla "$@" - '') - profile-cleaner - ]; - }; + imports = [inputs.arkenfox-nixos.hmModules.arkenfox]; + + home.packages = with pkgs; [profile-cleaner]; programs.firefox = { enable = true; - package = pkgs.firefox.override { - cfg = with config.nixfiles.modules; { - enablePlasmaBrowserIntegration = kde.enable; - }; + arkenfox = { + enable = true; + version = "105.0"; }; - profiles.default = (import ./profile.nix) config lib; + profiles.default = let + mkCssWithRoot = css: + mkMerge [ + (with config.colourScheme; '' + :root { + --black: ${black}; + --red: ${red}; + --green: ${green}; + --yellow: ${yellow}; + --blue: ${blue}; + --magenta: ${magenta}; + --cyan: ${cyan}; + --white: ${white}; + --bright-black: ${brightBlack}; + --bright-red: ${brightRed}; + --bright-green: ${brightGreen}; + --bright-yellow: ${brightYellow}; + --bright-blue: ${brightBlue}; + --bright-magenta: ${brightMagenta}; + --bright-cyan: ${brightCyan}; + --bright-white: ${brightWhite}; + --background: ${background}; + --foreground: ${foreground}; + '') + (with config.fontScheme; '' + --sans-serif-font-family: "${sansSerifFont.family}", "${sansSerifFontFallback.family}", sans-serif; + --sans-serif-font-size: ${toString sansSerifFont.size}; + --serif-font-family: "${serifFont.family}", "${serifFontFallback.family}", serif; + --serif-font-size: ${toString serifFont.size}; + --monospace-font-family: "${monospaceFont.family}", "${monospaceFontFallback.family}", monospace; + --monospace-font-size: ${toString monospaceFont.size}; + } + '') + (builtins.readFile css) + ]; + in { + id = 0; + + isDefault = true; + + # A way to change the look of the Firefox itself. + userChrome = mkCssWithRoot ./userChrome.css; + + # A way to remove annoyances and visual bloat of many webpages. + userContent = mkCssWithRoot ./userContent.css; + + # https://github.com/arkenfox/user.js/blob/master/user.js + arkenfox = { + enable = true; + "0000".enable = true; + "0100" = { + enable = true; + "0102" = { + enable = true; + "browser.startup.page" = { + enable = true; + value = 3; + }; + }; + }; + "0200" = { + enable = true; + "0204" = { + enable = true; + "browser.search.region" = { + enable = true; + value = "US"; + }; + }; + "0210" = { + enable = true; + "intl.accept_languages" = { + enable = true; + value = "en-US, en"; + }; + }; + }; + "0300".enable = true; + "0400" = { + enable = false; + "0401" = { + enable = true; + "browser.safebrowsing.malware.enabled" = { + enable = true; + value = false; + }; + "browser.safebrowsing.phishing.enabled" = { + enable = true; + value = false; + }; + }; + "0402" = { + enable = true; + "browser.safebrowsing.downloads.enabled" = { + enable = true; + value = false; + }; + }; + "0404" = { + enable = true; + "browser.safebrowsing.downloads.remote.block_potentially_unwanted" = { + enable = true; + value = false; + }; + "browser.safebrowsing.downloads.remote.block_uncommon" = { + enable = true; + value = false; + }; + }; + }; + "0600".enable = true; + "0700" = { + enable = true; + "0701" = { + enable = true; + "network.dns.disableIPv6" = { + enable = true; + value = false; + }; + }; + "0710" = { + enable = true; + "network.trr.mode" = { + enable = true; + value = 5; + }; + }; + }; + "0800" = { + enable = true; + "0801" = { + enable = true; + "keyword.enabled" = { + enable = true; + value = true; + }; + }; + "0808" = { + enable = true; + "browser.urlbar.suggest.engines" = { + enable = true; + value = false; + }; + }; + "0810" = { + enable = true; + "browser.formfill.enable" = { + enable = true; + value = true; + }; + }; + }; + "0900".enable = true; + "1000" = { + enable = true; + "1001"."browser.cache.disk.enable" = { + enable = true; + value = true; + }; + }; + "1200" = { + enable = true; + }; + "1700" = { + enable = false; + "1701" = { + enable = true; + "privacy.userContext.enabled" = { + enable = true; + value = false; + }; + "privacy.userContext.ui.enabled" = { + enable = true; + value = false; + }; + }; + "1702" = { + enable = true; + "privacy.userContext.newTabContainerOnLeftClick.enabled" = { + enable = true; + value = false; + }; + }; + }; + "2000".enable = true; + "2400".enable = false; + "2600" = { + enable = true; + "2615" = { + enable = true; + "permissions.default.shortcuts" = { + enable = true; + value = 2; + }; + }; + }; + "2700".enable = true; + "2800".enable = true; + }; + + settings = { + "app.update.auto" = false; + "browser.bookmarks.max_backups" = 1; + "browser.disableResetPrompt" = true; + "browser.newtabpage.introShown" = true; + "browser.onboarding.enabled" = false; + "browser.search.update" = false; + "browser.startup.homepage_welcome_url" = ""; + "browser.startup.homepage_welcome_url.additional" = ""; + "browser.tabs.closeWindowWithLastTab" = true; + "browser.tabs.firefox-view" = false; + "browser.tabs.inTitlebar" = 1; + "browser.tabs.warnOnClose" = false; + "browser.tabs.warnOnCloseOtherTabs" = false; + "browser.tabs.warnOnOpen" = false; + "browser.toolbars.bookmarks.visibility" = "never"; + "browser.urlbar.decodeURLsOnCopy" = true; + "browser.warnOnQuitShortcut" = false; + "extensions.pocket.enabled" = false; + "extensions.screenshots.disabled" = true; + "extensions.update.autoUpdateDefault" = false; + "extensions.update.enabled" = false; + "full-screen-api.warning.delay" = 0; + "full-screen-api.warning.timeout" = 0; + "identity.fxaccounts.enabled" = false; + "media.autoplay.blocking_policy" = 2; + "media.autoplay.default" = 5; + "media.autoplay.enabled" = false; + "reader.parse-on-load.enabled" = false; + "signon.rememberSignons" = false; + "toolkit.legacyUserProfileCustomizations.stylesheets" = true; + }; + }; extensions = with pkgs.nur.repos.rycee.firefox-addons; + with config.nixfiles.modules; [ bitwarden darkreader - ipfs-companion libredirect noscript - stylus ublock-origin violentmonkey ] - ++ optional config.nixfiles.modules.kde.enable plasma-integration; + ++ optional ipfs.enable ipfs-companion; }; }; + + services.psd.enable = true; }; } diff --git a/modules/nixfiles/firefox/profile.nix b/modules/nixfiles/firefox/profile.nix deleted file mode 100644 index 2649402..0000000 --- a/modules/nixfiles/firefox/profile.nix +++ /dev/null @@ -1,480 +0,0 @@ -config: lib: -with lib; let - mkCssWithRoot = css: - mkMerge [ - (with config.colourScheme; '' - :root { - --black: ${black}; - --red: ${red}; - --green: ${green}; - --yellow: ${yellow}; - --blue: ${blue}; - --magenta: ${magenta}; - --cyan: ${cyan}; - --white: ${white}; - --bright-black: ${brightBlack}; - --bright-red: ${brightRed}; - --bright-green: ${brightGreen}; - --bright-yellow: ${brightYellow}; - --bright-blue: ${brightBlue}; - --bright-magenta: ${brightMagenta}; - --bright-cyan: ${brightCyan}; - --bright-white: ${brightWhite}; - --background: ${background}; - --foreground: ${foreground}; - '') - (with config.fontScheme; '' - --sans-serif-font-family: "${sansSerifFont.family}", "${sansSerifFontFallback.family}", sans-serif; - --sans-serif-font-size: ${toString sansSerifFont.size}; - --serif-font-family: "${serifFont.family}", "${serifFontFallback.family}", serif; - --serif-font-size: ${toString serifFont.size}; - --monospace-font-family: "${monospaceFont.family}", "${monospaceFontFallback.family}", monospace; - --monospace-font-size: ${toString monospaceFont.size}; - } - '') - (builtins.readFile css) - ]; -in { - id = 0; - - isDefault = true; - - # A way to change the look of the Firefox itself. - userChrome = mkCssWithRoot ./userChrome.css; - - # A way to remove annoyances and visual bloat of many webpages. - userContent = mkCssWithRoot ./userContent.css; - - # Mostly appropriated from https://github.com/arkenfox/user.js - settings = { - # Updates - # - "app.update.auto" = false; - "browser.search.update" = false; - "extensions.update.enabled" = false; - "extensions.update.autoUpdateDefault" = false; - # - "extensions.getAddons.cache.enabled" = false; - "extensions.getAddons.showPane" = false; - - # Telemetry - # - # https://bugzilla.mozilla.org/1195552 - "datareporting.healthreport.service.enabled" = false; - "datareporting.healthreport.uploadEnabled" = false; - "datareporting.policy.dataSubmissionEnabled" = false; - # https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/telemetry/internals/preferences.html - # https://medium.com/georg-fritzsche/data-preference-changes-in-firefox-58-2d5df9c428b5 - "toolkit.telemetry.unified" = false; - "toolkit.telemetry.server" = "data:,"; - "toolkit.telemetry.archive.enabled" = false; - "toolkit.telemetry.newProfilePing.enabled" = false; - "toolkit.telemetry.shutdownPingSender.enabled" = false; - "toolkit.telemetry.firstShutdownPing.enabled" = false; - "toolkit.telemetry.updatePing.enabled" = false; - "toolkit.telemetry.bhrPing.enabled" = false; # Background Hang Reporter - # https://blog.mozilla.org/data/2018/08/20/effectively-measuring-search-in-firefox - "toolkit.telemetry.coverage.opt-out" = true; - "toolkit.coverage.opt-out" = true; - "toolkit.coverage.endpoint.base" = ""; - - # Studies - # - # https://support.mozilla.org/en-US/kb/shield/ - "app.shield.optoutstudies.enabled" = false; - # https://mozilla.github.io/normandy/ - "app.normandy.enabled" = false; - "app.normandy.api_url" = ""; - - # Crash reports - # - "browser.tabs.crashReporting.sendReport" = false; - "breakpad.reportURL" = ""; - - # Captive Portal detection - # - # https://www.eff.org/deeplinks/2017/08/how-captive-portals-interfere-wireless-security-and-privacy - "captivedetect.canonicalURL" = ""; - "network.captive-portal-service.enabled" = false; - # https://bugzilla.mozilla.org/1460537 - "network.connectivity-service.enabled" = false; - - # Safe browsing - # - # https://feeding.cloud.geek.nz/posts/how-safe-browsing-works-in-firefox/ - # https://wiki.mozilla.org/Security/Safe_Browsing - # https://support.mozilla.org/kb/how-does-phishing-and-malware-protection-work - "browser.safebrowsing.malware.enabled" = false; - "browser.safebrowsing.passwords.enabled" = false; - "browser.safebrowsing.phishing.enabled" = false; - "browser.safebrowsing.downloads.enabled" = false; - "browser.safebrowsing.downloads.remote.enabled" = false; - "browser.safebrowsing.downloads.remote.url" = ""; - "browser.safebrowsing.downloads.remote.block_potentially_unwanted" = false; - "browser.safebrowsing.downloads.remote.block_uncommon" = false; - - # Implicit outbound - # - # https://developer.mozilla.org/docs/Web/HTTP/Link_prefetching_FAQ - "network.prefetch-next" = false; - # https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control - "network.dns.disablePrefetch" = true; - "network.dns.disablePrefetchFromHTTPS" = true; - # - "network.predictor.enabled" = false; - "network.predictor.enable-prefetch" = false; - # https://news.slashdot.org/story/15/08/14/2321202/how-to-quash-firefoxs-silent-requests - "network.http.speculative-parallel-limit" = 0; - # https://www.bleepingcomputer.com/news/software/major-browsers-to-prevent-disabling-of-click-tracking-privacy-risk/ - "browser.send_pings" = false; - # https://trac.torproject.org/projects/tor/wiki/doc/TorifyHOWTO/WebBrowsers - "network.proxy.socks_remote_dns" = true; - # https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/26424 - "network.file.disable_unc_paths" = true; - - # Proxy - # - # https://blog.mozilla.org/security/2021/10/25/securing-the-proxy-api-for-firefox-add-ons/ - "network.proxy.failover_direct" = false; - # https://bugzilla.mozilla.org/buglist.cgi?bug_id=1732792,1733994,1733481 - "network.proxy.allow_bypass" = false; - - # DNS-over-HTTPS (DoH) - # - # https://hacks.mozilla.org/2018/05/a-cartoon-intro-to-dns-over-https/ - # https://wiki.mozilla.org/Security/DOH-resolver-policy - # https://blog.mozilla.org/mozilla/news/firefox-by-default-dns-over-https-rollout-in-canada/ - # https://www.eff.org/deeplinks/2020/12/dns-doh-and-odoh-oh-my-year-review-2020 ***/ - "network.trr.mode" = 5; - - # Location bar & search - # - "browser.fixup.alternate.enabled" = false; - # - "browser.urlbar.trimURLs" = false; - # - "browser.search.suggest.enabled" = false; - "browser.urlbar.suggest.searches" = false; - # https://bugzilla.mozilla.org/1348275 - "browser.urlbar.speculativeConnect.enabled" = false; - # https://bugzilla.mozilla.org/1642623 - "browser.urlbar.dnsResolveSingleWordsAfterSearch" = 0; - # https://blog.mozilla.org/data/2021/09/15/data-and-firefox-suggest/ - "browser.urlbar.suggest.quicksuggest.nonsponsored" = false; - "browser.urlbar.suggest.quicksuggest.sponsored" = false; - - # Search & form history - # https://blog.mindedsecurity.com/2011/10/autocompleteagain.html - # https://bugzilla.mozilla.org/381681 - "browser.formfill.enable" = false; - # https://wiki.mozilla.org/Firefox/Features/Form_Autofill - "extensions.formautofill.available" = "off"; - "extensions.formautofill.addresses.enabled" = false; - "extensions.formautofill.creditCards.available" = false; - "extensions.formautofill.creditCards.enabled" = false; - "extensions.formautofill.heuristics.enabled" = false; - - # Passwords - # - "signon.rememberSignons" = false; - - # Disk avoidance - # - # Disable caching to disk. - # This is a possible performance hit. Could be removed in favor of PSD? - "browser.cache.disk.enable" = false; - # - "browser.privatebrowsing.forceMediaMemoryCache" = true; - "media.memory_cache_max_size" = 65536; - # Extra session data - "browser.sessionstore.privacy_level" = 2; - # Reduce writes - "browser.sessionstore.interval" = 30000; - - # SSL/TLS - # - # Block connections (SSL_ERROR_UNSAFE_NEGOTIATION) to servers that don't support RFC 5746 - # https://wiki.mozilla.org/Security:Renegotiation - # https://datatracker.ietf.org/doc/html/rfc5746 - # https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3555 - # https://www.ssllabs.com/ssl-pulse - "security.ssl.require_safe_negotiation" = true; - # Disable TLS1.3 0-RTT - # https://github.com/tlswg/tls13-spec/issues/1001 - # https://www.rfc-editor.org/rfc/rfc9001.html#name-replay-attacks-with-0-rtt - # https://blog.cloudflare.com/tls-1-3-overview-and-q-and-a/ - "security.tls.enable_0rtt_data" = false; - - # OCSP (Online Certificate Status Protocol) - # - # https://en.wikipedia.org/wiki/Ocsp - # https://scotthelme.co.uk/revocation-is-broken/ - # https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ - # https://www.imperialviolet.org/2014/04/19/revchecking.html - # "security.OCSP.require" = true; - - # HPKP (HTTP Public Key Pinning) - # - # https://blog.mozilla.org/security/2016/10/18/phasing-out-sha-1-on-the-public-web/ - "security.pki.sha1_enforcement_level" = 1; - # https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/16206 - "security.cert_pinning.enforcement_level" = 2; - # https://bugzilla.mozilla.org/buglist.cgi?bug_id=1429800,1670985 - # https://blog.mozilla.org/security/tag/crlite/ - "security.remote_settings.crlite_filters.enabled" = true; - "security.pki.crlite_mode" = 2; - - # Mixed content - # - "security.mixed_content.block_display_content" = true; - # Force HTTPS-only mode - # Exceptions are managed on the settings page - "dom.security.https_only_mode" = true; - "dom.security.https_only_mode_pbm" = true; - # https://bugzilla.mozilla.org/buglist.cgi?bug_id=1642387,1660945 - "dom.security.https_only_mode_send_http_background_request" = false; - - # UI - # - # Dispaly warning on the padlock for "broken security" - # https://wiki.mozilla.org/Security:Renegotiation - # https://bugzilla.mozilla.org/1353705 - "security.ssl.treat_unsafe_negotiation_as_broken" = true; - # https://github.com/pyllyukko/user.js/issues/210 - "browser.ssl_override_behavior" = 1; - # Display advanced information on Insecure Connection warning pages - "browser.xul.error_pages.expert_bad_cert" = true; - # Display "Not Secure" text on HTTP sites - "security.insecure_connection_text.enabled" = true; - # - "browser.privatebrowsing.infoEnabled" = false; - "browser.privatebrowsing.infoTitleEnabled" = false; - "browser.privatebrowsing.promoEnabled" = false; - "browser.privatebrowsing.promoTitleEnabled" = false; - "browser.privatebrowsing.vpnpromourl" = ""; - - # UX - # - "browser.urlbar.decodeURLsOnCopy" = true; - # - "browser.tabs.closeWindowWithLastTab" = true; - # - "general.autoScroll" = true; - "general.smoothScroll" = true; - - # Headers & referers - # - # "network.http.referer.XOriginPolicy" = 2; - # "network.http.referer.XOriginTrimmingPolicy" = 2; - - # Containers - # - # https://wiki.mozilla.org/Security/Contextual_Identity_Project/Containers - # https://addons.mozilla.org/firefox/addon/temporary-containers/ - # https://medium.com/@stoically/enhance-your-privacy-in-firefox-with-temporary-containers-33925cd6cd21 - # https://github.com/stoically/temporary-containers/wiki - "privacy.userContext.enabled" = true; - "privacy.userContext.ui.enabled" = true; - - # WebRTC - # - # Disable WebRTC - # https://browserleaks.com/webrtc - # https://groups.google.com/g/discuss-webrtc/c/6stQXi72BEU/m/2FwZd24UAQAJ - # https://datatracker.ietf.org/doc/html/draft-ietf-mmusic-mdns-ice-candidates#section-3.1.1 - # "media.peerconnection.enabled" = false; - - # DRM - # - # https://www.eff.org/deeplinks/2017/10/drms-dead-canary-how-we-just-lost-web-what-we-learned-it-and-what-we-need-do-next - "media.eme.enabled" = false; - # https://bugzilla.mozilla.org/show_bug.cgi?id=1451762#c55 - "browser.eme.ui.enabled" = false; - - # GMP (Gecko Media Plugins) - # - "media.gmp-provider.enabled" = false; - - # Disable autoplay of HTML5 media - "media.autoplay.enabled" = false; - "media.autoplay.default" = 5; - "media.autoplay.blocking_policy" = 2; - - # DOM (Document Object Model) - # - # Disable "Confirm you want to leave" dialog on page close - # https://developer.mozilla.org/docs/Web/Events/beforeunload - "dom.disable_beforeunload" = true; - # Prevent scripts from moving and resizing open windows - "dom.disable_window_move_resize" = true; - # Block popup windows - "dom.disable_open_during_load" = true; - # Limit events that can cause a popup - "dom.popup_allowed_events" = "click dblclick mousedown pointerdown"; - - # PDFjs - # - # "pdfjs.disabled" = true; - "pdfjs.enableScripting" = false; - - # Developer Tools - # - "devtools.accessibility.enabled" = false; - "devtools.application.enabled" = false; - "devtools.chrome.enabled" = true; - "devtools.dom.enabled" = true; - "devtools.enabled" = true; - "devtools.inspector.enabled" = true; - "devtools.jsonview.enabled" = true; - "devtools.memory.enabled" = true; - "devtools.netmonitor.enabled" = true; - "devtools.performance.enabled" = false; - "devtools.storage.enabled" = true; - "devtools.styleeditor.enabled" = true; - # This will prevent working with XUL - # https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/16222 - "devtools.debugger.enabled" = false; - "devtools.debugger.remote-enabled" = false; - - # Downloads - # - "browser.download.useDownloadDir" = false; - "browser.download.alwaysOpenPanel" = false; - "browser.download.manager.addToRecentDocs" = false; - "browser.download.autohideButton" = false; - - # Extensions - # - # https://mike.kaply.com/2012/02/21/understanding-add-on-scopes/ - # https://archive.is/DYjAM - "extensions.enabledScopes" = 5; - "extensions.autoDisableScopes" = 15; - # https://bugzilla.mozilla.org/buglist.cgi?bug_id=1659530,1681331 - "extensions.postDownloadThirdPartyPrompt" = false; - # Disable recommendations in about:addons panes - "extensions.htmlaboutaddons.recommendations.enabled" = false; - # Mozilla's trash - "extensions.pocket.enabled" = false; - "extensions.screenshots.disabled" = true; - "idenitity.fxaccounts.enabled" = false; - "reader.parse-on-load.enabled" = false; - - # ETP (Encahnced Tracking Protection) - # - # https://blog.mozilla.org/security/2021/02/23/total-cookie-protection/ - "browser.contentblocking.category" = "strict"; - "privacy.partition.serviceWorkers" = true; - - # Sanitize - # - "privacy.sanitize.sanitizeOnShutdown" = true; - "privacy.sanitize.timeSpan" = 0; - "privacy.clearOnShutdown.cache" = true; - "privacy.clearOnShutdown.cookies" = false; - "privacy.clearOnShutdown.downloads" = true; - "privacy.clearOnShutdown.formdata" = true; - "privacy.clearOnShutdown.history" = false; - "privacy.clearOnShutdown.offlineApps" = false; - "privacy.clearOnShutdown.sessions" = false; - "privacy.clearOnShutdown.siteSettings" = false; - "privacy.cpd.cache" = true; - "privacy.cpd.cookies" = false; - "privacy.cpd.downloads" = true; - "privacy.cpd.formdata" = true; - "privacy.cpd.history" = false; - "privacy.cpd.offlineApps" = false; - "privacy.cpd.passwords" = false; - "privacy.cpd.sessions" = false; - "privacy.cpd.siteSettings" = false; - - # Fingerprinting - # - # https://bugzilla.mozilla.org/418986 - # "privacy.resistFingerprinting" = true; - # https://bugzilla.mozilla.org/1448423 - # "browser.startup.blankWindow" = false; - - # Rice - # - "toolkit.legacyUserProfileCustomizations.stylesheets" = true; - # - "browser.startup.page" = 1; - "browser.startup.homepage" = "about:blank"; - "browser.startup.homepage_welcome_url" = ""; - "browser.startup.homepage_welcome_url.additional" = ""; - # - "browser.toolbars.bookmarks.visibility" = "never"; - # - "browser.tabs.inTitlebar" = 1; - # - "browser.newtabpage.enabled" = false; - "browser.newtabpage.enhanced" = false; - "browser.newtabpage.activity-stream.default.sites" = ""; - "browser.newtabpage.activity-stream.discoverystream.enabled" = false; - "browser.newtabpage.activity-stream.feeds.discoverystreamfeed" = false; - "browser.newtabpage.activity-stream.feeds.places" = false; - "browser.newtabpage.activity-stream.feeds.sections" = false; - "browser.newtabpage.activity-stream.feeds.snippets" = false; - "browser.newtabpage.activity-stream.feeds.telemetry" = false; - "browser.newtabpage.activity-stream.feeds.topsites" = false; - "browser.newtabpage.activity-stream.showSearch" = false; - "browser.newtabpage.activity-stream.showSponsored" = false; - "browser.newtabpage.activity-stream.showSponsoredTopSites" = false; - "browser.newtabpage.activity-stream.telemetry" = false; - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.addons" = false; - "browser.newtabpage.activity-stream.asrouter.userprefs.cfr.features" = false; - # - "layout.css.color-mix.enabled" = true; - # - "svg.context-properties.content.enabled" = true; - - # Annoyances - # - "browser.aboutConfig.showWarning" = false; - "browser.disableResetPrompt" = true; - "browser.newtabpage.introShown" = true; - "browser.onboarding.enabled" = false; - "browser.shell.checkDefaultBrowser" = false; - "browser.tabs.warnOnClose" = false; - "browser.tabs.warnOnCloseOtherTabs" = false; - "browser.tabs.warnOnOpen" = false; - "browser.tabs.warnOnQuitShortcut" = false; - "full-screen-api.warning.delay" = 0; - "full-screen-api.warning.timeout" = 0; - "permissions.default.shortcuts" = 2; - "security.dialog_enable_delay" = 0; - - # Geo - # - # Disable OS provider - "geo.provider.use_gpsd" = false; - # Use the Mozilla provider. Defaults to Google otherwise - "geo.provider.network.url" = "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%"; - - # Unsorted - # - "accessibility.force_disabled" = 1; - "beacon.enabled" = false; - "browser.helperApps.deleteTempFileOnExit" = true; - "browser.pagethumbnails.capturing_disabled" = true; - "browser.region.network.url" = ""; - "browser.region.update.enabled" = false; - "browser.selfsupport.url" = ""; - "browser.uitour.enabled" = false; - "browser.uitour.url" = ""; - "intl.accept_languages" = "en-US, en"; - "layout.spellcheckDefault" = 2; - "middlemouse.contentLoadURL" = false; - "permissions.delegation.enabled" = false; - "permissions.manager.defaultsUrl" = ""; - "webchannel.allowObject.urlWhitelist" = ""; - "network.manage-offline-status" = false; - "xpinstall.signatures.required" = false; - - # Toolbar - # - "browser.uiCustomization.state" = '' - {"placements":{"widget-overflow-fixed-list":["ublock0_raymondhill_net-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","7esoorv3_alefvanoon_anonaddy_me-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","ipfs-firefox-addon_lidel_org-browser-action","addon_darkreader_org-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action"],"nav-bar":["back-button","forward-button","urlbar-container","save-to-pocket-button"],"toolbar-menubar":["menubar-items"],"TabsToolbar":["tabbrowser-tabs","new-tab-button","alltabs-button"],"PersonalToolbar":["personal-bookmarks"]},"seen":["addon_darkreader_org-browser-action","ipfs-firefox-addon_lidel_org-browser-action","plasma-browser-integration_kde_org-browser-action","ublock0_raymondhill_net-browser-action","_2e5ff8c8-32fe-46d0-9fc8-6b8986621f3c_-browser-action","_446900e4-71c2-419f-a6a7-df9c091e268b_-browser-action","_73a6fe31-595d-460b-a920-fcc0f8843232_-browser-action","_7a7a4a92-a2a0-41d1-9fd7-1e92480d612d_-browser-action","_aecec67f-0d10-4fa7-b7c7-609a2db280cf_-browser-action","_b7f9d2cd-d772-4302-8c3f-eb941af36f76_-browser-action","developer-button","_a4c4eda4-fb84-4a84-b4a1-f7c1cbf2a1ad_-browser-action","7esoorv3_alefvanoon_anonaddy_me-browser-action"],"dirtyAreaCache":["nav-bar","widget-overflow-fixed-list","toolbar-menubar","TabsToolbar","PersonalToolbar"],"currentVersion":17,"newElementCount":8} - ''; - }; -} diff --git a/modules/nixfiles/firefox/userContent.css b/modules/nixfiles/firefox/userContent.css index 1dc3add..ff74e01 100644 --- a/modules/nixfiles/firefox/userContent.css +++ b/modules/nixfiles/firefox/userContent.css @@ -82,8 +82,29 @@ } } +@-moz-document regexp("https?:\/\/kubernetes\.io\/docs\/.*") { + .announcement, + .announcement-main, + .d-none { + display: none !important; + } +} + +@-moz-document regexp("https?:\/\/min\.io\/docs\/.*") { + #cookie { + display: none !important; + } +} + +@-moz-document regexp("https?:\/\/werf\.io\/documentation\/.*") { + .guides-banner { + display: none !important; + } +} + @-moz-document regexp("https:\/\/habr\.com\/(ru|en)\/(article|company\/.*\/blog|post)\/.*") { .Vue-Toastification__container, + .tm-article-presenter__footer, .tm-article-presenter__meta, .tm-article-snippet__labels, .tm-article-sticky-panel, @@ -99,6 +120,8 @@ .tm-notice, .tm-page__header, .tm-page__sidebar, + .tm-placeholder-inset, + .tm-placeholder-promo, .tm-user-info, vue-portal-target { display: none !important; @@ -174,48 +197,6 @@ } } -@-moz-document regexp("https?:\/\/utaten\.com\/lyric/.*") { - :root { - --kana-font-size: 20px; - --furigana-font-size: 14px; - } - - body { - font-family: var(--sans-serif-font-family) !important; - font-size: var(--kana-font-size) !important; - } - - .rb { - font-size: var(--kana-font-size) !important; - } - - .rt { - font-size: var(--furigana-font-size) !important; - } - - #JP_uta_pc_lyric_footeroverlay, - #footer__area, - #reviews, - #sidebar, - .btn_sbs, - .gaugeWrap, - .lyricData, - .movie_contents, - .newLyricWorkFooter, - .path::before, - .recommendAdTag, - .shareArea, - .sideBySideBanner, - .topBanner, - header { - display: none !important; - } - - #contents { - width: 100% !important; - } -} - @-moz-document regexp("https?:\/\/www\.songsterr\.com.*") { #favorite, #fullscreen, @@ -239,7 +220,6 @@ #shots, a[rel*="noreferrer"], a[target="_blank"], - button, div[class*="SiteWideBanner"], footer, iframe { @@ -257,7 +237,7 @@ } } -@-moz-document regexp("https:\/\/\.*\.wikipedia\.org.*") { +@-moz-document regexp("https:\/\/\.*\.wiki(pedia|less)\.org.*") { #footer, #mp-topbanner, #mw-head, diff --git a/modules/nixfiles/fonts.nix b/modules/nixfiles/fonts.nix index 18c6f52..042c0e8 100644 --- a/modules/nixfiles/fonts.nix +++ b/modules/nixfiles/fonts.nix @@ -81,7 +81,6 @@ in { }; config = mkMerge [ - {home-manager.users.root.fonts.fontconfig.enable = false;} (mkIf cfg.enable { hm.fonts.fontconfig.enable = true; diff --git a/modules/nixfiles/games/lutris.nix b/modules/nixfiles/games/lutris.nix index 0c942a8..e7faef3 100644 --- a/modules/nixfiles/games/lutris.nix +++ b/modules/nixfiles/games/lutris.nix @@ -29,9 +29,6 @@ in { }; }; steamSupport = false; - extraPkgs = _: [ - driversi686Linux.mesa # Battle.net - ]; }) ]; }; diff --git a/modules/nixfiles/games/steam-run.nix b/modules/nixfiles/games/steam-run.nix index bab12f3..4731fd6 100644 --- a/modules/nixfiles/games/steam-run.nix +++ b/modules/nixfiles/games/steam-run.nix @@ -63,6 +63,7 @@ in { elem (getName p) [ "steam" "steam-original" + "steam-run" ]; }; } diff --git a/modules/nixfiles/games/steam.nix b/modules/nixfiles/games/steam.nix index 71e5068..bbd01f6 100644 --- a/modules/nixfiles/games/steam.nix +++ b/modules/nixfiles/games/steam.nix @@ -22,6 +22,7 @@ in { elem (getName p) [ "steam" "steam-original" + "steam-run" ]; }; } diff --git a/modules/nixfiles/git.nix b/modules/nixfiles/git.nix index b121f8f..facff2f 100644 --- a/modules/nixfiles/git.nix +++ b/modules/nixfiles/git.nix @@ -130,7 +130,7 @@ in { "[._]ss[a-gi-z]" "[._]sw[a-p]" "\#*\#" - "compile_commands.json" + "compile_commands*.json" "cscope.*" "vgcore.*" ]; @@ -142,8 +142,14 @@ in { }; bash = { - shellAliases.gl = "${pkgs.glab}/bin/glab"; - initExtra = mkAfter "_complete_alias gl __start_glab glab"; + shellAliases = { + gl = "${pkgs.glab}/bin/glab"; + ht = "${pkgs.hut}/bin/hut"; + }; + initExtra = mkAfter '' + _complete_alias gl __start_glab glab + _complete_alias ht __start_hut hut + ''; }; }; }; @@ -202,7 +208,7 @@ in { group = "git"; in { gitolite = { - # TODO Make configuration purely declarative. + # TODO Make the configuration purely declarative. enable = true; inherit user group; adminPubkey = my.ssh.key; diff --git a/modules/nixfiles/gotify.nix b/modules/nixfiles/gotify.nix index 8489e93..f21a98d 100644 --- a/modules/nixfiles/gotify.nix +++ b/modules/nixfiles/gotify.nix @@ -30,7 +30,14 @@ in { extraConfig = nginxInternalOnly; }; }; - postgresql.enable = true; + postgresql = { + enable = true; + extraPostStart = [ + '' + $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' + '' + ]; + }; }; services = { @@ -44,7 +51,7 @@ in { ensureUsers = [ { name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; diff --git a/modules/nixfiles/grafana.nix b/modules/nixfiles/grafana.nix index c29bf75..807f8fe 100644 --- a/modules/nixfiles/grafana.nix +++ b/modules/nixfiles/grafana.nix @@ -23,69 +23,77 @@ in { }; }; - config = mkIf cfg.enable { - secrets = { - grafana-admin-password = { - file = "${inputs.self}/secrets/grafana-admin-password"; - owner = "grafana"; - group = "grafana"; - }; - grafana-key = { - file = "${inputs.self}/secrets/grafana-key"; - owner = "grafana"; - group = "grafana"; + config = let + db = "grafana"; + in + mkIf cfg.enable { + secrets = { + grafana-admin-password = { + file = "${inputs.self}/secrets/grafana-admin-password"; + owner = "grafana"; + group = "grafana"; + }; + grafana-key = { + file = "${inputs.self}/secrets/grafana-key"; + owner = "grafana"; + group = "grafana"; + }; }; - }; - nixfiles.modules = { - nginx = { - enable = true; - upstreams.grafana.servers."127.0.0.1:${toString cfg.port}" = {}; - virtualHosts.${cfg.domain}.locations."/" = { - proxyPass = "http://grafana"; - proxyWebsockets = true; - extraConfig = nginxInternalOnly; + nixfiles.modules = { + nginx = { + enable = true; + upstreams.grafana.servers."127.0.0.1:${toString cfg.port}" = {}; + virtualHosts.${cfg.domain}.locations."/" = { + proxyPass = "http://grafana"; + proxyWebsockets = true; + extraConfig = nginxInternalOnly; + }; + }; + postgresql = { + enable = true; + extraPostStart = [ + '' + $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' + '' + ]; }; }; - postgresql.enable = true; - }; - services = let - db = "grafana"; - in { - grafana = { - enable = true; + services = { + grafana = { + enable = true; - inherit (cfg) domain port; - protocol = "http"; - addr = "127.0.0.1"; + inherit (cfg) domain port; + protocol = "http"; + addr = "127.0.0.1"; - analytics.reporting.enable = false; + analytics.reporting.enable = false; - database = { - type = "postgres"; - host = "/run/postgresql"; - name = db; - user = db; - }; + database = { + type = "postgres"; + host = "/run/postgresql"; + name = db; + user = db; + }; - security = with config.secrets; { - secretKeyFile = grafana-key.path; - adminPasswordFile = grafana-admin-password.path; - }; + security = with config.secrets; { + secretKeyFile = grafana-key.path; + adminPasswordFile = grafana-admin-password.path; + }; - extraOptions.LOG_LEVEL = "warn"; - }; + extraOptions.LOG_LEVEL = "warn"; + }; - postgresql = { - ensureDatabases = [db]; - ensureUsers = [ - { - name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; - } - ]; + postgresql = { + ensureDatabases = [db]; + ensureUsers = [ + { + name = db; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; + } + ]; + }; }; }; - }; } diff --git a/modules/nixfiles/hydra.nix b/modules/nixfiles/hydra.nix index 2168ed5..590fecb 100644 --- a/modules/nixfiles/hydra.nix +++ b/modules/nixfiles/hydra.nix @@ -48,7 +48,7 @@ in { ensureUsers = [ { name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; diff --git a/modules/nixfiles/matrix/dendrite.nix b/modules/nixfiles/matrix/dendrite.nix index 8dbc318..0fad5f2 100644 --- a/modules/nixfiles/matrix/dendrite.nix +++ b/modules/nixfiles/matrix/dendrite.nix @@ -12,138 +12,146 @@ in { enable = mkEnableOption "Dendrite Matrix server"; domain = mkOption { - description = "Domain name sans protocol scheme."; - type = with types; str; + type = types.str; default = config.networking.domain; + description = "Domain name sans protocol scheme."; }; }; - config = mkIf cfg.enable { - secrets.dendrite-private-key = { - file = "${inputs.self}/secrets/dendrite-private-key"; - mode = "0444"; # FIXME User is dynamic so the file must be world-readable. - }; + config = let + db = "dendrite"; + in + mkIf cfg.enable { + secrets.dendrite-private-key = { + file = "${inputs.self}/secrets/dendrite-private-key"; + mode = "0444"; # The user is dynamic so the file must be world-readable. + }; + secrets.dendrite-environment-file = { + file = "${inputs.self}/secrets/dendrite-environment-file"; + mode = "0444"; # The user is dynamic so the file must be world-readable. + }; - nixfiles.modules = { - nginx = { - enable = true; - upstreams.dendrite.servers."127.0.0.1:${toString config.services.dendrite.httpPort}" = {}; - virtualHosts.${cfg.domain}.locations = { - "/_matrix".proxyPass = "http://dendrite"; - "= /.well-known/matrix/server" = { - extraConfig = '' - add_header Content-Type application/json; - ''; - return = "200 '${ - generators.toJSON {} {"m.server" = "${cfg.domain}:443";} - }'"; - }; - "= /.well-known/matrix/client" = { - extraConfig = '' - add_header Content-Type application/json; - add_header Access-Control-Allow-Origin *; - ''; - return = "200 '${ - generators.toJSON {} { - "m.homeserver".base_url = "https://${cfg.domain}"; - } - }'"; + nixfiles.modules = { + nginx = { + enable = true; + upstreams.dendrite.servers."127.0.0.1:${toString config.services.dendrite.httpPort}" = {}; + virtualHosts.${cfg.domain}.locations = { + "/_matrix".proxyPass = "http://dendrite"; + "= /.well-known/matrix/server" = { + extraConfig = '' + add_header Content-Type application/json; + ''; + return = "200 '${ + generators.toJSON {} {"m.server" = "${cfg.domain}:443";} + }'"; + }; + "= /.well-known/matrix/client" = { + extraConfig = '' + add_header Content-Type application/json; + add_header Access-Control-Allow-Origin *; + ''; + return = "200 '${ + generators.toJSON {} { + "m.homeserver".base_url = "https://${cfg.domain}"; + } + }'"; + }; }; }; + postgresql = { + enable = true; + extraPostStart = [ + '' + $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' + '' + ]; + }; }; - postgresql.enable = true; - }; - - services = let - name = "dendrite"; - prefix = "${name}-"; - databaseNames = [ - "account" - "appservice" - "device" - "federation" - "key" - "media" - "mscs" - "room" - "sync" - ]; - databaseList = forEach databaseNames (x: concatStrings [prefix x]); - databaseAttr = genAttrs databaseNames (x: concatStrings [prefix x]); - - mkDatabaseConnection = database: "postgres://${name}@/${database}?sslmode=disable"; - in { - dendrite = { - enable = true; - httpPort = 8008; - settings = { - global = { - server_name = cfg.domain; - - private_key = config.secrets.dendrite-private-key.path; - - disable_federation = false; - }; - - app_service_api.database.connection_string = - mkDatabaseConnection databaseAttr.appservice; - client_api = { - registration_disabled = true; - turn = {}; # TODO - }; - - federation_api.database.connection_string = - mkDatabaseConnection databaseAttr.federation; - - key_server.database.connection_string = - mkDatabaseConnection databaseAttr.key; - - media_api = { - database.connection_string = - mkDatabaseConnection databaseAttr.media; - base_path = "./media"; - }; - - mscs.database.connection_string = - mkDatabaseConnection databaseAttr.mscs; - - room_server.database.connection_string = - mkDatabaseConnection databaseAttr.room; - - sync_api.database.connection_string = - mkDatabaseConnection databaseAttr.sync; - - user_api = { - account_database.connection_string = - mkDatabaseConnection databaseAttr.account; - device_database.connection_string = - mkDatabaseConnection databaseAttr.device; + services = { + dendrite = { + enable = true; + httpPort = 8008; + environmentFile = config.secrets.dendrite-environment-file.path; + settings = { + version = 2; + global = { + server_name = cfg.domain; + private_key = config.secrets.dendrite-private-key.path; + database = { + connection_string = "postgresql://${db}@/${db}?host=/run/postgresql"; + max_open_conns = 64; + max_idle_connections = 8; + }; + cache = { + max_size_estimated = "1gb"; + max_age = "1h"; + }; + trusted_third_party_id_servers = [ + "matrix.org" + "nixos.org" + "vector.im" + ]; + presence = { + enable_inbound = false; + enable_outbound = false; + }; + }; + client_api = { + registration_disabled = true; + guests_disabled = true; + registration_shared_secret = "$REGISTRATION_SHARED_SECRET"; + }; + media_api = { + max_file_size_bytes = 0; + dynamic_thumbnails = true; + max_thumbnail_generators = 8; + thumbnail_sizes = [ + { + width = 32; + height = 32; + method = "crop"; + } + { + width = 96; + height = 96; + method = "crop"; + } + { + width = 640; + height = 480; + method = "scale"; + } + ]; + }; + logging = [ + { + type = "std"; + level = "warn"; + } + ]; }; + }; - metrics.enabled = false; # TODO + postgresql = { + ensureDatabases = [db]; + ensureUsers = [ + { + name = db; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; + } + ]; }; }; - postgresql = { - ensureDatabases = databaseList; - ensureUsers = - map (x: { - inherit name; - ensurePermissions."DATABASE \"${x}\"" = "ALL PRIVILEGES"; - }) - databaseList; - }; + systemd.services.dendrite.serviceConfig.ExecStart = + mkForce + (concatStringsSep " " [ + "${pkgs.dendrite}/bin/dendrite-monolith-server" + "--config /run/dendrite/dendrite.yaml" + "--http-bind-address 127.0.0.1:${ + toString config.services.dendrite.httpPort + }" + ]); }; - - systemd.services.dendrite.serviceConfig.ExecStart = - mkForce - (concatStringsSep " " [ - "${pkgs.dendrite}/bin/dendrite-monolith-server" - "--config /run/dendrite/dendrite.yaml" - "--http-bind-address 127.0.0.1:${ - toString config.services.dendrite.httpPort - }" - ]); - }; } diff --git a/modules/nixfiles/matrix/synapse.nix b/modules/nixfiles/matrix/synapse.nix index 5f16b7d..6ff5e0d 100644 --- a/modules/nixfiles/matrix/synapse.nix +++ b/modules/nixfiles/matrix/synapse.nix @@ -79,13 +79,15 @@ in { ]; }; - postgresql.initialScript = pkgs.writeText "init-matrix-synapse.sql" '' - CREATE USER "${db}"; - CREATE DATABASE "${db}" WITH OWNER "${db}" - TEMPLATE template0 - LC_COLLATE = "C" - LC_CTYPE = "C"; - ''; + postgresql = { + ensureDatabases = [db]; + ensureUsers = [ + { + name = db; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; + } + ]; + }; }; }; } diff --git a/modules/nixfiles/monitoring/default.nix b/modules/nixfiles/monitoring/default.nix index 35261e2..d5ed1b5 100644 --- a/modules/nixfiles/monitoring/default.nix +++ b/modules/nixfiles/monitoring/default.nix @@ -7,7 +7,9 @@ with lib; let cfg = config.nixfiles.modules.monitoring; in { - options.nixfiles.modules.monitoring.enable = mkEnableOption "a custom monitoring stack"; + options.nixfiles.modules.monitoring.enable = mkEnableOption '' + a custom monitoring stack bas on the Grafana Labs toolkit + ''; config = mkIf cfg.enable { nixfiles.modules = { @@ -60,6 +62,8 @@ in { options.path = ./dashboards/postgresql.json; } ]; + + notifiers = []; # TODO Add. }; loki.configuration.ruler.alertmanager_url = "https://${config.nixfiles.modules.alertmanager.domain}"; @@ -67,69 +71,96 @@ in { prometheus = { # It would be nice if these could be generated dynamically. That would # require a complete rework of how configurations are defined, though. - scrapeConfigs = with my.configurations; - with config.services.prometheus.exporters; [ - { - job_name = "endlessh-go"; - static_configs = [ - { - targets = with config.services.endlessh-go.prometheus; [ - "${manwe.hostname}:${toString port}" - "${varda.hostname}:${toString port}" - "${yavanna.hostname}:${toString port}" - ]; - } - ]; - } - { - job_name = "nginx"; - static_configs = [ - { - targets = with nginx; [ - "${manwe.hostname}:${toString port}" - "${varda.hostname}:${toString port}" - "${yavanna.hostname}:${toString port}" - ]; - } - ]; - } - { - job_name = "node"; - static_configs = [ - { - targets = with node; [ - "${manwe.hostname}:${toString port}" - "${varda.hostname}:${toString port}" - "${yavanna.hostname}:${toString port}" - ]; - } - ]; - } - { - job_name = "postgres"; - static_configs = [ - { - targets = with postgres; ["${manwe.hostname}:${toString port}"]; - } - ]; - } - { - job_name = "unbound"; - static_configs = [ - { - targets = with unbound; ["${manwe.hostname}:${toString port}"]; - } - ]; - } - { - job_name = "wireguard"; - static_configs = [ - { - targets = with wireguard; ["${manwe.hostname}:${toString port}"]; - } - ]; - } - ]; + scrapeConfigs = let + mkTargets = hosts: port: map (host: "${host.hostname}:${toString port}") hosts; + in + with my.configurations; + with config.services.prometheus.exporters; [ + { + job_name = "endlessh-go"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + varda + yavanna + ] + config.services.endlessh-go.prometheus.port; + } + ]; + } + { + job_name = "nginx"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + varda + yavanna + ] + nginx.port; + } + ]; + } + { + job_name = "node"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + varda + yavanna + ] + node.port; + } + ]; + } + { + job_name = "postgres"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + ] + postgres.port; + } + ]; + } + { + job_name = "unbound"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + ] + unbound.port; + } + ]; + } + { + job_name = "wireguard"; + static_configs = [ + { + targets = + mkTargets + [ + manwe + ] + wireguard.port; + } + ]; + } + ]; alertmanagers = [ { diff --git a/modules/nixfiles/nextcloud.nix b/modules/nixfiles/nextcloud.nix index 11eb8d3..69bea8a 100644 --- a/modules/nixfiles/nextcloud.nix +++ b/modules/nixfiles/nextcloud.nix @@ -103,7 +103,7 @@ in { ensureUsers = [ { name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; diff --git a/modules/nixfiles/nsd.nix b/modules/nixfiles/nsd.nix index 57973ee..0dade8f 100644 --- a/modules/nixfiles/nsd.nix +++ b/modules/nixfiles/nsd.nix @@ -107,6 +107,7 @@ in { # ns2 = varda; alertmanager = manwe; + bitwarden = manwe; git = manwe; gotify = manwe; grafana = manwe; diff --git a/modules/nixfiles/postgresql.nix b/modules/nixfiles/postgresql.nix index 14bfc68..df05e7e 100644 --- a/modules/nixfiles/postgresql.nix +++ b/modules/nixfiles/postgresql.nix @@ -8,17 +8,52 @@ with lib; let cfg = config.nixfiles.modules.postgresql; in { - options.nixfiles.modules.postgresql.enable = mkEnableOption "PostgeSQL"; + options.nixfiles.modules.postgresql = { + enable = mkEnableOption "PostgreSQL"; + + package = mkOption { + type = types.package; + default = pkgs.postgresql_15; + description = "PostgreSQL package to use."; + }; + + extraPostStart = mkOption { + type = with types; listOf str; + default = []; + description = '' + Additional post-startup commands. + + This could be used to provide a crude interface to grant permissions and + such. + ''; + }; + }; config = mkIf cfg.enable { + assertions = [ + { + assertion = any (x: x == "en_GB.UTF-8/UTF-8") config.i18n.supportedLocales; + message = "The locale must be available"; + } + ]; + services = { postgresql = { enable = true; - package = pkgs.postgresql_14; # Pin version to prevent any surprises. + + inherit (cfg) package; + + initdbArgs = [ + "--encoding=UTF8" + "--locale-provider=icu" + "--icu-locale=en_GB@collation=posix" + "--locale=en_GB.UTF-8" + "--lc-collate=C" + "--lc-ctype=C" + ]; + authentication = '' local all all trust - host all all 127.0.0.1/32 trust - host all all ::1/128 trust ''; }; @@ -29,6 +64,11 @@ in { }; }; + systemd.services.postgresql.postStart = + optionalString (cfg.extraPostStart != []) + concatStringsSep "\n" + cfg.extraPostStart; + environment.sessionVariables.PSQLRC = toString (pkgs.writeText "psqlrc" '' \set QUIET 1 diff --git a/modules/nixfiles/profiles/default.nix b/modules/nixfiles/profiles/default.nix index c236722..356413a 100644 --- a/modules/nixfiles/profiles/default.nix +++ b/modules/nixfiles/profiles/default.nix @@ -77,8 +77,8 @@ in { vim.enable = true; }; - home-manager.users.root.home.file.".bash_history".source = - config.hm.lib.file.mkOutOfStoreSymlink "/dev/null"; + # home-manager.users.root.home.file.".bash_history".source = + # config.hm.lib.file.mkOutOfStoreSymlink "/dev/null"; hm.home.language = { collate = "C"; diff --git a/modules/nixfiles/profiles/dev/default.nix b/modules/nixfiles/profiles/dev/default.nix index 1a0ad07..4656ade 100644 --- a/modules/nixfiles/profiles/dev/default.nix +++ b/modules/nixfiles/profiles/dev/default.nix @@ -28,91 +28,9 @@ in { hm.home = { file = { - ".editorconfig".text = '' - root = true + ".editorconfig".source = ./editorconfig.ini; - [*] - charset = utf-8 - end_of_line = lf - indent_size = 4 - indent_style = space - insert_final_newline = true - max_line_length = 80 - trim_trailing_whitespace = true - - [*.nix] - indent_size = 2 - indent_style = space - - [*.{S,s,asm}] - indent_size = 4 - indent_style = tab - - [*.{C,H,c,c++,cc,cpp,cxx,h,h++,hh,hpp,hxx}] - indent_size = 4 - indent_style = tab - - [*.{cl,clj,el,l,lisp,lsp,rkt,scm,ss}] - indent_size = 2 - indent_style = space - - [*.go] - indent_size = 4 - indent_style = tab - - [*.{py,pyx}] - indent_size = 4 - indent_style = space - - [*.{hs,lhs}] - indent_size = 2 - indent_style = space - - [*.{html,xhtml,xml}] - indent_size = 4 - indent_style = tab - - [*.json] - indent_size = 2 - indent_style = space - - [*.{yaml,yml}] - indent_size = 2 - indent_style = space - - [*.{toml,tml}] - indent_size = 4 - indent_style = space - - [*.{py,pyx}] - indent_size = 4 - indent_style = space - max_line_length = 72 - - [*.zig] - indent_size = 4 - indent_style = tab - - [configure.ac] - indent_size = 4 - indent_style = tab - - [{Makefile*,*.mk}] - indent_size = 4 - indent_style = tab - - [{CMakeLists.txt,*.cmake}] - indent_size = 8 - indent_style = tab - - [*.tex] - indent_size = 4 - indent_style = tab - - [*.{md,adoc,rtf,txt}] - indent_size = 4 - indent_style = tab - ''; + ".gdbinit".source = ./gdbinit; ".ghc/ghci.conf".source = ./ghci.conf; @@ -125,140 +43,41 @@ in { }; }; - ".clang-format".text = generators.toYAML {} { - AccessModifierOffset = -4; - AlignAfterOpenBracket = "Align"; - AlignConsecutiveAssignments = "Consecutive"; - AlignConsecutiveBitFields = "Consecutive"; - AlignConsecutiveDeclarations = "Consecutive"; - AlignConsecutiveMacros = "Consecutive"; - AlignEscapedNewlines = "Right"; - AlignOperands = "Align"; - AlignTrailingComments = false; - AllowAllArgumentsOnNextLine = false; - AllowAllConstructorInitializersOnNextLine = true; - AllowAllParametersOfDeclarationOnNextLine = true; - AllowShortBlocksOnASingleLine = "Never"; - AllowShortCaseLabelsOnASingleLine = false; - AllowShortEnumsOnASingleLine = false; - AllowShortFunctionsOnASingleLine = "None"; - AllowShortIfStatementsOnASingleLine = "Never"; - AllowShortLambdasOnASingleLine = "Inline"; - AllowShortLoopsOnASingleLine = false; - AlwaysBreakAfterDefinitionReturnType = "All"; - AlwaysBreakAfterReturnType = "AllDefinitions"; - AlwaysBreakBeforeMultilineStrings = false; - AlwaysBreakTemplateDeclarations = "Yes"; - BinPackArguments = false; - BinPackParameters = false; - BreakBeforeBinaryOperators = "None"; - BreakBeforeBraces = "Allman"; - BreakBeforeTernaryOperators = true; - BreakConstructorInitializers = "BeforeComma"; - BreakInheritanceList = "BeforeComma"; - BreakStringLiterals = true; - ColumnLimit = 80; - CommentPragmas = "^ IWYU pragma:"; - CompactNamespaces = false; - ConstructorInitializerAllOnOneLineOrOnePerLine = false; - ConstructorInitializerIndentWidth = 4; - ContinuationIndentWidth = 4; - Cpp11BracedListStyle = true; - DeriveLineEnding = false; - DerivePointerAlignment = false; - DisableFormat = false; - ExperimentalAutoDetectBinPacking = false; - FixNamespaceComments = true; - IncludeBlocks = "Regroup"; - IndentCaseBlocks = false; - IndentCaseLabels = false; - IndentExternBlock = "NoIndent"; - IndentGotoLabels = false; - IndentPPDirectives = "None"; - IndentWidth = 4; - IndentWrappedFunctionNames = false; - KeepEmptyLinesAtTheStartOfBlocks = false; - Language = "Cpp"; - MaxEmptyLinesToKeep = 1; - NamespaceIndentation = "None"; - PointerAlignment = "Left"; - ReflowComments = false; - SortIncludes = "CaseSensitive"; - SortUsingDeclarations = true; - SpaceAfterCStyleCast = false; - SpaceAfterLogicalNot = false; - SpaceAfterTemplateKeyword = true; - SpaceBeforeAssignmentOperators = true; - SpaceBeforeCpp11BracedList = false; - SpaceBeforeCtorInitializerColon = true; - SpaceBeforeInheritanceColon = true; - SpaceBeforeParens = "ControlStatements"; - SpaceBeforeRangeBasedForLoopColon = true; - SpaceInEmptyParentheses = false; - SpacesBeforeTrailingComments = 1; - SpacesInAngles = false; - SpacesInCStyleCastParentheses = false; - SpacesInContainerLiterals = false; - SpacesInParentheses = false; - SpacesInSquareBrackets = false; - Standard = "Latest"; - TabWidth = 4; - UseTab = "Always"; + "${config.dirs.data}/stack/global-project/stack.yaml".text = generators.toYAML {} { + packages = []; + resolver = "lts-19.28"; }; + }; - ".gdbinit".text = '' - set confirm off - set verbose off - set editing off - - set history expansion on - - set height 0 - set width 0 - - handle SIGALRM nostop print nopass - handle SIGBUS stop print nopass - handle SIGPIPE nostop print nopass - handle SIGSEGV stop print nopass - - set print address on - set print elements 0 - set print object on - set print pretty on - set print repeats 0 - set print static-members on - set print vtbl on - - set output-radix 10 + sessionVariables = with config.dirs; rec { + ANDROID_HOME = "${data}/android"; - set demangle-style gnu-v3 + CABAL_DIR = "${data}/cabal"; + CABAL_CONFIG = pkgs.writeText "cabal-config" '' + repository hackage.haskell.org + url: https://hackage.haskell.org/ + secure: True - set disassembly-flavor intel + jobs: $ncpus - alias iv=info variables + remote-repo-cache: ${CABAL_DIR}/packages - alias da=disassemble + world-file: ${CABAL_DIR}/world - define fs - finish - step - end + logs-dir: ${CABAL_DIR}/logs + build-summary: ${CABAL_DIR}/logs/build.log - define btc - backtrace - continue - end + installdir: ${CABAL_DIR}/bin + extra-prog-path: ${CABAL_DIR}/bin ''; - }; - sessionVariables = with config.dirs; { - ANDROID_HOME = "${data}/android"; - CABAL_CONFIG = "${data}/cabal/config"; - CABAL_DIR = "${data}/cabal"; + STACK_ROOT = "${data}/stack"; + CARGO_HOME = "${data}/cargo"; + GOPATH = "${data}/go"; + PYTHONSTARTUP = ./pystartup.py; - STACK_ROOT = "${data}/stack"; }; packages = with pkgs; [ diff --git a/modules/nixfiles/profiles/dev/editorconfig.ini b/modules/nixfiles/profiles/dev/editorconfig.ini new file mode 100644 index 0000000..17b0317 --- /dev/null +++ b/modules/nixfiles/profiles/dev/editorconfig.ini @@ -0,0 +1,83 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 80 +trim_trailing_whitespace = true + +[*.nix] +indent_size = 2 +indent_style = space + +[*.{S,s,asm}] +indent_size = 4 +indent_style = tab + +[*.{C,H,c,c++,cc,cpp,cxx,h,h++,hh,hpp,hxx}] +indent_size = 4 +indent_style = tab + +[*.{cl,clj,el,l,lisp,lsp,rkt,scm,ss}] +indent_size = 2 +indent_style = space + +[*.go] +indent_size = 4 +indent_style = tab + +[*.{py,pyx}] +indent_size = 4 +indent_style = space + +[*.{hs,lhs}] +indent_size = 2 +indent_style = space + +[*.{html,xhtml,xml}] +indent_size = 4 +indent_style = tab + +[*.json] +indent_size = 2 +indent_style = space + +[*.{yaml,yml}] +indent_size = 2 +indent_style = space + +[*.{toml,tml}] +indent_size = 4 +indent_style = space + +[*.{py,pyx}] +indent_size = 4 +indent_style = space +max_line_length = 72 + +[*.zig] +indent_size = 4 +indent_style = tab + +[configure.ac] +indent_size = 4 +indent_style = tab + +[{Makefile*,*.mk}] +indent_size = 4 +indent_style = tab + +[{CMakeLists.txt,*.cmake}] +indent_size = 8 +indent_style = tab + +[*.tex] +indent_size = 4 +indent_style = tab + +[*.{md,adoc,rtf,txt}] +indent_size = 4 +indent_style = tab diff --git a/modules/nixfiles/profiles/dev/gdbinit b/modules/nixfiles/profiles/dev/gdbinit new file mode 100644 index 0000000..e266236 --- /dev/null +++ b/modules/nixfiles/profiles/dev/gdbinit @@ -0,0 +1,41 @@ +set confirm off +set verbose off +set editing off + +set history expansion on + +set height 0 +set width 0 + +handle SIGALRM nostop print nopass +handle SIGBUS stop print nopass +handle SIGPIPE nostop print nopass +handle SIGSEGV stop print nopass + +set print address on +set print elements 0 +set print object on +set print pretty on +set print repeats 0 +set print static-members on +set print vtbl on + +set output-radix 10 + +set demangle-style gnu-v3 + +set disassembly-flavor intel + +alias iv=info variables + +alias da=disassemble + +define fs + finish + step +end + +define btc + backtrace + continue +end diff --git a/modules/nixfiles/profiles/headless.nix b/modules/nixfiles/profiles/headless.nix index 6ac91c1..369f457 100644 --- a/modules/nixfiles/profiles/headless.nix +++ b/modules/nixfiles/profiles/headless.nix @@ -44,13 +44,6 @@ in { }; }; - i18n = { - # TODO Convert everything including PostgreSQL databases to the "en_US" - # locale or probably even the "C" one. - defaultLocale = mkForce "C"; - supportedLocales = mkForce ["en_US.UTF-8/UTF-8" "en_GB.UTF-8/UTF-8"]; - }; - services.udisks2.enable = false; xdg.sounds.enable = false; diff --git a/modules/nixfiles/qutebrowser.nix b/modules/nixfiles/qutebrowser.nix index 186623a..76f9f98 100644 --- a/modules/nixfiles/qutebrowser.nix +++ b/modules/nixfiles/qutebrowser.nix @@ -10,534 +10,527 @@ in { options.nixfiles.modules.qutebrowser.enable = mkEnableOption "Qutebrowser"; config = mkIf cfg.enable { - hm = { - # home.sessionVariables.BROWSER = mkOverride 400 "qutebrowser"; + hm.programs.qutebrowser = with config.nixfiles.modules; { + enable = true; - programs.qutebrowser = with config.nixfiles.modules; { - enable = true; - - package = pkgs.qutebrowser.override { - withMediaPlayback = false; - withPdfReader = false; - }; + package = pkgs.qutebrowser.override { + withMediaPlayback = false; + withPdfReader = false; + }; - keyBindings.normal = mkIf mpv.enable { - "z" = let - mpv = "${config.hm.programs.mpv.package}/bin/mpv"; - in "hint links spawn --detach ${mpv} {hint-url}"; - }; + keyBindings.normal = mkIf mpv.enable { + "z" = let + mpv = "${config.hm.programs.mpv.package}/bin/mpv"; + in "hint links spawn --detach ${mpv} {hint-url}"; + }; - searchEngines = rec { - aliexpress = "https://www.aliexpress.com/wholesale?SearchText={}"; - ansible = "https://galaxy.ansible.com/search?keywords={}"; - arch = "https://wiki.archlinux.org/?search={}"; - crates = "https://crates.io/search?q={}"; - crawl = "http://crawl.chaosforge.org/index.php?search={}"; - discogs = "https://www.discogs.com/search/?q={}"; - dockerdocs = "https://docs.docker.com/search/?q={}"; - dockerhub = "https://hub.docker.com/search?q={}"; - doublegis = "https://2gis.ru/search/{}"; - duckduckgo = "https://duckduckgo.com/?q={}'"; - dwarffortress = "https://dwarffortresswiki.org/index.php?search={}"; - ebay = "https://www.ebay.com/sch/i.html?_nkw={}"; - ecosia = "https://www.ecosia.org/search?q={}"; - factorio = "https://wiki.factorio.com/index.php?search={}"; - genius = "https://genius.com/search?q={}"; - github = "https://github.com/search?q={}"; - godocs = "https://godocs.io/?q={}"; - gogdb = "https://www.gogdb.org/products?search={}"; - google = "https://www.google.com/search?q={}"; - google-images = "https://www.google.com/search?q={}&tbm=isch"; - gopkgs = "https://pkg.go.dev/search?q={}"; - habr = "https://habr.com/ru/search/?q={}"; - hackage = "https://hackage.haskell.org/packages/search?terms={}"; - hackernews = "https://hn.algolia.com/?q={}"; - headhunter = "https://hh.ru/search/vacancy?st=searchVacancy&text={}"; - hoogle = "https://hoogle.haskell.org/?hoogle={}"; - jisho = "https://jisho.org/search/{}"; - kotobank = "https://kotobank.jp/gs/?q={}"; - kubernetes = "https://kubernetes.io/search/?q={}"; - lastfm = "https://www.last.fm/search?q={}"; - lobsters = "https://lobste.rs/search?q=test{}"; - mdn = "https://developer.mozilla.org/en-US/search?q={}"; - melpa = "https://melpa.org/#/?q={}"; - moddb = "https://www.moddb.com/search?q={}"; - musicbrainz = "https://musicbrainz.org/search?query={}"; - nix-issues = "https://github.com/NixOS/nix/issues?q={}"; - nix-prs = "https://github.com/NixOS/nix/pulls?q={}"; - nixos-flakes = "https://search.nixos.org/flakes?query={}"; - nixos-options = "https://search.nixos.org/options?query={}"; - nixos-packages = "https://search.nixos.org/packages?query={}"; - nixos-wiki = "https://nixos.wiki/index.php?search={}"; - nixpkgs-issues = "https://github.com/NixOS/nixpkgs/issues?q={}"; - nixpkgs-prs = "https://github.com/NixOS/nixpkgs/pulls?q={}"; - openstreetmap = "https://www.openstreetmap.org/search?query={}"; - ozon = "https://www.ozon.ru/search/?text={}"; - protondb = "https://www.protondb.com/search?q={}"; - pypi = "https://pypi.org/search/?q={}"; - pythondocs = "https://docs.python.org/3/search.html?q={}"; - rateyourmusic = "https://rateyourmusic.com/search?searchterm={}"; - riichi = "https://riichi.wiki/index.php?search={}"; - rustdoc = "https://doc.rust-lang.org/std/?search={}"; - searx = "https://searx.tiekoetter.com/search?q={}"; - slashdot = "https://slashdot.org/index2.pl?fhfilter={}"; - sourcehut = "https://sr.ht/projects?search={}"; - steam = "https://store.steampowered.com/search/?term={}"; - steamdb = "https://steamdb.info/search/?a=app&q={}"; - ubuntu = "https://wiki.ubuntu.com/Home?action=fullsearch&value={}"; - wikipedia-en = "https://en.wikipedia.org/w/index.php?search={}"; - wikipedia-ru = "https://ru.wikipedia.org/w/index.php?search={}"; - wikipedia-ja = "https://ja.wikipedia.org/w/index.php?search={}"; - wolphramalpha = "https://www.wolframalpha.com/input/?i={}"; - yahoo = "https://yahoo.com/search/?text={}"; - yahoo-images = "https://yahoo.com/images/search?text={}"; - yahoo-market = "https://market.yahoo.com/search?text={}"; - youtube = "https://yewtu.be/search?q={}"; - - aw = arch; - d = duckduckgo; - do = dockerhub; - docker = dockerhub; - dod = dockerdocs; - g = google; - gh = github; - h = hoogle; - k = kubernetes; - mb = musicbrainz; - n = nixos-options; - nw = nixos-wiki; - py = pypi; - pyd = pythondocs; - rym = rateyourmusic; - s = searx; - sh = sourcehut; - sr = sourcehut; - w = wikipedia-en; - wen = wikipedia-en; - wja = wikipedia-ja; - wru = wikipedia-ru; - y = yahoo; - yt = youtube; - }; + searchEngines = rec { + aliexpress = "https://www.aliexpress.com/wholesale?SearchText={}"; + ansible = "https://galaxy.ansible.com/search?keywords={}"; + arch = "https://wiki.archlinux.org/?search={}"; + crates = "https://crates.io/search?q={}"; + crawl = "http://crawl.chaosforge.org/index.php?search={}"; + discogs = "https://www.discogs.com/search/?q={}"; + dockerdocs = "https://docs.docker.com/search/?q={}"; + dockerhub = "https://hub.docker.com/search?q={}"; + doublegis = "https://2gis.ru/search/{}"; + duckduckgo = "https://duckduckgo.com/?q={}'"; + dwarffortress = "https://dwarffortresswiki.org/index.php?search={}"; + ebay = "https://www.ebay.com/sch/i.html?_nkw={}"; + ecosia = "https://www.ecosia.org/search?q={}"; + factorio = "https://wiki.factorio.com/index.php?search={}"; + genius = "https://genius.com/search?q={}"; + github = "https://github.com/search?q={}"; + godocs = "https://godocs.io/?q={}"; + gogdb = "https://www.gogdb.org/products?search={}"; + google = "https://www.google.com/search?q={}"; + google-images = "https://www.google.com/search?q={}&tbm=isch"; + gopkgs = "https://pkg.go.dev/search?q={}"; + habr = "https://habr.com/ru/search/?q={}"; + hackage = "https://hackage.haskell.org/packages/search?terms={}"; + hackernews = "https://hn.algolia.com/?q={}"; + headhunter = "https://hh.ru/search/vacancy?st=searchVacancy&text={}"; + hoogle = "https://hoogle.haskell.org/?hoogle={}"; + jisho = "https://jisho.org/search/{}"; + kotobank = "https://kotobank.jp/gs/?q={}"; + kubernetes = "https://kubernetes.io/search/?q={}"; + lastfm = "https://www.last.fm/search?q={}"; + lobsters = "https://lobste.rs/search?q=test{}"; + mdn = "https://developer.mozilla.org/en-US/search?q={}"; + melpa = "https://melpa.org/#/?q={}"; + moddb = "https://www.moddb.com/search?q={}"; + musicbrainz = "https://musicbrainz.org/search?query={}"; + nix-issues = "https://github.com/NixOS/nix/issues?q={}"; + nix-prs = "https://github.com/NixOS/nix/pulls?q={}"; + nixos-flakes = "https://search.nixos.org/flakes?query={}"; + nixos-options = "https://search.nixos.org/options?query={}"; + nixos-packages = "https://search.nixos.org/packages?query={}"; + nixos-wiki = "https://nixos.wiki/index.php?search={}"; + nixpkgs-issues = "https://github.com/NixOS/nixpkgs/issues?q={}"; + nixpkgs-prs = "https://github.com/NixOS/nixpkgs/pulls?q={}"; + openstreetmap = "https://www.openstreetmap.org/search?query={}"; + ozon = "https://www.ozon.ru/search/?text={}"; + protondb = "https://www.protondb.com/search?q={}"; + pypi = "https://pypi.org/search/?q={}"; + pythondocs = "https://docs.python.org/3/search.html?q={}"; + rateyourmusic = "https://rateyourmusic.com/search?searchterm={}"; + riichi = "https://riichi.wiki/index.php?search={}"; + rustdoc = "https://doc.rust-lang.org/std/?search={}"; + searx = "https://searx.tiekoetter.com/search?q={}"; + slashdot = "https://slashdot.org/index2.pl?fhfilter={}"; + sourcehut = "https://sr.ht/projects?search={}"; + steam = "https://store.steampowered.com/search/?term={}"; + steamdb = "https://steamdb.info/search/?a=app&q={}"; + ubuntu = "https://wiki.ubuntu.com/Home?action=fullsearch&value={}"; + wikipedia-en = "https://en.wikipedia.org/w/index.php?search={}"; + wikipedia-ru = "https://ru.wikipedia.org/w/index.php?search={}"; + wikipedia-ja = "https://ja.wikipedia.org/w/index.php?search={}"; + wolphramalpha = "https://www.wolframalpha.com/input/?i={}"; + yahoo = "https://yahoo.com/search/?text={}"; + yahoo-images = "https://yahoo.com/images/search?text={}"; + yahoo-market = "https://market.yahoo.com/search?text={}"; + youtube = "https://yewtu.be/search?q={}"; + + aw = arch; + d = duckduckgo; + do = dockerhub; + docker = dockerhub; + dod = dockerdocs; + g = google; + gh = github; + h = hoogle; + k = kubernetes; + mb = musicbrainz; + n = nixos-options; + nw = nixos-wiki; + py = pypi; + pyd = pythondocs; + rym = rateyourmusic; + s = searx; + sh = sourcehut; + sr = sourcehut; + w = wikipedia-en; + wen = wikipedia-en; + wja = wikipedia-ja; + wru = wikipedia-ru; + y = yahoo; + yt = youtube; + }; - settings = { - changelog_after_upgrade = "never"; - - content = { - autoplay = false; - cookies.accept = "all"; - default_encoding = "utf-8"; - desktop_capture = "ask"; - dns_prefetch = false; - geolocation = false; - headers.do_not_track = true; - javascript.enabled = true; - prefers_reduced_motion = true; - webgl = true; - - blocking = { - enabled = true; - method = "adblock"; - adblock.lists = [ - "https://easylist.to/easylist/easylist.txt" - "https://easylist.to/easylist/easyprivacy.txt" - "https://easylist.to/easylist/fanboy-social.txt" - "https://secure.fanboy.co.nz/fanboy-annoyance.txt" - "https://secure.fanboy.co.nz/fanboy-cookiemonster.txt" - ]; - }; + settings = { + changelog_after_upgrade = "never"; + + content = { + autoplay = false; + cookies.accept = "all"; + default_encoding = "utf-8"; + desktop_capture = "ask"; + dns_prefetch = false; + geolocation = false; + headers.do_not_track = true; + javascript.enabled = true; + prefers_reduced_motion = true; + webgl = true; + + blocking = { + enabled = true; + method = "adblock"; + adblock.lists = [ + "https://easylist.to/easylist/easylist.txt" + "https://easylist.to/easylist/easyprivacy.txt" + "https://easylist.to/easylist/fanboy-social.txt" + "https://secure.fanboy.co.nz/fanboy-annoyance.txt" + "https://secure.fanboy.co.nz/fanboy-cookiemonster.txt" + ]; }; + }; - completion = { - height = "50%"; - show = "auto"; - shrink = true; - timestamp_format = "%y-%m-%d"; - min_chars = 3; - open_categories = ["bookmarks" "quickmarks" "history"]; - - scrollbar = { - width = 0; - padding = 0; - }; + completion = { + height = "50%"; + show = "auto"; + shrink = true; + timestamp_format = "%y-%m-%d"; + min_chars = 3; + open_categories = ["bookmarks" "quickmarks" "history"]; + + scrollbar = { + width = 0; + padding = 0; }; + }; - downloads = { - location = { - directory = config.userDirs.download; - prompt = true; - }; - remove_finished = 0; - }; - - editor.command = [ - ( - if alacritty.enable - then "${pkgs.alacritty}/bin/alacritty" - else "${pkgs.xterm}/bin/xterm" - ) - "-e" - "${config.programs.vim.package}/bin/vim" - "-f" - "{}" - ]; - - hints = { - auto_follow = "unique-match"; - auto_follow_timeout = 0; - border = "0px"; - min_chars = 1; - scatter = false; - uppercase = false; + downloads = { + location = { + directory = config.userDirs.download; + prompt = true; }; + remove_finished = 0; + }; - hints.radius = 0; - keyhint.radius = 0; - prompt.radius = 0; + editor.command = [ + ( + if alacritty.enable + then "${pkgs.alacritty}/bin/alacritty" + else "${pkgs.xterm}/bin/xterm" + ) + "-e" + "${config.programs.vim.package}/bin/vim" + "-f" + "{}" + ]; + + hints = { + auto_follow = "unique-match"; + auto_follow_timeout = 0; + border = "0px"; + min_chars = 1; + scatter = false; + uppercase = false; + }; - scrolling = { - bar = "never"; - smooth = false; - }; + hints.radius = 0; + keyhint.radius = 0; + prompt.radius = 0; - spellcheck.languages = ["en-GB" "en-US" "ru-RU"]; + scrolling = { + bar = "never"; + smooth = false; + }; - statusbar.position = "bottom"; + spellcheck.languages = ["en-US" "en-GB" "ru-RU"]; - tabs = { - position = "top"; + statusbar.position = "bottom"; - title = { - alignment = "left"; - format = "{audio}{index} : {current_title}"; - format_pinned = "{audio}{index}"; - }; + tabs = { + position = "top"; - min_width = -1; - max_width = -1; + title = { + alignment = "left"; + format = "{audio}{index} : {current_title}"; + format_pinned = "{audio}{index}"; + }; - indicator.width = 0; + min_width = -1; + max_width = -1; - pinned = { - shrink = true; - frozen = false; - }; + indicator.width = 0; - close_mouse_button = "middle"; - mousewheel_switching = false; + pinned = { + shrink = true; + frozen = false; + }; - background = true; - select_on_remove = "next"; - new_position = { - related = "next"; - unrelated = "last"; - }; + close_mouse_button = "middle"; + mousewheel_switching = false; - favicons = { - show = "pinned"; - scale = 0.75; - }; + background = true; + select_on_remove = "next"; + new_position = { + related = "next"; + unrelated = "last"; }; - url = rec { - default_page = "about:blank"; - start_pages = [default_page]; + favicons = { + show = "pinned"; + scale = 0.75; }; + }; - window = { - hide_decoration = false; - title_format = "{perc}{current_title}{title_sep}qutebrowser"; - }; + url = rec { + default_page = "about:blank"; + start_pages = [default_page]; + }; + + window = { + hide_decoration = false; + title_format = "{perc}{current_title}{title_sep}qutebrowser"; + }; - colors = with config.colourScheme; { - completion = rec { + colors = with config.colourScheme; { + completion = rec { + fg = white; + match.fg = red; + odd.bg = black; + even.bg = odd.bg; + category = { fg = white; - match.fg = red; - odd.bg = black; - even.bg = odd.bg; - category = { - fg = white; - bg = black; - border = { - top = black; - bottom = black; - }; - }; - item.selected = { - fg = black; - bg = white; - border = { - top = white; - bottom = white; - }; - }; - scrollbar = { - fg = white; - bg = black; + bg = black; + border = { + top = black; + bottom = black; }; }; - contextmenu = { - menu = { - fg = white; - bg = black; - }; - selected = { - fg = black; - bg = white; - }; - disabled = { - fg = brightBlack; - bg = black; + item.selected = { + fg = black; + bg = white; + border = { + top = white; + bottom = white; }; }; - downloads = { - bar.bg = black; - start = { - fg = green; - bg = black; - }; - stop = { - fg = yellow; - bg = black; - }; - error = { - fg = red; - bg = black; - }; - system = { - fg = "none"; - bg = "none"; - }; - }; - hints = { + scrollbar = { fg = white; - match.fg = red; bg = black; }; - keyhint = { + }; + contextmenu = { + menu = { fg = white; - suffix.fg = red; bg = black; }; - messages = { - error = rec { - bg = black; - fg = red; - border = bg; - }; - info = rec { - fg = blue; - bg = black; - border = bg; - }; - warning = rec { - fg = yellow; - bg = black; - border = bg; - }; + selected = { + fg = black; + bg = white; }; - prompts = rec { - fg = white; + disabled = { + fg = brightBlack; bg = black; - selected = { - fg = black; - bg = white; - }; + }; + }; + downloads = { + bar.bg = black; + start = { + fg = green; + bg = black; + }; + stop = { + fg = yellow; + bg = black; + }; + error = { + fg = red; + bg = black; + }; + system = { + fg = "none"; + bg = "none"; + }; + }; + hints = { + fg = white; + match.fg = red; + bg = black; + }; + keyhint = { + fg = white; + suffix.fg = red; + bg = black; + }; + messages = { + error = rec { + bg = black; + fg = red; border = bg; }; - statusbar = { - normal = { - bg = black; - fg = white; - }; - command = { - bg = black; - fg = white; - }; - insert = { - bg = green; - fg = black; - }; - passthrough = { - bg = blue; - fg = black; + info = rec { + fg = blue; + bg = black; + border = bg; + }; + warning = rec { + fg = yellow; + bg = black; + border = bg; + }; + }; + prompts = rec { + fg = white; + bg = black; + selected = { + fg = black; + bg = white; + }; + border = bg; + }; + statusbar = { + normal = { + bg = black; + fg = white; + }; + command = { + bg = black; + fg = white; + }; + insert = { + bg = green; + fg = black; + }; + passthrough = { + bg = blue; + fg = black; + }; + private = { + bg = magenta; + fg = black; + }; + url = { + fg = blue; + hover.fg = brightBlue; + success = { + http.fg = brightGreen; + https.fg = brightGreen; }; - private = { - bg = magenta; + warn.fg = brightYellow; + error.fg = brightRed; + }; + }; + tabs = rec { + bar.bg = black; + even = { + bg = black; + fg = white; + }; + odd = with even; {inherit bg fg;}; + selected = rec { + even = { + bg = white; fg = black; }; - url = { - fg = blue; - hover.fg = brightBlue; - success = { - http.fg = brightGreen; - https.fg = brightGreen; - }; - warn.fg = brightYellow; - error.fg = brightRed; - }; + odd = with even; {inherit bg fg;}; }; - tabs = rec { - bar.bg = black; + pinned = rec { even = { - bg = black; - fg = white; + bg = brightBlack; + fg = brightWhite; }; odd = with even; {inherit bg fg;}; - selected = rec { - even = { - bg = white; - fg = black; - }; - odd = with even; {inherit bg fg;}; - }; - pinned = rec { - even = { - bg = brightBlack; - fg = brightWhite; - }; - odd = with even; {inherit bg fg;}; + }; + indicator = { + start = green; + stop = yellow; + error = red; + system = "none"; + }; + }; + webpage = { + bg = "white"; + darkmode = { + enabled = false; + algorithm = "lightness-cielab"; + contrast = 0.0; + grayscale = { + all = false; + images = 0.0; }; - indicator = { - start = green; - stop = yellow; - error = red; - system = "none"; + policy = { + images = "smart"; + page = "smart"; }; - }; - webpage = { - bg = "white"; - darkmode = { - enabled = false; - algorithm = "lightness-cielab"; - contrast = 0.0; - grayscale = { - all = false; - images = 0.0; - }; - policy = { - images = "smart"; - page = "smart"; - }; - threshold = { - background = 0; - text = 256; - }; + threshold = { + background = 0; + text = 256; }; - preferred_color_scheme = "auto"; }; + preferred_color_scheme = "auto"; }; + }; - fonts = - (with config.fontScheme.monospaceFont; { - default_family = family; - default_size = (toString size) + "pt"; - }) - // { - web = with config.fontScheme; { - family = rec { - standard = sans_serif; - fixed = monospaceFont.family; - serif = serifFont.family; - sans_serif = sansSerifFont.family; - cursive = null; - fantasy = null; - }; - size = rec { - default = sansSerifFont.size; - default_fixed = monospaceFont.size; - minimum = 0; - minimum_logical = default / 2; - }; + fonts = + (with config.fontScheme.monospaceFont; { + default_family = family; + default_size = (toString size) + "pt"; + }) + // { + web = with config.fontScheme; { + family = rec { + standard = sans_serif; + fixed = monospaceFont.family; + serif = serifFont.family; + sans_serif = sansSerifFont.family; + cursive = null; + fantasy = null; }; - } - // mapListToAttrs (_: "default_size default_family") [ - "completion.category" - "completion.entry" - "contextmenu" - "debug_console" - "downloads" - "hints" - "keyhint" - "messages.error" - "messages.info" - "messages.warning" - "prompts" - "statusbar" - ]; + size = rec { + default = sansSerifFont.size; + default_fixed = monospaceFont.size; + minimum = 0; + minimum_logical = default / 2; + }; + }; + } + // mapListToAttrs (_: "default_size default_family") [ + "completion.category" + "completion.entry" + "contextmenu" + "debug_console" + "downloads" + "hints" + "keyhint" + "messages.error" + "messages.info" + "messages.warning" + "prompts" + "statusbar" + ]; - qt = mkIf kde.enable { - force_platform = null; - force_platformtheme = "KDE"; - }; + qt = mkIf kde.enable { + force_platform = null; + force_platformtheme = "KDE"; }; + }; - extraConfig = - (let - mkPaddingDictionary = { - name, - bottom, - left, - right, - top, - }: let - n = "c.${name}.padding"; - b = "'bottom': ${toString bottom}"; - l = "'left': ${toString left}"; - r = "'right': ${toString right}"; - t = "'top': ${toString top}"; - in "${n} = {${b}, ${l}, ${r}, ${t}}"; - - final = map mkPaddingDictionary [ - { - name = "hints"; - bottom = 3; - left = 3; - right = 3; - top = 3; - } - { - name = "statusbar"; - bottom = 1; - left = 0; - right = 3; - top = 1; - } - { - name = "tabs"; - bottom = 1; - left = 6; - right = 6; - top = 1; - } - ]; - in - concatStringsSep "\n" final + "\n") - + (let - allowSetting = setting: url: "config.set('content.${setting}', True, '${url}')"; - - allowMediaCaptureSetting = url: [ - (allowSetting "desktop_capture" url) - (allowSetting "media.audio_video_capture" url) - ]; - allowedMediaCapture = flatten (map allowMediaCaptureSetting [ - "https://discord.com" - "https://meet.google.com" - "https://web.skype.com" - ]); - - allowNotificationsSetting = allowSetting "notifications.enabled"; - allowedNotifications = map allowNotificationsSetting [ - "https://discord.com" - "https://web.skype.com" - "https://web.telegram.org" - "https://web.whatsapp.com" - ]; + extraConfig = + (let + mkPaddingDictionary = { + name, + bottom, + left, + right, + top, + }: let + n = "c.${name}.padding"; + b = "'bottom': ${toString bottom}"; + l = "'left': ${toString left}"; + r = "'right': ${toString right}"; + t = "'top': ${toString top}"; + in "${n} = {${b}, ${l}, ${r}, ${t}}"; + + final = map mkPaddingDictionary [ + { + name = "hints"; + bottom = 3; + left = 3; + right = 3; + top = 3; + } + { + name = "statusbar"; + bottom = 1; + left = 0; + right = 3; + top = 1; + } + { + name = "tabs"; + bottom = 1; + left = 6; + right = 6; + top = 1; + } + ]; + in + concatStringsSep "\n" final + "\n") + + (let + allowSetting = setting: url: "config.set('content.${setting}', True, '${url}')"; + + allowMediaCaptureSetting = url: [ + (allowSetting "desktop_capture" url) + (allowSetting "media.audio_video_capture" url) + ]; + allowedMediaCapture = flatten (map allowMediaCaptureSetting [ + "https://discord.com" + "https://web.telegram.org" + ]); + + allowNotificationsSetting = allowSetting "notifications.enabled"; + allowedNotifications = map allowNotificationsSetting [ + "https://discord.com" + "https://web.telegram.org" + ]; - final = allowedMediaCapture ++ allowedNotifications; - in - concatStringsSep "\n" final + "\n"); - }; + final = allowedMediaCapture ++ allowedNotifications; + in + concatStringsSep "\n" final + "\n"); }; services.psd.enable = true; diff --git a/modules/nixfiles/rtorrent.nix b/modules/nixfiles/rtorrent.nix index 9f28c61..834e36d 100644 --- a/modules/nixfiles/rtorrent.nix +++ b/modules/nixfiles/rtorrent.nix @@ -25,7 +25,7 @@ in { user = "rtorrent"; group = "rtorrent"; baseDir = "/var/lib/rtorrent"; - rpcSocket = "/run/rtorrent/rpc.socket"; + rpcSocket = "${baseDir}/rpc.socket"; in mkIf cfg.enable (mkMerge [ (let @@ -40,12 +40,98 @@ in { seedDir = "${baseDir}/seed"; sessionDir = "${baseDir}/session"; logDir = "${baseDir}/log"; + configFile = let + moveCompleted = let + pkg = pkgs.writeShellApplication { + name = "move-completed"; + runtimeInputs = with pkgs; [ + coreutils-full + gnused + findutils + ]; + text = '' + set -x + + leech_path="$1" + seed_path="$2" + # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')" + + mkdir -pv "$seed_path" + mv -fv "$leech_path" "$seed_path" + ''; + }; + in "${pkg}/bin/move-completed"; + in + pkgs.writeText "rtorrent.rc" '' + method.insert = cfg.leech, private|const|string, (cat, "${leechDir}") + method.insert = cfg.seed, private|const|string, (cat, "${seedDir}") + method.insert = cfg.session, private|const|string, (cat, "${sessionDir}") + method.insert = cfg.log, private|const|string, (cat, "${logDir}") + method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}") + + directory.default.set = (cat, (cfg.leech)) + session.path.set = (cat, (cfg.session)) + + network.port_range.set = ${toString port}-${toString port} + network.port_random.set = no + + dht.mode.set = disable + protocol.pex.set = no + + trackers.use_udp.set = no + + protocol.encryption.set = allow_incoming,try_outgoing,enable_retry + + pieces.memory.max.set = ${toString (pow 2 11)}M + pieces.preload.type.set = 2 + + network.xmlrpc.size_limit.set = ${toString (pow 2 17)} + + network.max_open_files.set = ${toString (pow 2 10)} + network.max_open_sockets.set = ${toString (pow 2 10)} + + network.http.max_open.set = ${toString (pow 2 8)} + + throttle.global_down.max_rate.set_kb = 0 + throttle.global_up.max_rate.set_kb = 0 + + encoding.add = UTF-8 + system.umask.set = 0027 + system.cwd.set = (directory.default) + + network.scgi.open_local = (cat, (cfg.rpcsocket)) + + method.insert = d.move_completed, simple, "\ + d.directory.set=$argument.1=;\ + execute=${moveCompleted}, $argument.0=, $argument.1=;\ + d.save_full_session=\ + " + method.insert = d.leech_path, simple, "\ + if=(d.is_multi_file),\ + (cat, (d.directory), /),\ + (cat, (d.directory), /, (d.name))\ + " + method.insert = d.seed_path, simple, "\ + cat=$cfg.seed=, /, $d.custom1=\ + " + method.set_key = event.download.finished, move_complete, "\ + d.move_completed=$d.leech_path=, $d.seed_path=\ + " + + log.open_file = "log", (cat, (cfg.log), "/", "default.log") + log.add_output = "info", "log" + log.execute = (cat, (cfg.log), "/", "execute.log") + ''; in { - User = user; - Group = group; - Type = "simple"; + Restart = "on-failure"; + RestartSec = 3; + KillMode = "process"; KillSignal = "SIGHUP"; + + User = user; + Group = group; + ExecStartPre = concatStringsSep " " [ "${pkgs.coreutils-full}/bin/mkdir -p" leechDir @@ -53,104 +139,44 @@ in { sessionDir logDir ]; - ExecStart = let - configFile = let - moveCompleted = let - pkg = pkgs.writeShellApplication { - name = "move-completed"; - runtimeInputs = with pkgs; [ - coreutils-full - gnused - findutils - ]; - text = '' - set -x - - leech_path="$1" - seed_path="$2" - # seed_path="$(echo "$2" | sed 's@+@ @g;s@%@\\x@g' | xargs -0 printf '%b')" - - mkdir -p "$seed_path" - mv -u "$leech_path" "$seed_path" - ''; - }; - in "${pkg}/bin/move-completed"; - in - pkgs.writeText "rtorrent.rc" '' - method.insert = cfg.leech, private|const|string, (cat, "${leechDir}") - method.insert = cfg.seed, private|const|string, (cat, "${seedDir}") - method.insert = cfg.session, private|const|string, (cat, "${sessionDir}") - method.insert = cfg.log, private|const|string, (cat, "${logDir}") - method.insert = cfg.rpcsocket, private|const|string, (cat, "${rpcSocket}") - - directory.default.set = (cat, (cfg.leech)) - session.path.set = (cat, (cfg.session)) - - network.port_range.set = ${toString port}-${toString port} - network.port_random.set = no - - dht.mode.set = disable - protocol.pex.set = no - - trackers.use_udp.set = no - - protocol.encryption.set = allow_incoming,try_outgoing,enable_retry - - pieces.memory.max.set = 2048M - pieces.preload.type.set = 2 - - network.max_open_files.set = 1024 - network.max_open_sockets.set = 1024 - - network.http.max_open.set = 128 - - throttle.global_down.max_rate.set_kb = 0 - throttle.global_up.max_rate.set_kb = 0 - - encoding.add = UTF-8 - system.umask.set = 0027 - system.cwd.set = (directory.default) - - network.scgi.open_local = (cat, (cfg.rpcsocket)) - schedule = scgi_group, 0, 0, "\ - execute.nothrow=chown, \":${group}\", (cfg.rpcsocket)\ - " - schedule = scgi_permission, 0, 0, "\ - execute.nothrow=chmod, \"g+w,o=\", (cfg.rpcsocket)\ - " - - method.insert = d.move_completed, simple, "\ - d.directory.set=$argument.1=;\ - execute=${moveCompleted}, $argument.0=, $argument.1=;\ - d.save_full_session=\ - " - method.insert = d.leech_path, simple, "\ - if=(d.is_multi_file),\ - (cat, (d.directory), /),\ - (cat, (d.directory), /, (d.name))\ - " - method.insert = d.seed_path, simple, "\ - cat=$cfg.seed=, /, $d.custom1=\ - " - method.set_key = event.download.finished, move_complete, "\ - d.move_completed=$d.leech_path=, $d.seed_path=\ - " - - log.open_file = "log", (cat, (cfg.log), "/", "default.log") - log.add_output = "debug", "log" - log.execute = (cat, (cfg.log), "/", "execute.log") - ''; - in - concatStringsSep " " [ - "${pkgs.rtorrent}/bin/rtorrent" - "-n" - "-o system.daemon.set=true" - "-o import=${configFile}" - ]; - Restart = "on-failure"; - RestartSec = 3; + ExecStart = concatStringsSep " " [ + "${pkgs.rtorrent}/bin/rtorrent" + "-n" + "-o system.daemon.set=true" + "-o network.bind_address.set=0.0.0.0" + "-o import=${configFile}" + ]; + ExecStop = concatStringsSep " " [ + "${pkgs.coreutils-full}/bin/rm -rf" + rpcSocket + ]; + RuntimeDirectory = "rtorrent"; - RuntimeDirectoryMode = 755; + RuntimeDirectoryMode = 0750; + UMask = 0027; + AmbientCapabilities = [""]; + CapabilityBoundingSet = [""]; + LockPersonality = true; + MemoryDenyWriteExecute = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProcSubset = "pid"; + RemoveIPC = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = ["@system-service" "~@resources" "~@privileged"]; }; wantedBy = ["multi-user.target"]; }; @@ -216,10 +242,12 @@ in { after = ["network.target" "rtorrent.service"]; path = with pkgs; [mediainfo]; serviceConfig = { + Restart = "on-failure"; + RestartSec = 3; + User = user; Group = group; - Type = "simple"; - KillMode = "process"; + ExecStart = concatStringsSep " " [ "${pkg}/bin/flood" "--allowedpath=${baseDir}" @@ -231,8 +259,40 @@ in { "--ssl=false" "--auth=none" ]; - Restart = "on-failure"; - RestartSec = 3; + + RuntimeDirectory = "rtorrent"; + RuntimeDirectoryMode = 0750; + UMask = 0027; + AmbientCapabilities = [""]; + CapabilityBoundingSet = [""]; + LockPersonality = true; + NoNewPrivileges = true; + PrivateDevices = true; + PrivateTmp = true; + PrivateUsers = true; + ProtectClock = true; + ProtectControlGroups = true; + ProtectHome = true; + ProtectHostname = true; + ProtectKernelLogs = true; + ProtectKernelModules = true; + ProtectKernelTunables = true; + ProcSubset = "pid"; + ProtectProc = "invisible"; + RemoveIPC = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + SystemCallArchitectures = "native"; + SystemCallFilter = [ + "~@cpu-emulation" + "~@debug" + "~@mount" + "~@obsolete" + "~@privileged" + "~@resources" + ]; }; wantedBy = ["multi-user.target"]; }; diff --git a/modules/nixfiles/soju.nix b/modules/nixfiles/soju.nix index a7d30f7..14faf00 100644 --- a/modules/nixfiles/soju.nix +++ b/modules/nixfiles/soju.nix @@ -40,12 +40,21 @@ in { db = "soju"; in mkIf cfg.enable { + nixfiles.modules.postgresql = { + enable = true; + extraPostStart = [ + '' + $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' + '' + ]; + }; + services.postgresql = { ensureDatabases = [db]; ensureUsers = [ { name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; } ]; }; @@ -56,16 +65,17 @@ in { after = ["network-online.target" "postgresql.service"]; serviceConfig = { ExecStart = let + # https://soju.im/doc/soju.1.html configFile = pkgs.writeText "soju.conf" '' listen ${cfg.protocol}://${cfg.address}:${toString cfg.port} - db postgres "${ + db postgres ${ concatStringsSep " " [ "host=/run/postgresql" "user=${db}" "dbname=${db}" "sslmode=disable" ] - }" + } hostname ${cfg.domain} title ${cfg.domain} ''; diff --git a/modules/nixfiles/vaultwarden.nix b/modules/nixfiles/vaultwarden.nix index dc8bb84..7d51667 100644 --- a/modules/nixfiles/vaultwarden.nix +++ b/modules/nixfiles/vaultwarden.nix @@ -17,105 +17,118 @@ in { }; }; - config = mkIf cfg.enable { - secrets.vaultwarden-environment = { - file = "${inputs.self}/secrets/vaultwarden-environment"; - owner = "vaultwarden"; - group = "vaultwarden"; - }; + config = let + db = "vaultwarden"; + in + mkIf cfg.enable { + secrets.vaultwarden-environment = { + file = "${inputs.self}/secrets/vaultwarden-environment"; + owner = "vaultwarden"; + group = "vaultwarden"; + }; - nixfiles.modules = { - nginx = { - enable = true; - upstreams = with config.services.vaultwarden.config; { - vaultwarden_rocket.servers."${ROCKET_ADDRESS}:${toString ROCKET_PORT}" = {}; - vaultwarden_websocket.servers."${WEBSOCKET_ADDRESS}:${toString WEBSOCKET_PORT}" = {}; - }; - virtualHosts.${cfg.domain} = { - locations."/" = { - proxyPass = "http://vaultwarden_rocket"; - proxyWebsockets = true; - }; - locations."/notifications/hub" = { - proxyPass = "http://vaultwarden_websocket"; - proxyWebsockets = true; + nixfiles.modules = { + nginx = { + enable = true; + upstreams = with config.services.vaultwarden.config; { + vaultwarden_rocket.servers."${ROCKET_ADDRESS}:${toString ROCKET_PORT}" = {}; + vaultwarden_websocket.servers."${WEBSOCKET_ADDRESS}:${toString WEBSOCKET_PORT}" = {}; }; - locations."/notifications/hub/negotiate" = { - proxyPass = "http://vaultwarden_rocket"; - proxyWebsockets = true; + virtualHosts.${cfg.domain} = { + locations."/" = { + proxyPass = "http://vaultwarden_rocket"; + proxyWebsockets = true; + }; + locations."/notifications/hub" = { + proxyPass = "http://vaultwarden_websocket"; + proxyWebsockets = true; + }; + locations."/notifications/hub/negotiate" = { + proxyPass = "http://vaultwarden_rocket"; + proxyWebsockets = true; + }; }; }; + postgresql = { + enable = true; + extraPostStart = [ + '' + $PSQL "${db}" -tAc 'GRANT ALL ON SCHEMA "public" TO "${db}"' + '' + ]; + }; }; - postgresql.enable = true; - }; - services = let - db = "vaultwarden"; - in { - vaultwarden = { - enable = true; - config = { - TZ = config.time.timeZone; + services = { + vaultwarden = { + enable = true; + config = { + TZ = config.time.timeZone; + + WEB_VAULT_ENABLED = true; + + DOMAIN = optionalString (cfg.domain != null) "http://${cfg.domain}"; - WEB_VAULT_ENABLED = true; + SIGNUPS_ALLOWED = false; + INVITATIONS_ALLOWED = false; - DOMAIN = optionalString (cfg.domain != null) "http://${cfg.domain}"; + ORG_CREATION_USERS = "none"; - SIGNUPS_ALLOWED = false; - INVITATIONS_ALLOWED = true; + PASSWORD_HINTS_ALLOWED = false; + SHOW_PASSWORD_HINT = false; - ROCKET_ADDRESS = "127.0.0.1"; - ROCKET_PORT = 8812; + ROCKET_ADDRESS = "127.0.0.1"; + ROCKET_PORT = 8812; - WEBSOCKET_ENABLED = true; - WEBSOCKET_ADDRESS = "127.0.0.1"; - WEBSOCKET_PORT = 8813; + WEBSOCKET_ENABLED = true; + WEBSOCKET_ADDRESS = "127.0.0.1"; + WEBSOCKET_PORT = 8813; - LOG_LEVEL = "error"; + LOG_LEVEL = "error"; - DATABASE_URL = "postgresql://${db}@/${db}"; + DATABASE_URL = "postgresql://${db}@/${db}"; + }; + dbBackend = "postgresql"; + environmentFile = config.secrets.vaultwarden-environment.path; + }; + + postgresql = { + ensureDatabases = [db]; + ensureUsers = [ + { + name = db; + ensurePermissions."DATABASE \"${db}\"" = "ALL"; + } + ]; }; - dbBackend = "postgresql"; - environmentFile = config.secrets.vaultwarden-environment.path; - }; - postgresql = { - ensureDatabases = [db]; - ensureUsers = [ - { - name = db; - ensurePermissions."DATABASE \"${db}\"" = "ALL PRIVILEGES"; - } - ]; + fail2ban.jails = mkIf config.nixfiles.modules.fail2ban.enable { + vaultwarden = '' + enabled = true + filter = vaultwarden + port = http,https + ''; + vaultwarden-admin = '' + enabled = true + filter = vaultwarden-admin + port = http,https + ''; + }; }; - fail2ban.jails = mkIf config.nixfiles.modules.fail2ban.enable { - vaultwarden = '' - enabled = true - filter = vaultwarden - port = http,https + environment.etc = mkIf config.nixfiles.modules.fail2ban.enable { + "fail2ban/filter.d/vaultwarden.conf".text = '' + [Definition] + failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$ + ignoreregex = + journalmatch = _SYSTEMD_UNIT=vaultwarden.service ''; - vaultwarden-admin = '' - enabled = true - filter = vaultwarden-admin - port = http,https + "fail2ban/filter.d/vaultwarden-admin.conf".text = '' + [Definition] + failregex = ^.*Invalid admin token\. IP: <ADDR>.*$ + ignoreregex = + journalmatch = _SYSTEMD_UNIT=vaultwarden.service ''; }; }; - - environment.etc = mkIf config.nixfiles.modules.fail2ban.enable { - "fail2ban/filter.d/vaultwarden.conf".text = '' - [Definition] - failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$ - ignoreregex = - journalmatch = _SYSTEMD_UNIT=vaultwarden.service - ''; - "fail2ban/filter.d/vaultwarden-admin.conf".text = '' - [Definition] - failregex = ^.*Invalid admin token\. IP: <ADDR>.*$ - ignoreregex = - journalmatch = _SYSTEMD_UNIT=vaultwarden.service - ''; - }; - }; } |