From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 49C6B1FF161 for ; Tue, 22 Oct 2024 10:29:06 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8C4C23FFB1; Tue, 22 Oct 2024 10:29:43 +0200 (CEST) Date: Tue, 22 Oct 2024 10:29:05 +0200 From: Fabian =?iso-8859-1?q?Gr=FCnbichler?= To: Proxmox VE development discussion References: <20240924143502.361901-1-m.sandoval@proxmox.com> <20240924143502.361901-2-m.sandoval@proxmox.com> In-Reply-To: <20240924143502.361901-2-m.sandoval@proxmox.com> MIME-Version: 1.0 User-Agent: astroid/0.16.0 (https://github.com/astroidmail/astroid) Message-Id: <1729584916.zq75nvzkam.astroid@yuna.none> X-SPAM-LEVEL: Spam detection results: 0 AWL 0.048 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [systemd.io, qemuserver.pm, freedesktop.org, proxmox.com] Subject: Re: [pve-devel] [RFC PATCH 2/2] config: add systemd credentials support X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Cc: Wolfgang Bumiller Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" On September 24, 2024 4:35 pm, Maximiliano Sandoval wrote: > Allows to pass systemd credentials to a VM. See [1] for a description of > systemd credentials. This can be potentially used to provision a VM as > per [2]. Values can be passed either as plain text (which might be > base64 encrypted) or by reading the contents of a snippet. > > A VM configuration file which, for example, contains: > > systemd.foo: value=bar > systemd.ssh.authorized_keys.root: snippet=local:snippets/id_ed25519.pub > systemd.encoded-foo: value=YmFya=,base64=1 why not our usual scheme? systemd0: key=foo,value=bar systemd1: key=ssh.authorized_keys.root,snippet=local:snippets/id_ed25519.pub systemd2: key=encoded-foo,value=YmFya=,base64=1 if need be, the key could be persisted base64-encoded (e.g., if it can contain characters used as delimiters or otherwise special) > will have the following arguments added to its kvm command: > > -smbios 'type=11,value=io.systemd.credential.binary:ssh.authorized_keys.root=c3NoLWVkMjU1MTkgQUFBQUMzTnphQzFsWkRJMU5URTVBQUFBSUZWZkFTYnVHdGdoWXBQQTBUS0w4N3I2dWRYNm5CbEM2L2hLWVZaTTdENzYgZm9vQGJhcgo=' \ > -smbios 'type=11,value=io.systemd.credential:foo=bar' \ > -smbios 'type=11,value=io.systemd.credential.binary:encoded-foo=YmFy' > > On the guest these credentials can be read via: > > dmidecode -t 11 > > In the example above, the SSH key will be added to > /root/.ssh/authorized_keys provided the file did not exist, see [3]. > > [1] https://systemd.io/CREDENTIALS/ > [2] https://www.freedesktop.org/software/systemd/man/latest/systemd.system-credentials.html > [3] https://www.freedesktop.org/software/systemd/man/latest/systemd.system-credentials.html#ssh.authorized_keys.root > > Suggested-by: Wolfgang Bumiller > Signed-off-by: Maximiliano Sandoval > --- > PVE/QemuServer.pm | 77 +++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 77 insertions(+) > > diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm > index 1566cf91..3ec21064 100644 > --- a/PVE/QemuServer.pm > +++ b/PVE/QemuServer.pm > @@ -149,6 +149,26 @@ my $watchdog_fmt = { > }; > PVE::JSONSchema::register_format('pve-qm-watchdog', $watchdog_fmt); > > +our $systemd_value_fmt = { > + value => { > + description => 'The credential value. base64=1 should be specified if the value is base64 encoded.', > + type => 'string', nack - this needs some sort of restriction (e.g. a sane character set for non-base64 encoded values, or base64) > + optional => 1, > + }, > + snippet => { > + type => 'string', > + description => "Specify a snippet containing the credential's value", > + format => 'pve-volume-id', not too sure about adding yet more usage to the already overloaded and problematic snippet feature that we want to get rid of/overhaul.. > + optional => 1, > + }, > + base64 => { > + description => 'Whether the value is base64 encoded.', > + type => 'boolean', > + optional => 1, > + default => 0, > + }, > +}; > + > my $agent_fmt = { > enabled => { > description => "Enable/disable communication with a QEMU Guest Agent (QGA) running in the VM.", > @@ -2039,6 +2059,16 @@ sub parse_guest_agent { > return $res; > } > > +sub parse_systemd_credential { > + my ($value) = @_; > + > + return {} if !$value; > + > + my $res = eval { parse_property_string($systemd_value_fmt, $value) }; > + warn $@ if $@; why? if you do this, it needs to be optin via a $noerr parameter.. > + return $res; > +} > + > sub get_qga_key { > my ($conf, $key) = @_; > return undef if !defined($conf->{agent}); > @@ -2390,6 +2420,12 @@ sub parse_vm_config { you only touch parse_vm_config.. how does this work on read-modify-write cycles?? > $conf->{$key} = $value; > next; > } > + if ($key =~ /^systemd\.([a-z][a-z_\.-]*)$/) { > + # ignore validation of systemd credentials > + $conf->{'systemd-credentials'}->{$1} = $value; > + next; > + } > + this part here would not be needed if it were a regular config option instead of getting special treatment.. > eval { $value = check_type($key, $value); }; but this part here would still trigger schema validation then, which would be a plus! > if ($@) { > $handle_error->("vm $vmid - unable to parse value of '$key' - $@"); > @@ -3514,6 +3550,27 @@ my sub get_vga_properties { > return ($vga, $qxlnum); > } > > +sub smbios_11_cred_arg { > + my ($key, $value, $is_encoded) = @_; > + > + if ($is_encoded) { > + return ('-smbios', "type=11,value=io.systemd.credential.binary:$key=$value"); > + } else { > + return ('-smbios', "type=11,value=io.systemd.credential:$key=$value"); > + } > +} > + > +sub read_systemd_custom_file { > + my ($storage_conf, $path) = @_; > + > + my ($vtype, undef) = PVE::Storage::parse_volname($storage_conf, $path); > + > + die "$path is not in the snippets directory\n" if $vtype ne 'snippets'; > + > + my $full_path = PVE::Storage::abs_filesystem_path($storage_conf, $path, 1); > + return PVE::Tools::file_get_contents($full_path, 1 * 1024 * 1024); > +} this is a 1:1 copy of PVE::QemuServer::Cloudinit::read_cloudinit_snippets_file .. > + > sub config_to_command { > my ($storecfg, $vmid, $conf, $defaults, $forcemachine, $forcecpu, > $live_restore_backing) = @_; > @@ -4142,6 +4199,26 @@ sub config_to_command { > push @$cmd, '-snapshot'; > } > > + # set systemd-credentials > + my $storage_conf; > + my $systemd_credentials = $conf->{'systemd-credentials'} || {}; > + foreach my $key (keys %$systemd_credentials) { > + my $opts = parse_systemd_credential($systemd_credentials->{$key}); > + my $is_encoded = $opts->{'base64'} ? 1 : 0; > + my $value; > + > + if (my $v = $opts->{'value'}) { > + $value = $v; > + } elsif (my $snippet = $opts->{'snippet'}) { > + $storage_conf = PVE::Storage::config() if !defined($storage_conf); why? config_to_command already has a copy of the storage config.. > + my $contents = read_systemd_custom_file($storage_conf, $snippet); > + $value = encode_base64($contents, ''); > + $is_encoded = 1; > + } > + > + push @$cmd, smbios_11_cred_arg($key, $value, $is_encoded) if $value; > + } > + > # add custom args > if ($conf->{args}) { > my $aa = PVE::Tools::split_args($conf->{args}); > -- > 2.39.5 > > > > _______________________________________________ > pve-devel mailing list > pve-devel@lists.proxmox.com > https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > > _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel