Fix IPsec host key generation with modern Libreswan
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled
Close inactive / close-inactive (push) Has been cancelled

https://github.com/webmin/webmin/issues/2132
This commit is contained in:
Ilia Ross
2026-08-29 01:36:24 +02:00
parent bcc120a93b
commit 19206d485a
3 changed files with 40 additions and 10 deletions

View File

@@ -7,6 +7,7 @@
* Add DNF 4 and 5 package hold management to the Software Package Updates module
* Fix DNF update confirmations by previewing packages and dependencies that will be installed or updated
* Fix PostgreSQL initialization on EL systems to use SCRAM-SHA-256 authentication by default
* Fix IPsec host key generation with modern Libreswan [#2132](https://github.com/webmin/webmin/issues/2132)
#### 2.660 (August 20, 2026)
* Add support for creating `vfsv1` Linux quota files for limits above 4 TiB, while preserving existing quota file formats

View File

@@ -139,13 +139,33 @@ return $? || $out =~ /not running/i ? 0 : 1;
# Returns this system's public key
sub get_public_key
{
local $out = `$config{'ipsec'} showhostkey --file '$config{'secrets'}' --left 2>&1`;
local $ckaid = &get_libreswan_key_id();
local $out;
if ($ckaid) {
# Modern Libreswan reads the selected host key from NSS
$out = `$config{'ipsec'} showhostkey --left --ckaid '$ckaid' 2>&1`;
}
else {
# Legacy implementations read the host key from ipsec.secrets
$out = `$config{'ipsec'} showhostkey --file '$config{'secrets'}' --left 2>&1`;
}
if ($out =~ /leftrsasigkey=(\S+)/) {
return $1;
}
return undef;
}
# get_libreswan_key_id()
# Returns the CKAID of the first Libreswan host key, or undef
sub get_libreswan_key_id
{
local $out;
local ($version, $program) = &get_ipsec_version(\$out);
return undef if (!$program || lc($program) ne "libreswan");
local $keys = `$config{'ipsec'} showhostkey --list 2>&1`;
return $keys =~ /\bckaid:\s*([a-f0-9]+)/i ? $1 : undef;
}
# get_public_key_dns()
# Returns the flags, protocol, algorithm and key data for the public key,
# suitable for creating a DNS KEY record
@@ -292,16 +312,17 @@ return $out =~ /(FreeS\/WAN|Openswan|StrongSWAN|Libreswan)\s+([^ \n\(]+)/i ? ($2
sub got_secret
{
local $gotkey;
open(SEC, "<".$config{'secrets'}) || return 0;
while(<SEC>) {
s/\r|\n//g;
s/#.*$//;
if (/Modulus:\s*(\S+)/) {
$gotkey = 1;
if (open(SEC, "<".$config{'secrets'})) {
while(<SEC>) {
s/\r|\n//g;
s/#.*$//;
if (/Modulus:\s*(\S+)/) {
$gotkey = 1;
}
}
close(SEC);
}
close(SEC);
return $gotkey;
return ($gotkey || &get_libreswan_key_id()) ? 1 : 0;
}
# expand_conf(&config)

View File

@@ -6,7 +6,15 @@ require './ipsec-lib.pl';
&ReadParse();
&error_setup($text{'newkey_err'});
$in{'host'} =~ /^[a-z0-9\.\-]+$/i || &error($text{'newkey_ehost'});
$out = &backquote_logged("$config{'ipsec'} newhostkey --output '$config{'secrets'}' --hostname '$in{'host'}' 2>&1");
($ipsec_version, $ipsec_program) = &get_ipsec_version(\$out);
if ($ipsec_program && lc($ipsec_program) eq "libreswan") {
# Modern Libreswan stores host keys in its NSS database
$out = &backquote_logged("$config{'ipsec'} newhostkey 2>&1");
}
else {
# Legacy implementations write the key to ipsec.secrets
$out = &backquote_logged("$config{'ipsec'} newhostkey --output '$config{'secrets'}' --hostname '$in{'host'}' 2>&1");
}
$? && &error("<pre>$out</pre>");
&webmin_log("newkey");
&redirect("");