X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=html%2Fcgi-bin%2Fovpnmain.cgi;h=7a2833ce61bd5c283ef72112d41fd7e48df96092;hb=0fd28c360e123d770017207b434ff1de0cb7ed38;hp=eac962e6c7ba9f16fb7f0bd3778adaaf5df80b2f;hpb=d8ef6a9537537ed43d7766ced22d3500b965ed1a;p=people%2Fpmueller%2Fipfire-2.x.git diff --git a/html/cgi-bin/ovpnmain.cgi b/html/cgi-bin/ovpnmain.cgi index eac962e6c7..7a2833ce61 100644 --- a/html/cgi-bin/ovpnmain.cgi +++ b/html/cgi-bin/ovpnmain.cgi @@ -35,7 +35,7 @@ require '/var/ipfire/general-functions.pl'; require "${General::swroot}/lang.pl"; require "${General::swroot}/header.pl"; require "${General::swroot}/countries.pl"; -require "${General::swroot}/geoip-functions.pl"; +require "${General::swroot}/location-functions.pl"; # enable only the following on debugging purpose #use warnings; @@ -47,7 +47,7 @@ undef (@dummy); my %color = (); my %mainsettings = (); &General::readhash("${General::swroot}/main/settings", \%mainsettings); -&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color); +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include/colors.txt", \%color); ### ### Initialize variables @@ -64,6 +64,8 @@ my %cahash=(); my %selected=(); my $warnmessage = ''; my $errormessage = ''; +my $cryptoerror = ''; +my $cryptowarning = ''; my %settings=(); my $routes_push_file = ''; my $confighost="${General::swroot}/fwhosts/customhosts"; @@ -97,6 +99,8 @@ $cgiparams{'DCIPHER'} = ''; $cgiparams{'DAUTH'} = ''; $cgiparams{'TLSAUTH'} = ''; $routes_push_file = "${General::swroot}/ovpn/routes_push"; +# Perform crypto and configration test +&pkiconfigcheck; # Add CCD files if not already presant unless (-e $routes_push_file) { @@ -170,7 +174,12 @@ sub cleanssldatabase print FILE ""; close FILE; } + if (open(FILE, ">${General::swroot}/ovpn/certs/index.txt.attr")) { + print FILE ""; + close FILE; + } unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old"); unlink ("${General::swroot}/ovpn/certs/serial.old"); unlink ("${General::swroot}/ovpn/certs/01.pem"); } @@ -183,9 +192,13 @@ sub newcleanssldatabase close FILE; } if (! -s ">${General::swroot}/ovpn/certs/index.txt") { - system ("touch ${General::swroot}/ovpn/certs/index.txt"); + &General::system("touch", "${General::swroot}/ovpn/certs/index.txt"); + } + if (! -s ">${General::swroot}/ovpn/certs/index.txt.attr") { + &General::system("touch", "${General::swroot}/ovpn/certs/index.txt.attr"); } unlink ("${General::swroot}/ovpn/certs/index.txt.old"); + unlink ("${General::swroot}/ovpn/certs/index.txt.attr.old"); unlink ("${General::swroot}/ovpn/certs/serial.old"); } @@ -199,6 +212,57 @@ sub deletebackupcert } } +### +### Check for PKI and configure problems +### + +sub pkiconfigcheck +{ + # Warning if DH parameter is 1024 bit + if (-f "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}") { + my @dhparameter = &General::system_output("/usr/bin/openssl", "dhparam", "-text", "-in", "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}"); + my $dhbit; + + # Loop through the output and search for the DH bit lenght. + foreach my $line (@dhparameter) { + if ($line =~ (/(\d+)/)) { + # Assign match to dhbit value. + $dhbit = $1; + + last; + } + } + + # Check if the used key lenght is at least 2048 bit. + if ($dhbit < 2048) { + $cryptoerror = "$Lang::tr{'ovpn error dh'}"; + goto CRYPTO_ERROR; + } + } + + # Warning if md5 is in usage + if (-f "${General::swroot}/ovpn/certs/servercert.pem") { + my @signature = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if (grep(/md5WithRSAEncryption/, @signature) ) { + $cryptoerror = "$Lang::tr{'ovpn error md5'}"; + goto CRYPTO_ERROR; + } + } + + CRYPTO_ERROR: + + # Warning if certificate is not compliant to RFC3280 TLS rules + if (-f "${General::swroot}/ovpn/certs/servercert.pem") { + my @extendkeyusage = &General::system_output("/usr/bin/openssl", "x509", "-noout", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if ( ! grep(/TLS Web Server Authentication/, @extendkeyusage)) { + $cryptowarning = "$Lang::tr{'ovpn warning rfc3280'}"; + goto CRYPTO_WARNING; + } + } + + CRYPTO_WARNING: +} + sub writeserverconf { my %sovpnsettings = (); my @temp = (); @@ -228,14 +292,7 @@ sub writeserverconf { print CONF "server $tempovpnsubnet[0] $tempovpnsubnet[1]\n"; #print CONF "push \"route $netsettings{'GREEN_NETADDRESS'} $netsettings{'GREEN_NETMASK'}\"\n"; - # Check if we are using mssfix, fragment or mtu-disc and set the corretct mtu of 1500. - # If we doesn't use one of them, we can use the configured mtu value. - if ($sovpnsettings{'MSSFIX'} eq 'on') - { print CONF "tun-mtu 1500\n"; } - elsif ($sovpnsettings{'FRAGMENT'} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') - { print CONF "tun-mtu 1500\n"; } - else - { print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; } + print CONF "tun-mtu $sovpnsettings{'DMTU'}\n"; if ($vpnsettings{'ROUTES_PUSH'} ne '') { @temp = split(/\n/,$vpnsettings{'ROUTES_PUSH'}); @@ -268,6 +325,8 @@ sub writeserverconf { } if ($sovpnsettings{MSSFIX} eq 'on') { print CONF "mssfix\n"; + } else { + print CONF "mssfix 0\n"; } if ($sovpnsettings{FRAGMENT} ne '' && $sovpnsettings{'DPROTOCOL'} ne 'tcp') { print CONF "fragment $sovpnsettings{'FRAGMENT'}\n"; @@ -280,11 +339,10 @@ sub writeserverconf { print CONF "status /var/run/ovpnserver.log 30\n"; print CONF "ncp-disable\n"; print CONF "cipher $sovpnsettings{DCIPHER}\n"; - if ($sovpnsettings{'DAUTH'} eq '') { - print CONF ""; - } else { print CONF "auth $sovpnsettings{'DAUTH'}\n"; - } + # Set TLSv2 as minimum + print CONF "tls-version-min 1.2\n"; + if ($sovpnsettings{'TLSAUTH'} eq 'on') { print CONF "tls-auth ${General::swroot}/ovpn/certs/ta.key\n"; } @@ -306,10 +364,10 @@ sub writeserverconf { print CONF "push \"dhcp-option WINS $sovpnsettings{DHCP_WINS}\"\n"; } - if ($sovpnsettings{DHCP_WINS} eq '') { + if ($sovpnsettings{MAX_CLIENTS} eq '') { print CONF "max-clients 100\n"; } - if ($sovpnsettings{DHCP_WINS} ne '') { + if ($sovpnsettings{MAX_CLIENTS} ne '') { print CONF "max-clients $sovpnsettings{MAX_CLIENTS}\n"; } print CONF "tls-verify /usr/lib/openvpn/verify\n"; @@ -323,6 +381,11 @@ sub writeserverconf { } else { print CONF "verb 3\n"; } + + print CONF "# Log clients connecting/disconnecting\n"; + print CONF "client-connect \"/usr/sbin/openvpn-metrics client-connect\"\n"; + print CONF "client-disconnect \"/usr/sbin/openvpn-metrics client-disconnect\"\n"; + # Print server.conf.local if entries exist to server.conf if ( !-z $local_serverconf && $sovpnsettings{'ADDITIONAL_CONFIGS'} eq 'on') { open (LSC, "$local_serverconf"); @@ -417,10 +480,7 @@ sub addccdnet $errormessage=$Lang::tr{'ccd err invalidnet'}; return; } - - $errormessage=&General::checksubnets($ccdname,$ccdnet); - - + if (!$errormessage) { my %ccdconfhash=(); $baseaddress=&General::getnetworkip($ccdip,$subcidr); @@ -444,6 +504,13 @@ sub modccdnet my $oldname=$_[1]; my %ccdconfhash=(); my %ccdhash=(); + + # Check if the new name is valid. + if(!&General::validhostname($newname)) { + $errormessage=$Lang::tr{'ccd err invalidname'}; + return; + } + &General::readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash); foreach my $key (keys %ccdconfhash) { if ($ccdconfhash{$key}[0] eq $oldname) { @@ -679,7 +746,7 @@ sub writecollectdconf { close(COLLECTDVPN); # Reload collectd afterwards - system("/usr/local/bin/collectdctrl restart &>/dev/null"); + &General::system("/usr/local/bin/collectdctrl", "restart"); } #hier die refresh page @@ -709,11 +776,11 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'} || #start openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'start ovpn server'}){ &emptyserverlog(); - system('/usr/local/bin/openvpnctrl', '-s'); + &General::system("/usr/local/bin/openvpnctrl", "-s"); } #stop openvpn server if ($cgiparams{'ACTION'} eq $Lang::tr{'stop ovpn server'}){ - system('/usr/local/bin/openvpnctrl', '-k'); + &General::system("/usr/local/bin/openvpnctrl", "-k"); &emptyserverlog(); } # #restart openvpn server @@ -739,13 +806,12 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { $vpnsettings{'MAX_CLIENTS'} = $cgiparams{'MAX_CLIENTS'}; $vpnsettings{'REDIRECT_GW_DEF1'} = $cgiparams{'REDIRECT_GW_DEF1'}; $vpnsettings{'CLIENT2CLIENT'} = $cgiparams{'CLIENT2CLIENT'}; + $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; $vpnsettings{'ADDITIONAL_CONFIGS'} = $cgiparams{'ADDITIONAL_CONFIGS'}; $vpnsettings{'DHCP_DOMAIN'} = $cgiparams{'DHCP_DOMAIN'}; $vpnsettings{'DHCP_DNS'} = $cgiparams{'DHCP_DNS'}; $vpnsettings{'DHCP_WINS'} = $cgiparams{'DHCP_WINS'}; $vpnsettings{'ROUTES_PUSH'} = $cgiparams{'ROUTES_PUSH'}; - $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'}; - $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'}; my @temp=(); if ($cgiparams{'FRAGMENT'} eq '') { @@ -833,7 +899,7 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { undef $vpnsettings{'ROUTES_PUSH'}; &write_routepushfile; } - if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 255 )) { + if ((length($cgiparams{'MAX_CLIENTS'}) == 0) || (($cgiparams{'MAX_CLIENTS'}) < 1 ) || (($cgiparams{'MAX_CLIENTS'}) > 1024 )) { $errormessage = $Lang::tr{'invalid input for max clients'}; goto ADV_ERROR; } @@ -853,17 +919,6 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save-adv-options'}) { $errormessage = $Lang::tr{'invalid input for keepalive 1:2'}; goto ADV_ERROR; } - # Create ta.key for tls-auth if not presant - if ($cgiparams{'TLSAUTH'} eq 'on') { - if ( ! -e "${General::swroot}/ovpn/certs/ta.key") { - system('/usr/sbin/openvpn', '--genkey', '--secret', "${General::swroot}/ovpn/certs/ta.key"); - if ($?) { - $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; - goto ADV_ERROR; - } - } - } - &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); &writeserverconf();#hier ok } @@ -927,7 +982,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print SERVERCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print SERVERCONF "fragment $cgiparams{'FRAGMENT'}\n";} - if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; }; + if ($cgiparams{'MSSFIX'} eq 'on') {print SERVERCONF "mssfix\n"; } else { print SERVERCONF "mssfix 0\n" }; } print SERVERCONF "# Auth. Server\n"; @@ -950,6 +1005,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print SERVERCONF "auth $cgiparams{'DAUTH'}\n"; } + # Set TLSv1.2 as minimum + print SERVERCONF "tls-version-min 1.2\n"; + if ($cgiparams{'COMPLZO'} eq 'on') { print SERVERCONF "# Enable Compression\n"; print SERVERCONF "comp-lzo\n"; @@ -1023,14 +1081,14 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General if ($cgiparams{'MTU'} eq '') {$tunmtu = '1500'} else {$tunmtu = $cgiparams{'MTU'}}; print CLIENTCONF "tun-mtu $tunmtu\n"; if ($cgiparams{'FRAGMENT'} ne '') {print CLIENTCONF "fragment $cgiparams{'FRAGMENT'}\n";} - if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; }; + if ($cgiparams{'MSSFIX'} eq 'on') {print CLIENTCONF "mssfix\n"; } else { print CLIENTCONF "mssfix 0\n" }; } # Check host certificate if X509 is RFC3280 compliant. # If not, old --ns-cert-type directive will be used. # If appropriate key usage extension exists, new --remote-cert-tls directive will be used. - my $hostcert = `/usr/bin/openssl x509 -text -in ${General::swroot}/ovpn/certs/servercert.pem`; - if ($hostcert !~ /TLS Web Server Authentication/) { + my @hostcert = &General::system_output("/usr/bin/openssl", "x509", "-text", "-in", "${General::swroot}/ovpn/certs/servercert.pem"); + if ( ! grep(/TLS Web Server Authentication/, @hostcert)) { print CLIENTCONF "ns-cert-type server\n"; } else { print CLIENTCONF "remote-cert-tls server\n"; @@ -1052,6 +1110,9 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General print CLIENTCONF "auth $cgiparams{'DAUTH'}\n"; } + # Set TLSv1.2 as minimum + print CLIENTCONF "tls-version-min 1.2\n"; + if ($cgiparams{'COMPLZO'} eq 'on') { print CLIENTCONF "# Enable Compression\n"; print CLIENTCONF "comp-lzo\n"; @@ -1069,7 +1130,7 @@ unless(-d "${General::swroot}/ovpn/n2nconf/$cgiparams{'NAME'}"){mkdir "${General close(CLIENTCONF); } - + ### ### Save main settings ### @@ -1144,6 +1205,18 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg goto SETTINGS_ERROR; } + # Create ta.key for tls-auth if not presant + if ($cgiparams{'TLSAUTH'} eq 'on') { + if ( ! -e "${General::swroot}/ovpn/certs/ta.key") { + # This system call is safe, because all arguements are passed as an array. + system("/usr/sbin/openvpn", "--genkey", "--secret", "${General::swroot}/ovpn/certs/ta.key"); + if ($?) { + $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; + goto SETTINGS_ERROR; + } + } + } + $vpnsettings{'ENABLED_BLUE'} = $cgiparams{'ENABLED_BLUE'}; $vpnsettings{'ENABLED_ORANGE'} =$cgiparams{'ENABLED_ORANGE'}; $vpnsettings{'ENABLED'} = $cgiparams{'ENABLED'}; @@ -1155,11 +1228,28 @@ if ($cgiparams{'ACTION'} eq $Lang::tr{'save'} && $cgiparams{'TYPE'} eq '' && $cg $vpnsettings{'DMTU'} = $cgiparams{'DMTU'}; $vpnsettings{'DCOMPLZO'} = $cgiparams{'DCOMPLZO'}; $vpnsettings{'DCIPHER'} = $cgiparams{'DCIPHER'}; + $vpnsettings{'DAUTH'} = $cgiparams{'DAUTH'}; + $vpnsettings{'TLSAUTH'} = $cgiparams{'TLSAUTH'}; #wrtie enable - if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_blue 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_blue 2>/dev/null");} - if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable_orange 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable_orange 2>/dev/null");} - if ( $vpnsettings{'ENABLED'} eq 'on' ) {system("touch ${General::swroot}/ovpn/enable 2>/dev/null");}else{system("unlink ${General::swroot}/ovpn/enable 2>/dev/null");} + if ( $vpnsettings{'ENABLED_BLUE'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable_blue"); + } else { + unlink("${General::swroot}/ovpn/enable_blue"); + } + + if ( $vpnsettings{'ENABLED_ORANGE'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable_orange"); + } else { + unlink("${General::swroot}/ovpn/enable_orange"); + } + + if ( $vpnsettings{'ENABLED'} eq 'on' ) { + &General::system("touch", "${General::swroot}/ovpn/enable"); + } else { + unlink("${General::swroot}/ovpn/enable"); + } + #new settings for daemon &General::writehash("${General::swroot}/ovpn/settings", \%vpnsettings); &writeserverconf();#hier ok @@ -1172,7 +1262,7 @@ SETTINGS_ERROR: &General::readhasharray("${General::swroot}/ovpn/ovpnconfig", \%confighash); # Kill all N2N connections - system("/usr/local/bin/openvpnctrl -kn2n &>/dev/null"); + &General::system("/usr/local/bin/openvpnctrl", "-kn2n"); foreach my $key (keys %confighash) { my $name = $confighash{$cgiparams{'$key'}}[1]; @@ -1181,7 +1271,7 @@ SETTINGS_ERROR: delete $confighash{$cgiparams{'$key'}}; } - system ("/usr/local/bin/openvpnctrl -drrd $name"); + &General::system("/usr/local/bin/openvpnctrl", "-drrd", "$name"); } while ($file = glob("${General::swroot}/ovpn/ca/*")) { unlink $file; @@ -1220,7 +1310,7 @@ SETTINGS_ERROR: close FILE; } while ($file = glob("${General::swroot}/ovpn/n2nconf/*")) { - system ("rm -rf $file"); + unlink($file); } # Remove everything from the collectd configuration @@ -1266,7 +1356,8 @@ END unlink "${General::swroot}/ovpn/ca/$cgiparams{'DH_NAME'}"; } # Create Diffie Hellmann Parameter - system('/usr/bin/openssl', 'dhparam', '-out', "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}"); + # The system call is safe, because all arguments are passed as an array. + system("/usr/bin/openssl", "dhparam", "-out", "${General::swroot}/ovpn/ca/dh1024.pem", "$cgiparams{'DHLENGHT'}"); if ($?) { $errormessage = "$Lang::tr{'openssl produced an error'}: $?"; unlink ("${General::swroot}/ovpn/ca/dh1024.pem"); @@ -1291,7 +1382,6 @@ END