mirror of
https://github.com/webmin/webmin.git
synced 2025-07-20 16:48:46 +00:00
Add support to configure SSH socket #2356
This commit is contained in:
@ -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'});
|
||||
|
137
sshd/sshd-lib.pl
137
sshd/sshd-lib.pl
@ -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>"; }
|
||||
}
|
||||
|
Reference in New Issue
Block a user