diff --git a/morph/grid/local/grid.nix b/morph/grid/local/grid.nix index 4a1524c6b6b7f5e085766aec6a79af5b569e72ba..c686cdd2582a659c0feef7440f815a752174cdaf 100644 --- a/morph/grid/local/grid.nix +++ b/morph/grid/local/grid.nix @@ -59,6 +59,7 @@ let grid = { publicKeyPath = toString ./. + "/${grid-config.publicKeyPath}"; privateKeyPath = toString ./. + "/${grid-config.privateKeyPath}"; + inherit (grid-config) monitoringvpnEndpoint; }; # Configure deployment management authorization for all systems in the grid. services.private-storage.deployment = { @@ -70,12 +71,11 @@ let payments = { imports = [ gridlib.issuer - (gridlib.customize-issuer (grid-config // { - monitoringvpnIPv4 = "172.23.23.11"; - })) + (gridlib.customize-issuer grid-config) grid-module ]; config = { + grid.monitoringvpnIPv4 = "172.23.23.11"; grid.publicIPv4 = "192.168.67.21"; }; }; @@ -84,12 +84,12 @@ let imports = [ gridlib.storage (gridlib.customize-storage (grid-config // { - monitoringvpnIPv4 = "172.23.23.12"; stateVersion = "19.09"; })) grid-module ]; config = { + grid.monitoringvpnIPv4 = "172.23.23.12"; grid.publicIPv4 = "192.168.67.22"; }; }; @@ -98,12 +98,12 @@ let imports = [ gridlib.storage (gridlib.customize-storage (grid-config // { - monitoringvpnIPv4 = "172.23.23.13"; stateVersion = "19.09"; })) grid-module ]; config = { + grid.monitoringvpnIPv4 = "172.23.23.13"; grid.publicIPv4 = "192.168.67.23"; }; }; @@ -119,12 +119,12 @@ let inherit (grid-config) letsEncryptAdminEmail monitoringDomains; googleOAuthClientID = grid-config.monitoringGoogleOAuthClientID; enableSlackAlert = false; - monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) grid-module ]; config = { + grid.monitoringvpnIPv4 = "172.23.23.1"; grid.publicIPv4 = "192.168.67.24"; }; }; diff --git a/morph/grid/production/grid.nix b/morph/grid/production/grid.nix index 950282f5573560f76355bcdcf4d6da51dacedd7d..131978dc437d52dd3dedb93b8c7a8888e7fe72e6 100644 --- a/morph/grid/production/grid.nix +++ b/morph/grid/production/grid.nix @@ -21,6 +21,7 @@ let grid = { publicKeyPath = toString ./. + "/${grid-config.publicKeyPath}"; privateKeyPath = toString ./. + "/${grid-config.privateKeyPath}"; + inherit (grid-config) monitoringvpnEndpoint; }; # Configure deployment management authorization for all systems in the grid. services.private-storage.deployment = { @@ -33,11 +34,12 @@ let imports = [ gridlib.issuer gridlib.hardware-aws - (gridlib.customize-issuer (grid-config // { - monitoringvpnIPv4 = "172.23.23.11"; - })) + (gridlib.customize-issuer grid-config) grid-module ]; + config = { + grid.monitoringvpnIPv4 = "172.23.23.11"; + }; }; monitoring = { @@ -52,11 +54,13 @@ let inherit (grid-config) letsEncryptAdminEmail monitoringDomains; googleOAuthClientID = grid-config.monitoringGoogleOAuthClientID; enableSlackAlert = true; - monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) grid-module ]; + config = { + grid.monitoringvpnIPv4 = "172.23.23.1"; + }; }; defineStorageNode = name: { vpnIP, stateVersion }: @@ -82,7 +86,6 @@ let # Then customize the storage system a little bit based on this node's particulars. (gridlib.customize-storage (grid-config // nodecfg // { - monitoringvpnIPv4 = vpnIP; inherit stateVersion; })) @@ -90,15 +93,19 @@ let grid-module ]; - # And supply configuration for those hardware / network / bootloader - # options. See the 100tb module for handling of this value. The module - # name is quoted because `1` makes `100tb` look an awful lot like a - # number. - "100tb".config = nodecfg; + config = { + grid.monitoringvpnIPv4 = vpnIP; - # Enable statistics gathering for MegaRAID cards. - # TODO would be nice to enable only on machines that have such a device. - services.private-storage.monitoring.megacli2prom.enable = true; + # And supply configuration for those hardware / network / bootloader + # options. See the 100tb module for handling of this value. The module + # name is quoted because `1` makes `100tb` look an awful lot like a + # number. + "100tb".config = nodecfg; + + # Enable statistics gathering for MegaRAID cards. + # TODO would be nice to enable only on machines that have such a device. + services.private-storage.monitoring.megacli2prom.enable = true; + }; }; # Define all of the storage nodes for this grid. diff --git a/morph/grid/testing/grid.nix b/morph/grid/testing/grid.nix index 334518774851c22738c93b323223f255d871a394..a2d844a26f9bd0acc3b279d8d630b0108bc1f39b 100644 --- a/morph/grid/testing/grid.nix +++ b/morph/grid/testing/grid.nix @@ -21,6 +21,7 @@ let grid = { publicKeyPath = toString ./. + "/${grid-config.publicKeyPath}"; privateKeyPath = toString ./. + "/${grid-config.privateKeyPath}"; + inherit (grid-config) monitoringvpnEndpoint; }; # Configure deployment management authorization for all systems in the grid. services.private-storage.deployment = { @@ -33,11 +34,12 @@ let imports = [ gridlib.issuer gridlib.hardware-aws - (gridlib.customize-issuer (grid-config // { - monitoringvpnIPv4 = "172.23.23.11"; - })) + (gridlib.customize-issuer grid-config) grid-module ]; + config = { + grid.monitoringvpnIPv4 = "172.23.23.11"; + }; }; storage001 = { @@ -46,11 +48,13 @@ let gridlib.hardware-aws ./testing001-hardware.nix (gridlib.customize-storage (grid-config // { - monitoringvpnIPv4 = "172.23.23.12"; stateVersion = "19.03"; })) grid-module ]; + config = { + grid.monitoringvpnIPv4 = "172.23.23.12"; + }; }; monitoring = { @@ -65,11 +69,13 @@ let inherit (grid-config) letsEncryptAdminEmail monitoringDomains; googleOAuthClientID = grid-config.monitoringGoogleOAuthClientID; enableSlackAlert = true; - monitoringvpnIPv4 = "172.23.23.1"; stateVersion = "19.09"; }) grid-module ]; + config = { + grid.monitoringvpnIPv4 = "172.23.23.1"; + }; }; # TBD: derive these automatically: diff --git a/morph/lib/base.nix b/morph/lib/base.nix index 7390654ac167909149b0a6f4dfae897b8f3f43a3..9b698b9629c12c7343fbd2e9eea5d2ee599b612e 100644 --- a/morph/lib/base.nix +++ b/morph/lib/base.nix @@ -18,6 +18,18 @@ corresponding private keys for the system. ''; }; + monitoringvpnIPv4 = lib.mkOption { + type = lib.types.str; + description = '' + The IPv4 address of this node on the monitoring VPN. + ''; + }; + monitoringvpnEndpoint = lib.mkOption { + type = lib.types.str; + description = '' + The domain name and port of the monitoring VPN endpoint. + ''; + }; }; # Any extra NixOS modules to load on all our servers. Note that just diff --git a/morph/lib/customize-issuer.nix b/morph/lib/customize-issuer.nix index 0686556cdf6abe79f0ac9e16586c9c219f3cddb1..5a34db1ac4aa1950275404fd45154e255bcc0c42 100644 --- a/morph/lib/customize-issuer.nix +++ b/morph/lib/customize-issuer.nix @@ -1,16 +1,9 @@ # Define a function which returns a value which fills in all the holes left by # ``issuer.nix``. { - # A string giving the IP address and port number (":"-separated) of the VPN - # server. - monitoringvpnEndpoint - - # A string giving the VPN IPv4 address for this system. -, monitoringvpnIPv4 - # A string giving an email address to use for Let's Encrypt registration and # certificate issuance. -, letsEncryptAdminEmail + letsEncryptAdminEmail # A list of strings giving the domain names that point at this issuer # system. These will all be included in Let's Encrypt certificate. @@ -22,28 +15,7 @@ , ... }: { config, ... }: -let - inherit (config.grid) publicKeyPath privateKeyPath; -in { - deployment.secrets = { - # ``.../monitoringvpn`` is a path on the deployment system of a directory - # containing a number of VPN-related secrets. This is expected to contain - # a number of files named like ``<VPN IPv4 address>.key`` containing the - # VPN private key for the corresponding host. It must also contain - # ``server.pub`` and ``preshared.key`` holding the VPN server's public key - # and the pre-shared key, respectively. All of these things are used as - # the sources of various VPN-related morph secrets. - "monitoringvpn-secret-key".source = "${privateKeyPath}/monitoringvpn/${monitoringvpnIPv4}.key"; - "monitoringvpn-preshared-key".source = "${privateKeyPath}/monitoringvpn/preshared.key"; - }; - - services.private-storage.monitoring.vpn.client = { - enable = true; - ip = monitoringvpnIPv4; - endpoint = monitoringvpnEndpoint; - endpointPublicKeyFile = "${publicKeyPath}/monitoringvpn/server.pub"; - }; - +{ services.private-storage-issuer = { inherit letsEncryptAdminEmail allowedChargeOrigins; domains = issuerDomains; diff --git a/morph/lib/customize-monitoring.nix b/morph/lib/customize-monitoring.nix index 2899d9940d4309b81a31f96590f0d3df1d632dc4..a8f96f2d7e11473c707b44dba1b923ad92e11799 100644 --- a/morph/lib/customize-monitoring.nix +++ b/morph/lib/customize-monitoring.nix @@ -9,7 +9,6 @@ hostsMap # See ``customize-issuer.nix``. -, monitoringvpnIPv4 , letsEncryptAdminEmail , monitoringDomains @@ -47,7 +46,7 @@ }: { config, ... }: let - inherit (config.grid) publicKeyPath privateKeyPath; + inherit (config.grid) publicKeyPath privateKeyPath monitoringvpnIPv4; in { deployment.secrets = let # When Grafana SSO is disabled there is not necessarily any client secret @@ -93,12 +92,8 @@ in { action = ["sudo" "systemctl" "restart" "grafana.service"]; }; }; - monitoringvpn = { - "monitoringvpn-private-key".source = "${privateKeyPath}/monitoringvpn/server.key"; - "monitoringvpn-preshared-key".source = "${privateKeyPath}/monitoringvpn/preshared.key"; - }; in - grafanaSSO // grafanaSlackUrl // monitoringvpn; + grafanaSSO // grafanaSlackUrl; networking.hosts = hostsMap; diff --git a/morph/lib/customize-storage.nix b/morph/lib/customize-storage.nix index 6a288213c3f117309b697e44304be9a7d5620bcb..e6b93fefdc735dfb08e3ce091ee1d125d7031b04 100644 --- a/morph/lib/customize-storage.nix +++ b/morph/lib/customize-storage.nix @@ -1,12 +1,8 @@ # Define a function which returns a value which fills in all the holes left by # ``storage.nix``. { - # See ``customize-issuer.nix`` - monitoringvpnEndpoint -, monitoringvpnIPv4 - # An integer giving the value of a single pass in byte×months. -, passValue + passValue # An integer giving the port number to include in Tahoe storage service # advertisements and on which to listen for storage connections. @@ -20,21 +16,9 @@ let inherit (config.grid) publicKeyPath privateKeyPath; in { - deployment.secrets = { - "monitoringvpn-secret-key".source = "${privateKeyPath}/monitoringvpn/${monitoringvpnIPv4}.key"; - "monitoringvpn-preshared-key".source = "${privateKeyPath}/monitoringvpn/preshared.key"; - }; - services.private-storage = { inherit passValue publicStoragePort; }; - services.private-storage.monitoring.vpn.client = { - enable = true; - ip = monitoringvpnIPv4; - endpoint = monitoringvpnEndpoint; - endpointPublicKeyFile = "${publicKeyPath}/monitoringvpn/server.pub"; - }; - system.stateVersion = stateVersion; } diff --git a/morph/lib/issuer.nix b/morph/lib/issuer.nix index d3ee812e865f741b01eb811589262ae01ece824f..5390f9e12ba978d20869cc735f9c5b0a217afdd0 100644 --- a/morph/lib/issuer.nix +++ b/morph/lib/issuer.nix @@ -6,7 +6,7 @@ # See https://whetstone.privatestorage.io/privatestorage/PrivateStorageio/-/issues/80 { config, ...}: let - inherit (config.grid) publicKeyPath privateKeyPath; + inherit (config.grid) publicKeyPath privateKeyPath monitoringvpnEndpoint monitoringvpnIPv4; in { deployment = { secrets = { @@ -29,6 +29,7 @@ in { "monitoringvpn-secret-key" = { destination = "/run/keys/monitoringvpn/client.key"; + source = "${privateKeyPath}/monitoringvpn/${monitoringvpnIPv4}.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; @@ -36,6 +37,7 @@ in { }; "monitoringvpn-preshared-key" = { destination = "/run/keys/monitoringvpn/preshared.key"; + source = "${privateKeyPath}/monitoringvpn/preshared.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; @@ -57,4 +59,12 @@ in { database = "SQLite3"; databasePath = "${config.fileSystems."zkapissuer-data".mountPoint}/vouchers.sqlite3"; }; + + services.private-storage.monitoring.vpn.client = { + enable = true; + ip = monitoringvpnIPv4; + endpoint = monitoringvpnEndpoint; + endpointPublicKeyFile = "${publicKeyPath}/monitoringvpn/server.pub"; + }; + } diff --git a/morph/lib/monitoring.nix b/morph/lib/monitoring.nix index 89a328e89a799b445dff7180dff552350b9629cf..e10dd31c4dee7404d436285ad80c9babc350c246 100644 --- a/morph/lib/monitoring.nix +++ b/morph/lib/monitoring.nix @@ -1,10 +1,14 @@ # Similar to ``issuer.nix`` but for a "monitoring"-type system. Holes are # filled by ``customize-monitoring.nix``. -{ +{ config, ...}: +let + inherit (config.grid) privateKeyPath; +in { deployment = { secrets = { "monitoringvpn-private-key" = { destination = "/run/keys/monitoringvpn/server.key"; + source = "${privateKeyPath}/monitoringvpn/server.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; @@ -12,6 +16,7 @@ }; "monitoringvpn-preshared-key" = { destination = "/run/keys/monitoringvpn/preshared.key"; + source = "${privateKeyPath}/monitoringvpn/preshared.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; diff --git a/morph/lib/storage.nix b/morph/lib/storage.nix index 15e2373737a7ff2f1efe8cf2c41b59de606f0a1a..74ed448ac5e7d821cca0c09910a61343d2ec94af 100644 --- a/morph/lib/storage.nix +++ b/morph/lib/storage.nix @@ -2,7 +2,7 @@ # by ``customize-storage.nix``. { config, ...} : let - inherit (config.grid) publicKeyPath privateKeyPath; + inherit (config.grid) publicKeyPath privateKeyPath monitoringvpnIPv4 monitoringvpnEndpoint; in { deployment = { secrets = { @@ -19,6 +19,7 @@ in { }; "monitoringvpn-secret-key" = { destination = "/run/keys/monitoringvpn/client.key"; + source = "${privateKeyPath}/monitoringvpn/${monitoringvpnIPv4}.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; @@ -26,6 +27,7 @@ in { }; "monitoringvpn-preshared-key" = { destination = "/run/keys/monitoringvpn/preshared.key"; + source = "${privateKeyPath}/monitoringvpn/preshared.key"; owner.user = "root"; owner.group = "root"; permissions = "0400"; @@ -56,4 +58,11 @@ in { # Give it the Ristretto signing key to support authorization. ristrettoSigningKeyPath = config.deployment.secrets.ristretto-signing-key.destination; }; + + services.private-storage.monitoring.vpn.client = { + enable = true; + ip = monitoringvpnIPv4; + endpoint = monitoringvpnEndpoint; + endpointPublicKeyFile = "${publicKeyPath}/monitoringvpn/server.pub"; + }; }