summaryrefslogtreecommitdiff
path: root/cloudinit/ssh_util.py
diff options
context:
space:
mode:
authorsxt1001 <shixuantong1@huawei.com>2023-04-03 01:30:36 +0800
committerGitHub <noreply@github.com>2023-04-02 12:30:36 -0500
commit09a64badfb3f51b1b391fa29be19962381a4bbeb (patch)
treea9ac46f499fbee1de056e08624239d0238306434 /cloudinit/ssh_util.py
parent612b4de892d19333c33276d541fed99fd16d3998 (diff)
downloadcloud-init-git-09a64badfb3f51b1b391fa29be19962381a4bbeb.tar.gz
Fix private key permissions when openssh not earlier than 9.0 #2072
Cloud-init's host key generation mimics that of sshd-keygen. It used to generate 640 permissions, but going forward it should be 600. Check sshd version to set the permissions appropriately. LP: #2011291
Diffstat (limited to 'cloudinit/ssh_util.py')
-rw-r--r--cloudinit/ssh_util.py48
1 files changed, 47 insertions, 1 deletions
diff --git a/cloudinit/ssh_util.py b/cloudinit/ssh_util.py
index eb5c9f64..eee399f2 100644
--- a/cloudinit/ssh_util.py
+++ b/cloudinit/ssh_util.py
@@ -8,10 +8,11 @@
import os
import pwd
+from contextlib import suppress
from typing import List, Sequence, Tuple
from cloudinit import log as logging
-from cloudinit import util
+from cloudinit import subp, util
LOG = logging.getLogger(__name__)
@@ -642,4 +643,49 @@ def append_ssh_config(lines: Sequence[Tuple[str, str]], fname=DEF_SSHD_CFG):
)
+def get_opensshd_version():
+ """Get the full version of the OpenSSH sshd daemon on the system.
+
+ On an ubuntu system, this would look something like:
+ 1.2p1 Ubuntu-1ubuntu0.1
+
+ If we can't find `sshd` or parse the version number, return None.
+ """
+ # -V isn't actually a valid argument, but it will cause sshd to print
+ # out its version number to stderr.
+ err = ""
+ with suppress(subp.ProcessExecutionError):
+ _, err = subp.subp(["sshd", "-V"], rcs=[0, 1])
+ prefix = "OpenSSH_"
+ for line in err.split("\n"):
+ if line.startswith(prefix):
+ return line[len(prefix) : line.find(",")]
+ return None
+
+
+def get_opensshd_upstream_version():
+ """Get the upstream version of the OpenSSH sshd dameon on the system.
+
+ This will NOT include the portable number, so if the Ubuntu version looks
+ like `1.2p1 Ubuntu-1ubuntu0.1`, then this function would return
+ `1.2`
+ """
+ # The default version of openssh is not less than 9.0
+ upstream_version = "9.0"
+ full_version = get_opensshd_version()
+ if full_version is None:
+ return util.Version.from_str(upstream_version)
+ if "p" in full_version:
+ upstream_version = full_version[: full_version.find("p")]
+ elif " " in full_version:
+ upstream_version = full_version[: full_version.find(" ")]
+ else:
+ upstream_version = full_version
+ try:
+ upstream_version = util.Version.from_str(upstream_version)
+ return upstream_version
+ except (ValueError, TypeError):
+ LOG.warning("Could not parse sshd version: %s", upstream_version)
+
+
# vi: ts=4 expandtab