Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Projets publics
Ravada-Mirror
Commits
b847e558
Unverified
Commit
b847e558
authored
Mar 02, 2021
by
Francesc Guasch
Committed by
GitHub
Mar 02, 2021
Browse files
fix(backend): ports exposing conflict fish (#1509)
issue #1505
parent
35590d2d
Changes
5
Hide whitespace changes
Inline
Side-by-side
lib/Ravada.pm
View file @
b847e558
...
...
@@ -2452,6 +2452,7 @@ sub process_requests {
$sth
->
execute
(
time
);
my
@reqs
;
my
%duplicated
;
while
(
my
(
$id_request
,
$id_domain
)
=
$sth
->
fetchrow
)
{
my
$req
;
eval
{
$req
=
Ravada::
Request
->
open
(
$id_request
)
};
...
...
@@ -2467,6 +2468,10 @@ sub process_requests {
next
if
$req
->
command
!~
/shutdown/i
&&
$self
->
_domain_working
(
$id_domain
,
$id_request
);
my
$domain
=
'';
$domain
=
$id_domain
if
$id_domain
;
$domain
.=
(
$req
->
defined_arg
('
name
')
or
'');
next
if
$duplicated
{
$req
->
command
.
"
:
$domain
"}
++
;
push
@reqs
,(
$req
);
}
...
...
@@ -3717,6 +3722,8 @@ sub _cmd_refresh_vms($self, $request=undef) {
$self
->
_clean_requests
('
refresh_vms
',
$request
);
$self
->
_refresh_volatile_domains
();
$self
->
_check_duplicated_prerouting
();
$request
->
error
('')
if
$request
;
}
...
...
@@ -3997,6 +4004,61 @@ sub _refresh_down_nodes($self, $request = undef ) {
}
}
sub
_check_duplicated_prerouting
($self, $request = undef ) {
my
$sth
=
$CONNECTOR
->
dbh
->
prepare
(
"
SELECT id FROM vms WHERE is_active=1
"
);
$sth
->
execute
();
while
(
my
(
$id
)
=
$sth
->
fetchrow
())
{
my
$vm
;
eval
{
$vm
=
Ravada::
VM
->
open
(
$id
)
};
warn
$@
if
$@
;
if
(
$vm
)
{
my
$iptables
=
$vm
->
iptables_list
();
my
%prerouting
;
for
my
$line
(
@
{
$iptables
->
{'
nat
'}})
{
my
%args
=
@$line
;
next
if
$args
{
A
}
ne
'
PREROUTING
'
||
!
$args
{
dport
};
my
$port
=
$args
{
dport
};
if
(
$prerouting
{
$port
})
{
$self
->
_reopen_ports
(
$port
);
$self
->
_delete_iptables_rule
(
$vm
,'
nat
',
\
%args
);
$self
->
_delete_iptables_rule
(
$vm
,'
nat
',
$prerouting
{
$port
});
}
$prerouting
{
$port
}
=
\
%args
;
}
}
}
}
sub
_reopen_ports
($self, $port) {
my
$sth
=
$CONNECTOR
->
dbh
->
prepare
("
SELECT id_domain FROM domain_ports
"
.
"
WHERE public_port=?
");
$sth
->
execute
(
$port
);
my
(
$id_domain
)
=
$sth
->
fetchrow
;
return
if
!
$id_domain
;
Ravada::
Request
->
open_exposed_ports
(
uid
=>
Ravada::Utils::
user_daemon
->
id
,
id_domain
=>
$id_domain
);
}
sub
_delete_iptables_rule
($self, $vm, $table, $rule) {
my
%delete
=
%$rule
;
my
$chain
=
delete
$delete
{
A
};
my
$to_destination
=
delete
$delete
{'
to-destination
'};
my
$dport
=
delete
$delete
{
dport
};
my
$m
=
delete
$delete
{
m};
my $p = delete $delete{p}
;
my
@delete
=
(
t
=>
$table
,
'
D
'
=>
$chain
,
m => $m, p =
>
$p
,
dport
=>
$dport
,
%delete
,
'
to-destination
'
=>
$to_destination
);
$vm
->
iptables
(
@delete
);
}
sub
_refresh_disabled_nodes
($self, $request = undef ) {
my
@timeout
=
();
@timeout
=
(
timeout
=>
$request
->
args
('
timeout_shutdown
')
)
...
...
lib/Ravada/Domain.pm
View file @
b847e558
...
...
@@ -361,7 +361,7 @@ sub _around_start($orig, $self, @arg) {
$self
->
_request_set_base
();
next
;
}
die
$
@
;
die
$
error
;
}
$self
->
_post_start
(
%arg
);
...
...
@@ -2994,10 +2994,9 @@ sub _close_exposed_port_nat($self, $iptables, %port) {
if
(
exists
$args
{
j
}
&&
$args
{
j
}
eq
'
DNAT
'
&&
exists
$args
{
d
}
&&
$args
{
d
}
eq
$ip
&&
exists
$args
{
dport
}
&&
exists
$port
{
$args
{
dport
}}
&&
exists
$args
{'
to-destination
'}
)
{
my
$internal_port
=
$port
{
$args
{
dport
}}
->
{
internal_port
}
or
next
;
if
(
$args
{'
to-destination
'}
=~
/\:$internal_port$/
)
{
my
%delete
=
%args
;
delete
$delete
{
A
};
delete
$delete
{
dport
};
...
...
@@ -3016,7 +3015,6 @@ sub _close_exposed_port_nat($self, $iptables, %port) {
'
to-destination
',
$to_destination
);
$self
->
_vm
->
iptables
(
@delete
);
}
}
}
}
...
...
t/30_request.t
View file @
b847e558
...
...
@@ -248,6 +248,7 @@ sub test_requests_by_domain {
is
(
$domain
->
list_requests
,
3
,
Dumper
([
map
{
$_
->
{
command
}
}
$domain
->
list_requests
]));
rvd_back
->
_process_all_requests_dont_fork
();
wait_request
();
is
(
$req1
->
status
,
'
done
');
is
(
$req2
->
status
,
'
done
');
...
...
t/request/70_network.t
View file @
b847e558
...
...
@@ -28,6 +28,7 @@ sub test_list_nats($vm) {
,
vm_type
=>
$vm
->
type
);
rvd_back
->
_process_requests_dont_fork
();
wait_request
();
is
(
$req
->
status
,'
done
');
is
(
$req
->
error
,'');
like
(
$req
->
output
,
qr{\"$exp_nat[0]\"}
);
...
...
@@ -65,6 +66,7 @@ sub test_list_bridges($vm) {
,
vm_type
=>
$vm
->
type
);
rvd_back
->
_process_requests_dont_fork
();
wait_request
();
is
(
$req
->
status
,'
done
');
is
(
$req
->
error
,'');
...
...
t/vm/92_ports.t
View file @
b847e558
...
...
@@ -704,6 +704,93 @@ sub _iptables_save($vm,$table=undef,$chain=undef) {
return
@out
;
}
sub
test_open_port_duplicated
($vm) {
diag
("
Test open port duplicated
"
.
$vm
->
type
);
my
$base
=
$BASE
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
$base
->
expose
(
port
=>
22
,
name
=>
"
ssh
");
my
@base_ports0
=
$base
->
list_ports
();
$base
->
prepare_base
(
user
=>
user_admin
);
my
$clone
=
$base
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
$clone
->
start
(
remote_ip
=>
'
10.1.1.1
',
user
=>
user_admin
);
_wait_ip2
(
$vm
,
$clone
);
wait_request
();
my
@out
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open
=
(
grep
/--to-destination [\d\.]+:22/
,
@out
);
is
(
scalar
(
@open
),
1
);
my
(
$public_port
)
=
$open
[
0
]
=~
/--dport (\d+)/
;
die
"
Error: no public port in
$open
[0]
"
if
!
$public_port
;
$vm
->
iptables
(
t
=>
'
nat
'
,
A
=>
'
PREROUTING
'
,
p
=>
'
tcp
'
,
d
=>
'
192.0.2.3
'
,
dport
=>
$public_port
,
j
=>
'
DNAT
'
,
'
to-destination
'
=>
'
127.0.0.1:23
'
);
my
@out2
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open2
=
(
grep
/--dport $public_port/
,
@out2
);
is
(
scalar
(
@open2
),
2
)
or
die
Dumper
(
\
@open2
);
my
$req
=
Ravada::
Request
->
refresh_vms
();
wait_request
();
is
(
$req
->
status
,'
done
');
is
(
$req
->
error
,
'');
my
@out3
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open3
=
(
grep
/--dport $public_port/
,
@out3
);
is
(
scalar
(
@open3
),
1
)
or
die
Dumper
(
\
@open3
);
$clone
->
remove
(
user_admin
);
$base
->
remove
(
user_admin
);
}
sub
test_close_port
($vm) {
diag
("
Test close port
"
.
$vm
->
type
);
my
$base
=
$BASE
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
$base
->
expose
(
port
=>
22
,
name
=>
"
ssh
");
my
@base_ports0
=
$base
->
list_ports
();
$base
->
prepare_base
(
user
=>
user_admin
);
my
$clone
=
$base
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
$clone
->
start
(
remote_ip
=>
'
10.1.1.1
',
user
=>
user_admin
);
_wait_ip2
(
$vm
,
$clone
);
wait_request
();
my
@out
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open
=
(
grep
/--to-destination [\d\.]+:22/
,
@out
);
is
(
scalar
(
@open
),
1
);
my
(
$public_port
)
=
$open
[
0
]
=~
/--dport (\d+)/
;
die
"
Error: no public port in
$open
[0]
"
if
!
$public_port
;
$vm
->
iptables
(
t
=>
'
nat
'
,
A
=>
'
PREROUTING
'
,
p
=>
'
tcp
'
,
d
=>
'
192.0.2.3
'
,
dport
=>
$public_port
,
j
=>
'
DNAT
'
,
'
to-destination
'
=>
'
127.0.0.1:23
'
);
my
@out2
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open2
=
(
grep
/--dport $public_port/
,
@out2
);
is
(
scalar
(
@open2
),
2
)
or
die
Dumper
(
\
@open
);
$clone
->
shutdown_now
(
user_admin
);
wait_request
();
my
@out3
=
split
/\n/
,
`
iptables-save -t nat
`;
my
@open3
=
(
grep
/--to-destination [\d\.]+:22/
,
@out3
);
is
(
scalar
(
@open3
),
0
,
Dumper
(
\
@open3
));
$clone
->
remove
(
user_admin
);
$base
->
remove
(
user_admin
);
}
sub
test_clone_exports_add_ports
($vm) {
my
$base
=
$BASE
->
clone
(
name
=>
new_domain_name
,
user
=>
user_admin
);
...
...
@@ -759,30 +846,6 @@ sub _wait_ip2($vm_name, $domain) {
sub
_wait_ip
{
return
_wait_ip2
(
@
_
);
my
$vm_name
=
shift
;
my
$domain
=
shift
or
confess
"
Missing domain arg
";
return
$domain
->
ip
if
$domain
->
ip
;
sleep
1
;
eval
'
$domain->domain->send_key(Sys::Virt::Domain::KEYCODE_SET_LINUX,200, [28])
';
die
$@
if
$@
;
return
if
$@
;
sleep
2
;
for
(
1
..
12
)
{
rvd_back
->
_process_requests_dont_fork
();
eval
'
$domain->domain->send_key(Sys::Virt::Domain::KEYCODE_SET_LINUX,200, [28])
';
die
$@
if
$@
;
sleep
2
;
}
for
(
1
..
30
)
{
last
if
$domain
->
ip
;
sleep
1
;
diag
("
waiting for
"
.
$domain
->
name
.
"
ip
")
if
$_
==
10
;
}
return
$domain
->
ip
;
}
sub
add_network_10
{
...
...
@@ -1184,6 +1247,9 @@ for my $vm_name ( 'KVM', 'Void' ) {
flush_rules
()
if
!
$<
;
import_base
(
$vm
);
test_open_port_duplicated
(
$vm
);
test_close_port
(
$vm
);
test_routing_hibernated
(
$vm
);
test_routing_already_used
(
$vm
,
undef
,'
restricted
');
test_routing_already_used
(
$vm
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment