Commit c1e7fcdd authored by Francesc Guasch's avatar Francesc Guasch Committed by Francesc Guasch
Browse files

Feat: config minimum port expose (#1550)

feat(ports): set minimum port to expose

also do not assign public port for bases

issue #1531
parent 1e369623
......@@ -1984,6 +1984,11 @@ sub _sql_insert_defaults($self){
,name => "debug_ports"
,value => 0
}
,{
id_parent => $id_backend
,name => 'expose_port_min'
,value => '60000'
}
]
);
my %field = ( settings => 'name' );
......
......@@ -26,6 +26,7 @@ use feature qw(signatures);
use Ravada::Booking;
use Ravada::Domain::Driver;
use Ravada::Auth::SQL;
use Ravada::Utils;
our $TIMEOUT_SHUTDOWN = 120;
......@@ -3214,7 +3215,10 @@ sub _add_expose($self, $internal_port, $name, $restricted) {
my $public_port;
for ( 1 .. 100 ) {
eval {
$public_port = $self->_vm->_new_free_port();
$public_port = $self->_vm->_new_free_port() if !$self->is_base;
};
die $@ if $@ && $@ !~ /no free ports/i;
eval {
$sth->execute($self->id
, $public_port, $internal_port
, ($name or undef)
......@@ -3240,7 +3244,12 @@ sub _add_expose($self, $internal_port, $name, $restricted) {
}
sub _set_public_port($self, $id_port, $internal_port, $name, $restricted) {
my $public_port = $self->_vm->_new_free_port();
my $public_port;
eval {
$public_port = undef;
$public_port = $self->_vm->_new_free_port();
};
my $error = $@;
for (;;) {
if ($id_port) {
my $sth = $$CONNECTOR->dbh->prepare("UPDATE domain_ports set public_port=?"
......@@ -3270,6 +3279,12 @@ sub _set_public_port($self, $id_port, $internal_port, $name, $restricted) {
}
$public_port += int(rand(10))+1;
}
if ($error) {
my $user = Ravada::Auth::SQL->search_by_id($self->_data('id_owner'));
$user->send_message($error);
warn $error;
die $error;
}
}
sub _used_ports_iptables($self, $port, $skip_port) {
......@@ -3327,7 +3342,7 @@ sub _open_exposed_port($self, $internal_port, $name, $restricted) {
$sth->execute($internal_ip, $self->id, $internal_port);
$self->_update_display_port_exposed($name, $local_ip, $public_port, $internal_port);
if ( !$> ) {
if ( !$> && $public_port ) {
my ($out, $err) = $self->_vm->run_command("iptables-save","-t","nat");
my @open1 = (grep /--dport $public_port/, split/\n/,$out );
my @open2 = (grep /--to-destination $internal_ip:$internal_port/, split/\n/,$out );
......@@ -3615,9 +3630,19 @@ sub list_ports($self) {
my @ports_base = $base->list_ports();
for my $data (@ports_base) {
next if exists $clone_port{$data->{internal_port}};
unlock_hash(%$data);
$data->{public_port} = $self->_vm->_new_free_port() if $self->_vm;
lock_hash(%$data);
if ($self->_vm) {
unlock_hash(%$data);
eval {
$data->{public_port} = '';
$data->{public_port} = $self->_vm->_new_free_port();
};
my $error = $@;
if ($error) {
my $user = Ravada::Auth::SQL->search_by_id($self->_data('id_owner'));
$user->send_message(substr($error,0,80));
}
lock_hash(%$data);
}
push @list,($data);
}
}
......
......@@ -2044,10 +2044,13 @@ sub _new_free_port($self, $used_port={}) {
$self->_list_used_ports_ss($used_port);
$self->_list_used_ports_iptables($used_port);
my $free_port = $FREE_PORT;
my $min_free_port = Ravada::setting(undef,'/backend/expose_port_min');
my $free_port = $min_free_port;
for (;;) {
last if !$used_port->{$free_port};
$free_port++ ;
die "Error: no free ports available from $min_free_port.\n"
if $free_port > 65535;
}
return $free_port;
}
......
......@@ -140,6 +140,18 @@
</div>
</div>
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-2">
<label for="debug">Port expose</label>
</div>
<div class="col-md-8">
<input name="debug" ng-model="settings.backend.expose_port_min.value"
type="number" min="1" max="65530">
<%= l 'Minimum port number to expose virtual machine services.' %>
<a href="https://ravada.readthedocs.io/en/latest/docs/expose_ports.html"><i class="fa fa-info"></i></a>
</div>
</div>
<div class="row">
<div class="col-md-1"></div>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment