at master 5.0 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.programs.rust-motd; 10 format = pkgs.formats.toml { }; 11 12 # Order the sections in the TOML according to the order of sections 13 # in `cfg.order`. 14 motdConf = 15 pkgs.runCommand "motd.toml" 16 { 17 __structuredAttrs = true; 18 inherit (cfg) order settings; 19 nativeBuildInputs = [ 20 pkgs.remarshal 21 pkgs.jq 22 ]; 23 } 24 '' 25 cat "$NIX_ATTRS_JSON_FILE" \ 26 | jq '.settings as $settings 27 | .order 28 | map({ key: ., value: $settings."\(.)" }) 29 | from_entries' -r \ 30 | json2toml /dev/stdin "$out" 31 ''; 32in 33{ 34 options.programs.rust-motd = { 35 enable = lib.mkEnableOption "rust-motd, a Message Of The Day (MOTD) generator"; 36 enableMotdInSSHD = lib.mkOption { 37 default = true; 38 type = lib.types.bool; 39 description = '' 40 Whether to let `openssh` print the 41 result when entering a new `ssh`-session. 42 By default either nothing or a static file defined via 43 [](#opt-users.motd) is printed. Because of that, 44 the latter option is incompatible with this module. 45 ''; 46 }; 47 refreshInterval = lib.mkOption { 48 default = "*:0/5"; 49 type = lib.types.str; 50 description = '' 51 Interval in which the {manpage}`motd(5)` file is refreshed. 52 For possible formats, please refer to {manpage}`systemd.time(7)`. 53 ''; 54 }; 55 order = lib.mkOption { 56 type = lib.types.listOf lib.types.str; 57 default = builtins.attrNames cfg.settings; 58 defaultText = lib.literalExpression "attrNames cfg.settings"; 59 description = '' 60 The order of the sections in [](#opt-programs.rust-motd.settings). 61 By default they are ordered alphabetically. 62 63 Context: since attribute sets in Nix are always 64 ordered alphabetically internally this means that 65 66 ```nix 67 { 68 uptime = { /* ... */ }; 69 banner = { /* ... */ }; 70 } 71 ``` 72 73 will still have `banner` displayed before `uptime`. 74 75 To work around that, this option can be used to define the order of all keys, 76 i.e. 77 78 ```nix 79 { 80 order = [ 81 "uptime" 82 "banner" 83 ]; 84 } 85 ``` 86 87 makes sure that `uptime` is placed before `banner` in the motd. 88 ''; 89 }; 90 settings = lib.mkOption { 91 type = lib.types.attrsOf format.type; 92 description = '' 93 Settings on what to generate. Please read the 94 [upstream documentation](https://github.com/rust-motd/rust-motd/blob/main/README.md#configuration) 95 for further information. 96 ''; 97 }; 98 }; 99 config = lib.mkIf cfg.enable { 100 assertions = [ 101 { 102 assertion = config.users.motd == ""; 103 message = '' 104 `programs.rust-motd` is incompatible with `users.motd`! 105 ''; 106 } 107 { 108 assertion = builtins.sort (a: b: a < b) cfg.order == builtins.attrNames cfg.settings; 109 message = '' 110 Please ensure that every section from `programs.rust-motd.settings` is present in 111 `programs.rust-motd.order`. 112 ''; 113 } 114 ]; 115 systemd.services.rust-motd = { 116 path = with pkgs; [ bash ]; 117 documentation = [ 118 "https://github.com/rust-motd/rust-motd/blob/v${pkgs.rust-motd.version}/README.md" 119 ]; 120 description = "motd generator"; 121 wantedBy = [ "multi-user.target" ]; 122 serviceConfig = { 123 ExecStart = "${pkgs.writeShellScript "update-motd" '' 124 ${pkgs.rust-motd}/bin/rust-motd ${motdConf} > motd 125 ''}"; 126 CapabilityBoundingSet = [ "" ]; 127 LockPersonality = true; 128 MemoryDenyWriteExecute = true; 129 NoNewPrivileges = true; 130 PrivateDevices = true; 131 PrivateTmp = true; 132 ProtectClock = true; 133 ProtectControlGroups = true; 134 ProtectHome = true; 135 ProtectHostname = true; 136 ProtectKernelModules = true; 137 ProtectKernelLogs = true; 138 ProtectKernelTunables = true; 139 ProtectSystem = "full"; 140 StateDirectory = "rust-motd"; 141 RestrictAddressFamilies = [ "AF_UNIX" ]; 142 RestrictNamespaces = true; 143 RestrictRealtime = true; 144 RestrictSUIDSGID = true; 145 RemoveIPC = true; 146 WorkingDirectory = "/var/lib/rust-motd"; 147 }; 148 }; 149 systemd.timers.rust-motd = { 150 wantedBy = [ "timers.target" ]; 151 timerConfig.OnCalendar = cfg.refreshInterval; 152 }; 153 154 security.pam.services.sshd.showMotd = lib.mkIf cfg.enableMotdInSSHD true; 155 users.motdFile = lib.mkIf cfg.enableMotdInSSHD "/var/lib/rust-motd/motd"; 156 157 programs.rust-motd.settings.global.show_legacy_warning = false; 158 159 services.openssh.extraConfig = 160 lib.mkIf (cfg.settings ? last_login && cfg.settings.last_login != { }) 161 '' 162 PrintLastLog no 163 ''; 164 }; 165 meta.maintainers = with lib.maintainers; [ ma27 ]; 166}