Add support to configure SSH socket #2356

This commit is contained in:
Ilia Ross
2025-01-17 04:35:57 +02:00
parent 761a879919
commit 78d5332499
2 changed files with 137 additions and 4 deletions

View File

@ -54,6 +54,7 @@ else {
}
}
# Save ports
if ($in{'port_def'}) {
&save_directive("Port", $conf);
}
@ -66,6 +67,9 @@ else {
&save_directive("Port", $conf, \@ports, "ListenAddress");
}
# Sync socket options
&save_socket(\@ports, \@listens);
if ($version{'type'} eq 'openssh' &&
$version{'number'} >= 2 && $version{'number'} < 7.6) {
@prots = split(/\0/, $in{'prots'});

View File

@ -148,6 +148,108 @@ for($i=0; $i<@o || $i<@n; $i++) {
}
}
# save_socket(ports, listens)
sub save_socket
{
my ($ports, $listens) = @_;
return if ($version{'number'} < 6.7);
return if (!&foreign_available('init'));
&foreign_require('init');
my $default_port = 22;
my @socket_units = ('ssh.socket', 'sshd.socket');
my $socket_unit;
foreach (@socket_units) {
if (&init::action_status($_) == 2) {
$socket_unit = $_;
last;
}
}
return if (!$socket_unit);
# Extend listens with IPs from default socket configuration if set
my $socket_details = &init::cat_systemd($socket_unit, 'ListenStream');
my ($socket_conf_file, $socket_conf_dir);
my @default_streams;
foreach my $entry (@$socket_details) {
next if ($entry->{'file'} =~ m{^/run}); # Skip runtime files
my $streams = $entry->{'sections'}{'Socket'}{'ListenStream'};
if ($entry->{'file'} =~ m{^/etc}) {
if (defined($streams)) {
# Determine the socket configuration file and
# directory from the custom config that defines
# ListenStream to support multiple socket
# override files (edge case)
($socket_conf_dir, $socket_conf_file) =
$entry->{'file'} =~ m|^(.*/)([^/]+)$|;
$socket_conf_dir =~ s|/$|| if ($socket_conf_dir);
}
next;
}
if ($streams) {
foreach my $stream (@$streams) {
if ($stream =~ /^(?:\[(.+?)\]|([^:]+)):\d+$/) {
my $address = defined($1) ? "[$1]" : $2;
push(@default_streams, $address)
}
}
}
}
my @result;
# Set default port if empty
$ports = [$default_port] if (!@$ports);
# Check if port is different from default
my $port = @$ports == 1 && $ports->[0] == $default_port;
if (@$listens) {
# Process listens
foreach my $listen (@$listens) {
if ($listen =~ /:\d+$/) {
# If listen already contains a port, keep it as is
push(@result, $listen);
}
elsif ($listen =~ /^\[.*\]$/) {
# IPv6 address without a port
push(@result, map { "$listen:$_" } @$ports);
}
else {
# IPv4 address or hostname without a port
push(@result, map { "$listen:$_" } @$ports);
}
}
}
# Add ports not already in @result
if (!$port || @result) {
foreach my $port (@$ports) {
unless (grep { /:$port$/ } @result) {
if (@default_streams) {
push(@result, map { "$_:$port" }
@default_streams);
}
else {
push(@result, $port);
}
}
}
}
# Update socket if @results not empty
my $socket_conf = { 'Socket' => {} };
if (@result) {
unshift(@result, '');
$socket_conf = {
'Socket' => {
'ListenStream' => \@result,
},
};
}
&init::edit_systemd($socket_unit, $socket_conf,
$socket_conf_file, $socket_conf_dir);
}
# scmd(double)
sub scmd
{
@ -241,12 +343,34 @@ local $lref = &read_file_lines($config{'client_config'});
splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1);
}
# get_ssh_socket()
sub get_ssh_socket
{
return undef if ($version{'number'} < 6.7);
return undef if (!&foreign_available('init'));
&foreign_require('init');
return undef if ($init::init_mode ne 'systemd');
my @socket_units = ('ssh.socket', 'sshd.socket');
my $socket_unit;
foreach (@socket_units) {
if (&init::action_status($_) == 2) {
$socket_unit = $_;
last;
}
}
return $socket_unit if ($socket_unit);
return undef;
}
# restart_sshd()
# Re-starts the SSH server, and returns an error message on failure or
# undef on success
sub restart_sshd
{
if ($config{'restart_cmd'}) {
if (my $ssh_socket = &get_ssh_socket()) {
&init::restart_action($ssh_socket);
}
elsif ($config{'restart_cmd'}) {
local $out = `$config{'restart_cmd'} 2>&1 </dev/null`;
return "<pre>$out</pre>" if ($?);
}
@ -263,7 +387,10 @@ return undef;
# undef on success
sub stop_sshd
{
if ($config{'stop_cmd'}) {
if (my $ssh_socket = &get_ssh_socket()) {
&init::stop_action($ssh_socket);
}
elsif ($config{'stop_cmd'}) {
local $out = `$config{'stop_cmd'} 2>&1 </dev/null`;
return "<pre>$out</pre>" if ($?);
}
@ -284,8 +411,10 @@ sub start_sshd
if (-f $config{'pid_file'} && !&check_pid_file($config{'pid_file'})) {
&unlink_file($config{'pid_file'});
}
if ($config{'start_cmd'}) {
if (my $ssh_socket = &get_ssh_socket()) {
&init::start_action($ssh_socket);
}
elsif ($config{'start_cmd'}) {
$out = &backquote_logged("$config{'start_cmd'} 2>&1 </dev/null");
if ($?) { return "<pre>$out</pre>"; }
}