Commit 3ffb722d authored by Dietmar Maurer's avatar Dietmar Maurer

reuse host based access control code for spiceproxy

parent f3de8a0b
...@@ -5,6 +5,7 @@ use warnings; ...@@ -5,6 +5,7 @@ use warnings;
use POSIX ":sys_wait_h"; use POSIX ":sys_wait_h";
use Socket qw(IPPROTO_TCP TCP_NODELAY SOMAXCONN); use Socket qw(IPPROTO_TCP TCP_NODELAY SOMAXCONN);
use IO::Socket::INET; use IO::Socket::INET;
use Net::IP;
use PVE::SafeSyslog; use PVE::SafeSyslog;
use PVE::HTTPServer; use PVE::HTTPServer;
...@@ -191,4 +192,38 @@ sub start_server { ...@@ -191,4 +192,38 @@ sub start_server {
} }
} }
sub read_proxy_config {
my $conffile = "/etc/default/pveproxy";
# Note: evaluate with bash
my $shcmd = ". $conffile;\n";
$shcmd .= 'echo \"ALLOW_FROM:\$ALLOW_FROM\";';
$shcmd .= 'echo \"DENY_FROM:\$DENY_FROM\";';
$shcmd .= 'echo \"POLICY:\$POLICY\";';
my $data = `bash -c "$shcmd"`;
my $res = {};
while ($data =~ s/^(.*)\n//) {
my ($key, $value) = split(/:/, $1, 2);
if ($key eq 'ALLOW_FROM' || $key eq 'DENY_FROM') {
my $ips = [];
foreach my $ip (split(/,/, $value)) {
$ip = "0/0" if $ip eq 'all';
push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
}
$res->{$key} = $ips;
} elsif ($key eq 'POLICY') {
die "unknown policy '$value'\n" if $value !~ m/^(allow|deny)$/;
$res->{$key} = $value;
} else {
# silently skip everythin else?
}
}
return $res;
}
1; 1;
...@@ -31,25 +31,8 @@ DAEMON_OPTS="" ...@@ -31,25 +31,8 @@ DAEMON_OPTS=""
# Include defaults if available # Include defaults if available
if [ -f /etc/default/$NAME ] ; then if [ -f /etc/default/$NAME ] ; then
ALLOW_FROM=""
DENY_FROM=""
POLICY=""
. /etc/default/$NAME . /etc/default/$NAME
if [ -n "$ALLOW_FROM" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --allow-from ${ALLOW_FROM}"
fi
if [ -n "$DENY_FROM" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --deny-from ${DENY_FROM}"
fi
if [ -n "$POLICY" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --policy $POLICY"
fi
fi fi
case "$1" in case "$1" in
start) start)
......
...@@ -31,25 +31,8 @@ DAEMON_OPTS="" ...@@ -31,25 +31,8 @@ DAEMON_OPTS=""
# Include defaults if available # Include defaults if available
if [ -f /etc/default/$NAME ] ; then if [ -f /etc/default/$NAME ] ; then
ALLOW_FROM=""
DENY_FROM=""
POLICY=""
. /etc/default/$NAME . /etc/default/$NAME
if [ -n "$ALLOW_FROM" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --allow-from ${ALLOW_FROM}"
fi
if [ -n "$DENY_FROM" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --deny-from ${DENY_FROM}"
fi
if [ -n "$POLICY" ] ; then
DAEMON_OPTS="${DAEMON_OPTS} --policy $POLICY"
fi
fi fi
case "$1" in case "$1" in
start) start)
......
...@@ -18,47 +18,16 @@ use URI; ...@@ -18,47 +18,16 @@ use URI;
use URI::QueryParam; use URI::QueryParam;
use File::Find; use File::Find;
use Data::Dumper; use Data::Dumper;
use Net::IP;
my $pidfile = "/var/run/pveproxy/pveproxy.pid"; my $pidfile = "/var/run/pveproxy/pveproxy.pid";
my $lockfile = "/var/lock/pveproxy.lck"; my $lockfile = "/var/lock/pveproxy.lck";
my $opt_debug; my $opt_debug;
my $opt_allow_from;
my $opt_deny_from;
my $opt_policy;
initlog ('pveproxy'); initlog ('pveproxy');
if (!GetOptions ('allow-from=s@' => \$opt_allow_from, if (!GetOptions ('debug' => \$opt_debug)) {
'deny-from=s@' => \$opt_deny_from, die "usage: $0 [--debug]\n";
'policy=s' => \$opt_policy,
'debug' => \$opt_debug)) {
die "usage: $0 [--allow-from CIDR{,CIRD}] [--deny-from CIDR{,CIRD}] [--policy (allow|deny)] [--debug]\n";
}
$opt_deny_from = [ split(/,/, join(',', @$opt_deny_from)) ] if $opt_deny_from;
$opt_allow_from = [ split(/,/, join(',', @$opt_allow_from)) ] if $opt_allow_from;
die "unknown policy '$opt_policy'\n" if $opt_policy && $opt_policy !~ m/^(allow|deny)$/;
if ($opt_deny_from) {
my $ips = [];
foreach my $ip (@$opt_deny_from) {
$ip = "0/0" if $ip eq 'all';
push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
}
$opt_deny_from = $ips;
}
if ($opt_allow_from) {
my $ips = [];
foreach my $ip (@$opt_allow_from) {
$ip = "0/0" if $ip eq 'all';
push @$ips, Net::IP->new($ip) || die Net::IP::Error() . "\n";
}
$opt_allow_from = $ips;
} }
$SIG{'__WARN__'} = sub { $SIG{'__WARN__'} = sub {
...@@ -81,6 +50,8 @@ POSIX::setuid($uid) || die "setuid $uid failed - $!\n"; ...@@ -81,6 +50,8 @@ POSIX::setuid($uid) || die "setuid $uid failed - $!\n";
# just to be sure # just to be sure
die "detected strange uid/gid\n" if !($UID == $uid && $EUID == $uid && $GID eq "$gid $gid" && $EGID eq "$gid $gid"); die "detected strange uid/gid\n" if !($UID == $uid && $EUID == $uid && $GID eq "$gid $gid" && $EGID eq "$gid $gid");
my $proxyconf = PVE::APIDaemon::read_proxy_config();
sub add_dirs { sub add_dirs {
my ($result_hash, $alias, $subdir) = @_; my ($result_hash, $alias, $subdir) = @_;
...@@ -114,9 +85,9 @@ eval { ...@@ -114,9 +85,9 @@ eval {
max_conn => 500, max_conn => 500,
max_requests => 1000, max_requests => 1000,
debug => $opt_debug, debug => $opt_debug,
allow_from => $opt_allow_from, allow_from => $proxyconf->{ALLOW_FROM},
deny_from => $opt_deny_from, deny_from => $proxyconf->{DENY_FROM},
policy => $opt_policy, policy => $proxyconf->{POLICY},
trusted_env => 0, # not trusted, anyone can connect trusted_env => 0, # not trusted, anyone can connect
logfile => '/var/log/pveproxy/access.log', logfile => '/var/log/pveproxy/access.log',
lockfile => $lockfile, lockfile => $lockfile,
...@@ -286,7 +257,7 @@ pveproxy - the PVE API proxy server ...@@ -286,7 +257,7 @@ pveproxy - the PVE API proxy server
=head1 SYNOPSIS =head1 SYNOPSIS
pveproxy [--allow-from CIDR{,CIRD}] [--deny-from CIDR{,CIRD}] [--policy (allow|deny)] [--debug] pveproxy [--debug]
=head1 DESCRIPTION =head1 DESCRIPTION
...@@ -297,8 +268,7 @@ as service using: ...@@ -297,8 +268,7 @@ as service using:
=head1 Host based access control =head1 Host based access control
Options '--allow-from', '--deny-from' and '--policy' can be used to set up It is possible to configure apache2 like access control lists. Values are read
apache2 like access control. If started as service, those values are read
from file /etc/default/pveproxy. For example: from file /etc/default/pveproxy. For example:
ALLOW_FROM="10.0.0.1-10.0.0.5,192.168.0.0/22" ALLOW_FROM="10.0.0.1-10.0.0.5,192.168.0.0/22"
......
...@@ -44,6 +44,9 @@ POSIX::setuid($uid) || die "setuid $uid failed - $!\n"; ...@@ -44,6 +44,9 @@ POSIX::setuid($uid) || die "setuid $uid failed - $!\n";
# just to be sure # just to be sure
die "detected strange uid/gid\n" if !($UID == $uid && $EUID == $uid && $GID eq "$gid $gid" && $EGID eq "$gid $gid"); die "detected strange uid/gid\n" if !($UID == $uid && $EUID == $uid && $GID eq "$gid $gid" && $EGID eq "$gid $gid");
# we use same ALLOW/DENY/POLICY as pveproxy
my $proxyconf = PVE::APIDaemon::read_proxy_config();
my $cpid; my $cpid;
my $daemon; my $daemon;
eval { eval {
...@@ -56,6 +59,9 @@ eval { ...@@ -56,6 +59,9 @@ eval {
debug => $opt_debug, debug => $opt_debug,
spiceproxy => 1, spiceproxy => 1,
logfile => '/var/log/pveproxy/access.log', logfile => '/var/log/pveproxy/access.log',
allow_from => $proxyconf->{ALLOW_FROM},
deny_from => $proxyconf->{DENY_FROM},
policy => $proxyconf->{POLICY},
); );
}; };
...@@ -129,6 +135,15 @@ spiceproxy [--debug] ...@@ -129,6 +135,15 @@ spiceproxy [--debug]
SPICE proxy server for Proxmox VE. Listens on port 3128. SPICE proxy server for Proxmox VE. Listens on port 3128.
=head1 Host based access control
It is possible to configure apache2 like access control lists. Values are read
from file /etc/default/pveproxy (see 'pveproxy' for details).
=head1 FILES
/etc/default/pveproxy
=head1 COPYRIGHT AND DISCLAIMER =head1 COPYRIGHT AND DISCLAIMER
Copyright (C) 2007-2013 Proxmox Server Solutions GmbH Copyright (C) 2007-2013 Proxmox Server Solutions GmbH
......
Markdown is supported
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