git: 8ec108914247 - main - nuageinit: adopt cloud-init disable_root semantics

Baptiste Daroussin <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a7b04c3.41094.185ad680__34476.2779002608$1786447094$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by bapt:

URL: https://cgit.FreeBSD.org/src/commit/?id=8ec108914247502dff049059dc60df17920731c8

commit 8ec108914247502dff049059dc60df17920731c8
Author:     Baptiste Daroussin <[email protected]>
AuthorDate: 2026-08-11 08:56:52 +0000
Commit:     Baptiste Daroussin <[email protected]>
CommitDate: 2026-08-11 11:15:55 +0000

    nuageinit: adopt cloud-init disable_root semantics
    
    disable_root now restricts root's authorized_keys instead of setting
    PermitRootLogin.
    
    Reported by:    np@
---
 libexec/nuageinit/nuage.lua          |  8 ++++++--
 libexec/nuageinit/nuageinit          | 40 ++++++++++++++++++++++++++----------
 libexec/nuageinit/nuageinit.7        | 35 +++++++++++++++++++------------
 libexec/nuageinit/tests/nuageinit.sh | 31 ++++++++++++++--------------
 4 files changed, 73 insertions(+), 41 deletions(-)

diff --git a/libexec/nuageinit/nuage.lua b/libexec/nuageinit/nuage.lua
index cbd842460e55..3a9ac253fbcb 100644
--- a/libexec/nuageinit/nuage.lua
+++ b/libexec/nuageinit/nuage.lua
@@ -438,7 +438,7 @@ local function addgroup(grp)
 	return true
 end
 
-local function addsshkey(homedir, key)
+local function addsshkey(homedir, key, options)
 	local root = os.getenv("NUAGE_FAKE_ROOTDIR")
 	if root then
 		homedir = root .. "/" .. homedir
@@ -471,7 +471,11 @@ local function addsshkey(homedir, key)
 		warnmsg("impossible to open " .. ak_path)
 		return
 	end
-	f:write(key .. "\n")
+	if options and options ~= "" then
+		f:write(options .. " " .. key .. "\n")
+	else
+		f:write(key .. "\n")
+	end
 	f:close()
 
 	-- Set permissions and ownership on newly created files/dirs
diff --git a/libexec/nuageinit/nuageinit b/libexec/nuageinit/nuageinit
index ba26f504effb..d67ac6ce4229 100755
--- a/libexec/nuageinit/nuageinit
+++ b/libexec/nuageinit/nuageinit
@@ -570,18 +570,36 @@ local function ssh_deletekeys(obj)
 	end
 end
 
-local function disable_root(obj)
-	if obj.disable_root == nil then return end
-	if obj.disable_root then
-		local value = "no"
-		if obj.disable_root_opts then
-			if type(obj.disable_root_opts) == "string" then
-				value = obj.disable_root_opts
-			elseif type(obj.disable_root_opts) == "table" then
-				value = obj.disable_root_opts[1]
-			end
+local DISABLE_USER_OPTS = 'no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo \'Please login as the user \\"$USER\\" rather than the user \\"$DISABLE_USER\\".\';echo;sleep 10;exit 142"'
+
+local function disable_root(obj, metadata)
+	-- cloud-init semantics: restrict root's authorized_keys options
+	local disable = true
+	if obj.disable_root ~= nil then
+		disable = obj.disable_root
+	end
+	local opts = ""
+	if disable then
+		opts = obj.disable_root_opts or DISABLE_USER_OPTS
+		if type(opts) == "table" then
+			opts = opts[1]
+		end
+		opts = opts:gsub("%$USER", "freebsd")
+		opts = opts:gsub("%$DISABLE_USER", "root")
+	end
+	local keys = {}
+	if type(metadata.public_keys) == "table" then
+		for _, k in pairs(metadata.public_keys) do
+			table.insert(keys, k)
 		end
-		nuage.update_sshd_config("PermitRootLogin", value)
+	end
+	if obj and type(obj.ssh_authorized_keys) == "table" then
+		for _, k in ipairs(obj.ssh_authorized_keys) do
+			table.insert(keys, k)
+		end
+	end
+	for _, k in ipairs(keys) do
+		nuage.addsshkey("/root", k, opts)
 	end
 end
 
diff --git a/libexec/nuageinit/nuageinit.7 b/libexec/nuageinit/nuageinit.7
index a3d9da2415d9..c9c9096eee72 100644
--- a/libexec/nuageinit/nuageinit.7
+++ b/libexec/nuageinit/nuageinit.7
@@ -331,25 +331,34 @@ configuration in
 .It Ic disable_root
 Boolean which determines if root login via SSH should be disabled.
 If set to
-.Ar true ,
-sets
-.Qq Ic PermitRootLogin
-to
-.Ar no
-.Pq or the value specified in Ic disable_root_opts
-in
-.Pa /etc/ssh/sshd_config .
+.Ar true
+.Pq the default ,
+the public SSH keys are written to
+.Pa /root/.ssh/authorized_keys
+with the options specified in
+.Ic disable_root_opts ,
+which by default redirects the login to the default user.
+If set to
+.Ar false ,
+the public SSH keys are written to
+.Pa /root/.ssh/authorized_keys
+without any restriction.
 .It Ic disable_root_opts
-String or array of options used to set the value of
-.Qq Ic PermitRootLogin
-in
-.Pa /etc/ssh/sshd_config ,
+String or array of options used to prefix the public SSH keys in
+.Pa /root/.ssh/authorized_keys
 when
 .Ic disable_root
 is set to
 .Ar true .
+The
+.Ar $USER
+and
+.Ar $DISABLE_USER
+placeholders are replaced with the default user name and
+.Ar root
+respectively.
 If not specified, defaults to
-.Ar no .
+.Ar no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command="echo 'Please login as the user "$USER" rather than the user "$DISABLE_USER".';echo;sleep 10;exit 142" .
 .Pp
 Only the first value is used when an array is provided.
 .It Ic network
diff --git a/libexec/nuageinit/tests/nuageinit.sh b/libexec/nuageinit/tests/nuageinit.sh
index ab9e697076e1..1fb5f7b4c967 100644
--- a/libexec/nuageinit/tests/nuageinit.sh
+++ b/libexec/nuageinit/tests/nuageinit.sh
@@ -267,6 +267,7 @@ ssh_authorized_keys:
   - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
 EOF
 	mkdir -p etc
+	mkdir -p root
 	cat > etc/master.passwd << EOF
 root:*:0:0::0:0:Charlie &:/root:/bin/sh
 sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
@@ -294,6 +295,7 @@ ssh_authorized_keys:
   - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
 EOF
 	mkdir -p etc
+	mkdir -p root
 	cat > etc/master.passwd << EOF
 root:*:0:0::0:0:Charlie &:/root:/bin/sh
 sys:*:1:0::0:0:Sys:/home/sys:/bin/sh
@@ -340,6 +342,7 @@ config2_pubkeys_meta_data_body()
 }
 EOF
 	mkdir -p etc
+	mkdir -p root
 	cat > etc/master.passwd << EOF
 root:*:0:0::0:0:Charlie &:/root:/bin/csh
 sys:*:1:0::0:0:Sys:/home/sys:/bin/csh
@@ -1004,37 +1007,35 @@ config2_userdata_disable_root_body()
 {
 	mkdir -p media/nuageinit
 	setup_test_adduser
+	mkdir -p root
 	printf "{}" > media/nuageinit/meta_data.json
 	cat > media/nuageinit/user_data <<EOF
 #cloud-config
 disable_root: true
-EOF
-	mkdir -p etc/ssh
-	touch etc/ssh/sshd_config
-	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
-	atf_check -o inline:"PermitRootLogin no\n" cat etc/ssh/sshd_config
-	cat > media/nuageinit/user_data <<EOF
-#cloud-config
-disable_root: true
-disable_root_opts: "without-password"
+ssh_authorized_keys:
+  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
 EOF
 	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
-	atf_check -o inline:"PermitRootLogin without-password\n" cat etc/ssh/sshd_config
+	atf_check -o match:'no-port-forwarding,no-agent-forwarding,no-X11-forwarding,command=.*exit 142" ssh-rsa AAAAB3NzaC1y...== Generated by Nova' cat root/.ssh/authorized_keys
+	rm -f root/.ssh/authorized_keys
 	cat > media/nuageinit/user_data <<EOF
 #cloud-config
 disable_root: true
-disable_root_opts:
-  - "prohibit-password"
+disable_root_opts: "no-port-forwarding"
+ssh_authorized_keys:
+  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
 EOF
 	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
-	atf_check -o inline:"PermitRootLogin prohibit-password\n" cat etc/ssh/sshd_config
+	atf_check -o inline:"no-port-forwarding ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat root/.ssh/authorized_keys
+	rm -f root/.ssh/authorized_keys
 	cat > media/nuageinit/user_data <<EOF
 #cloud-config
 disable_root: false
+ssh_authorized_keys:
+  - "ssh-rsa AAAAB3NzaC1y...== Generated by Nova"
 EOF
-	echo "PermitRootLogin yes" > etc/ssh/sshd_config
 	atf_check -o empty /usr/libexec/nuageinit "${PWD}"/media/nuageinit config-2
-	atf_check -o inline:"PermitRootLogin yes\n" cat etc/ssh/sshd_config
+	atf_check -o inline:"ssh-rsa AAAAB3NzaC1y...== Generated by Nova\n" cat root/.ssh/authorized_keys
 }
 
 config2_userdata_bootcmd_head()
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.