summaryrefslogtreecommitdiffstats
path: root/etc/inc
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2005-10-12 16:49:15 +0000
committerScott Ullrich <sullrich@pfsense.org>2005-10-12 16:49:15 +0000
commitafb07cf1534c335bc9cffd49f00ba171cea5702c (patch)
treee5cc650292f7dd67af9b77de4e3b61bd027ec840 /etc/inc
parent8d3a4a1e12e23b6d3333de75f403c712a99d3c64 (diff)
downloadpfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.zip
pfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.tar.gz
Sync OpenVPN with http://www.protec-t.de/m0n0wall/downloads from Peter Allgeyer
Diffstat (limited to 'etc/inc')
-rw-r--r--etc/inc/openvpn.inc1291
1 files changed, 950 insertions, 341 deletions
diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc
index 0953779..1036f31 100644
--- a/etc/inc/openvpn.inc
+++ b/etc/inc/openvpn.inc
@@ -3,6 +3,7 @@
openvpn.inc
Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,8 @@ require_once("functions.inc");
function ovpn_configure($reconfigure) {
global $config;
if (is_array($config['ovpn']['server']))
+ ovpn_server_crl_add();
+ ovpn_server_ccd_add();
ovpn_config_server($reconfigure);
if (is_array($config['ovpn']['client']))
ovpn_config_client();
@@ -50,13 +53,13 @@ function ovpn_link_tap() {
mwexec("/sbin/kldload if_tap");
$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'w');
}
- else {
- $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
- $link_count = fread($fd);
- $link_count ++;
- }
- fwrite($fd, $link_count);
- fclose($fd);
+ //else {
+ // $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
+ // $link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
+ // $link_count ++;
+ //}
+ //fwrite($fd, $link_count);
+ //fclose($fd);
return true;
}
@@ -68,8 +71,8 @@ function ovpn_unlink_tap() {
return false; //no file, no links so why are we called?
$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
- $link_count = fread($fd);
- $link_count --;
+ $link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
+ $link_count--;
fwrite($fd, $link_count);
fclose($fd);
@@ -82,146 +85,103 @@ function ovpn_unlink_tap() {
/* Server related functions */
/*****************************/
-function getnxt_server_if($type) {
- /* find the first available device of type $type */
- global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- $max = ($type == 'tun') ? 17 : 4;
- for ($i = 0; $i < $max ; $i++) {
- $hit = false;
- foreach ($a_server as $server) {
- if ($server['tun_iface'] == $type . $i) {
- $hit = true;
- break;
- }
- }
- if (!$hit)
- return $type . $i;
- }
- return false;
-}
-
-function getnxt_server_port() {
- /* Get first unused port */
- global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- $port = 1194;
- while (true) {
- $hit = false;
- foreach ($a_server as $server) {
- if ($server['port'] == $port) {
- $hit = true;
- break;
- }
- }
- if (!$hit)
- if (!ovpn_port_inuse_client($port))
- return $port;
- $port++;
- }
- return false; /* should never get here */
-}
-
/* Configure the server */
function ovpn_config_server($reconfigure) {
- global $config, $g;
+ global $config, $g, $d_ovpnsrvdirty_path;
foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
/* get tunnel interface */
$tun = $server['tun_iface'];
- /* kill any running openvpn daemon */
- killbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid");
-
if (isset($server['enable'])) {
- if ($g['booting'])
+ if ($g['booting']) {
echo "Starting OpenVPN server $id... ";
+ /* define configuration options */
+ ovpn_srv_config_generate($id);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+
+ /* Send the boot message */
+ echo "done\n";
+
+ /* next server */
+ continue;
+ }
+
/* send SIGUSR1 to running openvpn daemon */
if ( $reconfigure == "true" && isset($server['dynip'])) {
sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
continue;
}
- /* Remove old certs & keys */
- unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
-
- /* Copy the TLS-Server certs & keys to disk */
- $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['ca_cert'])."\n");
- fclose($fd);
- }
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['srv_cert'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['srv_key'])."\n");
- fclose($fd);
- }
- $fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['dh_param'])."\n");
- fclose($fd);
- }
+ /* read dirtyfile */
+ if (is_readable($d_ovpnsrvdirty_path))
+ $lines = file($d_ovpnsrvdirty_path);
+
+ /* reconfigure server */
+ if (is_array($lines) && in_array($tun, $lines)) {
+
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_server_certs_del($tun);
- touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
- fclose($fd);
+ /* define configuration options */
+ ovpn_srv_config_generate($id);
}
/* Start the openvpn daemon */
- mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate($id));
+ if (!is_readable("{$g['varrun_path']}/ovpn_srv_{$tun}.pid"))
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
- if ($g['booting'])
- /* Send the boot message */
- echo "done\n";
+ /* next server */
+ continue;
}
- else {
- if (!$g['booting']){
- /* stop any processes, unload the tap module */
- /* Remove old certs & keys */
- ovpn_server_kill($tun);
- if ($server['type'] == "tap")
- ovpn_unlink_tap();
- }
+ /* server disabled */
+ if (!$g['booting']) {
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* Remove old certs & keys */
+ ovpn_server_certs_del($tun);
+
+ /* stop any processes, unload the tap module */
+ //if ($server['type'] == "tap")
+ // ovpn_unlink_tap();
}
}
return 0;
}
/* Kill off a running server process */
-function ovpn_server_kill($tun) {
+function ovpn_server_certs_del($tun) {
global $g;
- killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
-
/* Remove old certs & keys */
unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_srv_{$tun}.conf");
return 0;
}
+/* Kill off a running server process */
+function ovpn_server_kill($tun) {
+ global $g;
+
+ /* kill running server */
+ killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
+}
+
/* Generate the config for a OpenVPN server */
function ovpn_srv_config_generate($id) {
global $config, $g;
@@ -233,140 +193,253 @@ function ovpn_srv_config_generate($id) {
/* get optional interface name */
$iface = ovpn_get_opt_interface($tun);
+ /* Copy the TLS-Server certs & keys to disk */
+ if ($server['authentication_method'] != "pre_shared_key" ) {
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['ca_cert'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['srv_cert'])."\n");
+ fclose($fd);
+ }
+
+ touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['srv_key'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['dh_param'])."\n");
+ fclose($fd);
+ }
+ }
+
+ if ($server['authentication_method'] == "pre_shared_key" || isset($server['tlsauth'])) {
+ touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
+ fclose($fd);
+ }
+ }
+
+ $fd = fopen("{$g['varetc_path']}/ovpn_srv_{$tun}.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open ovpn_srv_{$tun}.conf in ovpn_srv_config_generate($id).\n");
+ return 1;
+ }
+
/* First the generic stuff:
- We are a server
- - We are a TLS Server (for authentication)
- We will run without privilege
*/
- $ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} --persist-tun --persist-key --status /var/log/openvpn_{$tun}.log 60 ";
-
- /* pid file */
- $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid ";
-
- /* interface */
- $ovpn_config .= "--dev {$server['tun_iface']} ";
-
- /* port */
- $ovpn_config .= "--port {$server['port']} ";
+ $ovpn_config = "";
+ $ovpn_config .= <<<EOD
+daemon
+user nobody
+group nobody
+verb {$server['verb']}
+persist-tun
+persist-key
+status /var/log/openvpn_{$tun}.log 60
+writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid
+dev {$server['tun_iface']}
+port {$server['port']}
+cipher {$server['crypto']}
+
+EOD;
/* Set protocol being used (p = udp (default), tcp-server) */
- if ($server['proto'] == 'tcp') {
- $ovpn_config .= "--proto tcp ";
- }
-
+ if ($server['proto'] == "tcp")
+ $ovpn_config .= "proto tcp-server\n";
+
/* Interface binding - 1 or all */
- if ($server['bind_iface'] != 'all') {
+ if ($server['bind_iface'] != 'all')
if ($ipaddr = ovpn_get_ip($server['bind_iface']))
- $ovpn_config .= "--local $ipaddr ";
- else
- return "Interface bridged";
- }
+ $ovpn_config .= "local {$ipaddr}\n";
/* are we using dynamic ip addresses? */
if (isset($server['dynip']))
- $ovpn_config .= "--persist-remote-ip ";
-
+ $ovpn_config .= "persist-remote-ip\n";
+
/* Client to client routing (off by default) */
if (isset($server['cli2cli']))
- $ovpn_config .= "--client-to-client ";
-
- /* Set maximum simultaneous clients */
- $ovpn_config .= "--max-clients {$server['maxcli']} ";
-
- /* bridging enabled? */
- if (($ifname = $config['interfaces'][$iface]['bridge']) && $server['type'] == "tap") {
- $gateway = $config['interfaces'][$ifname]['ipaddr'];
- $netmask = gen_subnet_mask($config['interfaces'][$ifname]['subnet']);
- $poolstart = $server['ipblock'];
- $poolend = gen_subnet_max($server['ipblock'], $server['prefix']);
+ $ovpn_config .= "client-to-client\n";
- $ovpn_config .= "--server-bridge $gateway $netmask $poolstart $poolend ";
+ /* Limit server to a maximum of n concurrent clients. */
+ if (!empty($server['maxcli']))
+ $ovpn_config .= "max-clients {$server['maxcli']}\n";
- $lastdigits = substr($tun, 3) + 2;
- $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+ /* Authentication method */
+ if ($server['authentication_method'] != "pre_shared_key") {
- $fd = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
- if ($fd) {
- fwrite($fd, $ovpn_srv_up);
- fclose($fd);
- chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
- $ovpn_config .= "--up /var/etc/ovpn_srv_up_{$tun}.sh ";
+ $ovpn_config .= <<<EOD
+client-config-dir {$g['vardb_path']}/ccd
+ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem
+cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem
+key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem
+dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem
+
+EOD;
+
+ /* CRL list */
+ if (isset($server['crlname']) &&
+ is_readable("{$g['vardb_path']}/{$server['crlname']}.crl.pem")) {
+ $ovpn_config .= "crl-verify {$g['vardb_path']}/{$server['crlname']}.crl.pem\n";
}
+
+ /* TLS auth */
+ if (isset($server['tlsauth']))
+ $ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
+
+ /* bridging enabled? */
+ if ($server['bridge'] && $server['type'] == "tap") {
+ if ($server['method'] == "ovpn") {
+ $netmask = gen_subnet_mask($config['interfaces'][$server['bridge']]['subnet']);
+ $ovpn_config .= "server-bridge {$server['gateway']} {$netmask} {$server['range_from']} {$server['range_to']}\n";
+ } else {
+ $ovpn_config .= <<<EOD
+mode server
+tls-server
+
+EOD;
+ }
+
+ $lastdigits = substr($tun, 3) + 2;
+ $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+ $fdo = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
+ if ($fdo) {
+ fwrite($fdo, $ovpn_srv_up);
+ fclose($fdo);
+ chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
+ $ovpn_config .= "up /var/etc/ovpn_srv_up_{$tun}.sh\n";
+ }
+
+ } else {
+ /* Not bridged, can be tun or tap, doesn't matter */
+ $netmask = gen_subnet_mask($server['prefix']);
+
+ if ($server['method'] == "ovpn") {
+ /* new --server macro simplifies config */
+ $ovpn_config .= "server {$server['ipblock']} {$netmask}\n";
+ } else {
+ $ovpn_config .= <<<EOD
+mode server
+tls-server
+ifconfig {$server['ipblock']} {$netmask}
+
+EOD;
+ }
+ } /* end bridging */
+
+ /* Duplicate CNs */
+ if (isset($server['dupcn']))
+ $ovpn_config .= "duplicate-cn\n";
+
} else {
- /* New --server macro simplifies config */
- $netmask = gen_subnet_mask($server['prefix']);
+ /* 'authentication_method' == "pre_shared_key" */
+ $network = gen_subnet($server['lipaddr'], $server['netmask']);
+ $netmask = gen_subnet_mask($server['netmask']);
- $ovpn_config .= "--server {$server['ipblock']} {$netmask} ";
- }
-
- /* TLS-Server params */
- $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem ";
- $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem ";
- $ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem ";
- $ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem ";
-
- /* TLS auth */
- if (isset($server['tlsauth']))
- $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0 ";
-
- /* Data channel encryption cipher*/
- $ovpn_config .= "--cipher {$server['crypto']} ";
+ $ovpn_config .= "secret {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
+
+ if (strstr($server['type'], "tun")) {
+ $ovpn_config .= "ifconfig {$server['lipaddr']} {$server['ripaddr']}\n";
+ $ovpn_config .= "route {$network} {$netmask}\n";
+ } else {
+ $ovpn_config .= "ifconfig {$server['lipaddr']} {$netmask}\n";
+ }
+
+ if (isset($server['client-to-client']))
+ $ovpn_config .= "push \"route {$network} {$netmask}\"\n";
+ else
+ $ovpn_config .= "push \"route {$server['lipaddr']}\"\n";
+
+ } /* end authentication_method */
+
+ $push_options = "";
- /* Duplicate CNs */
- if (isset($server['dupcn']))
- $ovpn_config .= "--duplicate-cn ";
-
/* Client push - redirect gateway */
- if (isset($server['psh_options']['redir'])){
+ if (isset($server['psh_options']['redir'])) {
if (isset($server['psh_options']['redir_loc']))
- $ovpn_config .= "--push \"redirect-gateway local\" ";
+ $push_config .= "push \"redirect-gateway local\"\n";
else
- $ovpn_config .= "--push \"redirect-gateway\" ";
+ $push_config .= "push \"redirect-gateway\"\n";
+ if ($server['method'] != "ovpn")
+ $push_config .= "push \"route-gateway {$server['ipblock']}\"\n";
}
-
+
/* Client push - route delay */
if (isset($server['psh_options']['rte_delay']))
- $ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay_int']}\" ";
-
+ $push_config .= "push \"route-delay {$server['psh_options']['rte_delay_int']}\"\n";
+
/* Client push - ping (note we set both server and client) */
if (isset ($server['psh_options']['ping'])){
$conflict = true;
$interval = $server['psh_options']['ping_int'];
- $ovpn_config .= "--ping {$server['psh_options']['ping_int']} ";
- $ovpn_config .= "--push \"ping {$server['psh_options']['ping_int']}\" ";
+ $ovpn_config .= "ping {$server['psh_options']['ping_int']}\n ";
+ $push_config .= "push \"ping {$server['psh_options']['ping_int']}\"\n";
}
-
+
/* Client push - ping-restart (note server uses 2 x client interval) */
if (isset ($server['psh_options']['pingrst'])){
$conflict = true;
$interval = $server['psh_options']['pingrst_int'];
- $ovpn_config .= "--ping-restart " . ($interval * 2) . " ";
- $ovpn_config .= "--push \"ping-restart $interval\" ";
+ $ovpn_config .= "ping-restart " . ($interval * 2) . "\n";
+ $push_config .= "push \"ping-restart $interval\"\n";
}
-
+
/* Client push - ping-exit (set on client) */
if (isset ($server['psh_options']['pingexit'])){
$conflict = true;
- $ovpn_config .= "--ping-exit {$server['psh_options']['pingexit_int']} ";
- $ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit_int']}\" ";
+ $ovpn_config .= "ping-exit {$server['psh_options']['pingexit_int']}\n";
+ $push_config .= "push \"ping-exit {$server['psh_options']['pingexit_int']}\"\n";
}
-
+
/* Client push - inactive (set on client) */
if (isset ($server['psh_options']['inact'])){
- $ovpn_config .= "--inactive {$server['psh_options']['inact_int']} ";
- $ovpn_config .= "--push \"inactive {$server['psh_options']['inact_int']}\" ";
+ $ovpn_config .= "inactive {$server['psh_options']['inact_int']}\n";
+ $push_config .= "push \"inactive {$server['psh_options']['inact_int']}\"\n";
}
-
+
+ if (isset($push_config))
+ $ovpn_config .= $push_config;
+
if (!isset($conflict))
- $ovpn_config .= "--keepalive 10 60 ";
+ $ovpn_config .= "keepalive 10 60\n";
+
+ /* Expert mode paramters */
+ if (isset($server['expertmode_enabled']) && is_array($server['expertmode'])) {
+ $ovpn_config .= ";begin expertmode\n";
+ foreach ($server['expertmode']['option'] as $option) {
+ $ovpn_config .= "{$option}\n";
+ }
+ $ovpn_config .= ";end expertmode\n";
+ }
+
+ fwrite($fd, $ovpn_config);
+ fclose($fd);
//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
- return $ovpn_config;
}
/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
function ovpn_server_iface(){
global $config, $g;
+
+ unset($filter_configure);
+ unset($bridge_configure);
foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
if (isset($server['enable'])) {
@@ -382,17 +455,31 @@ function ovpn_server_iface(){
&& ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
/* Already an interface defined - overwrite */
break;
- }
- else {
+ } else {
+
/* No existing entry, this is first unused */
$config['interfaces'][$ifname] = array();
+
+ /* add new filter rules */
+ $filter_configure = true;
break;
}
$i++;
}
- $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+ $config['interfaces'][$ifname]['descr'] = strtoupper($server['tun_iface']);
$config['interfaces'][$ifname]['if'] = $server['tun_iface'];
- $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
+ if ($server['method'] == "ovpn")
+ $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
+ else
+ $config['interfaces'][$ifname]['ipaddr'] = $server['ipblock'];
+ if (isset($server['bridge'])) {
+ $config['interfaces'][$ifname]['bridge'] = $server['bridge'];
+ $bridge_configure = true;
+ } else if (isset($config['interfaces'][$ifname]['bridge'])) {
+ /* bridge config removed */
+ unset ($config['interfaces'][$ifname]['bridge']);
+ $bridge_configure = true;
+ }
$config['interfaces'][$ifname]['subnet'] = $server['prefix'];
$config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
$config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
@@ -400,6 +487,13 @@ function ovpn_server_iface(){
write_config();
}
}
+
+ /* do we have to reconfigure filter rules? */
+ if (isset($bridge_configure))
+ interfaces_optional_configure();
+ else if (isset($filter_configure))
+ filter_configure();
+
return "OpenVPN server interface defined";
}
@@ -416,7 +510,6 @@ function ovpn_server_iface_del($tun) {
}
}
-
/* shift down other OPTn interfaces to get rid of holes */
$i++;
@@ -428,153 +521,339 @@ function ovpn_server_iface_del($tun) {
unset($config['interfaces']['opt' . $i]);
$i++;
}
+
+ /* reconfigure filter rules */
+ interfaces_optional_configure();
}
+/* Add client config file */
+function ovpn_server_ccd_add() {
+ global $config, $g;
-/****************************/
-/* Client related functions */
-/****************************/
+ if (is_array($config['ovpn']['server']['ccd'])) {
+ foreach ($config['ovpn']['server']['ccd'] as $id => $server) {
+ /* define configuration options */
+ ovpn_server_ccd_generate($id);
+ }
+ }
+}
-function getnxt_client_if($type) {
- /* find the first available device of type $type */
- global $config;
- $max = ($type == 'tun') ? 17 : 4;
- for ($i = 0; $i < $max; $i++) {
- $hit = false;
- foreach ($a_client as $client) {
- if ($client['if'] == $type . $i) {
- $hit = true;
- break;
- }
+
+/* Construct client config file */
+function ovpn_server_ccd_generate($id) {
+ global $config, $g;
+ $ovpnccd = $config['ovpn']['server']['ccd'][$id];
+
+ $cn = $ovpnccd['cn'];
+ $ccd_config = "";
+ $push_options = "";
+
+ /* Push reset */
+ if (!isset($ovpnccd['disable']) && isset($ovpnccd['psh_reset'])) {
+ $ccd_config .= "push-reset\n";
+
+ /* Client push - redirect gateway */
+ if (isset($ovpnccd['psh_options']['redir'])) {
+ if (isset($ovpnccd['psh_options']['redir_loc']))
+ $push_config .= "push \"redirect-gateway local\"\n";
+ else
+ $push_config .= "push \"redirect-gateway\"\n";
+ }
+
+ /* Client push - route delay */
+ if (isset($ovpnccd['psh_options']['rte_delay']))
+ $push_config .= "push \"route-delay {$ovpnccd['psh_options']['rte_delay_int']}\"\n";
+
+ /* Client push - ping (note we set both server and client) */
+ if (isset ($ovpnccd['psh_options']['ping'])){
+ $ccd_config .= "ping {$server['psh_options']['ping_int']}\n ";
+ $push_config .= "push \"ping {$ovpnccd['psh_options']['ping_int']}\"\n";
+ }
+
+ /* Client push - ping-restart (note server uses 2 x client interval) */
+ if (isset ($ovpnccd['psh_options']['pingrst'])){
+ $interval = $ovpnccd['psh_options']['pingrst_int'];
+ $ccd_config .= "ping-restart " . ($interval * 2) . "\n";
+ $push_config .= "push \"ping-restart $interval\"\n";
+ }
+
+ /* Client push - ping-exit (set on client) */
+ if (isset ($ovpnccd['psh_options']['pingexit'])){
+ $ccd_config .= "ping-exit {$ovpnccd['psh_options']['pingexit_int']}\n";
+ $push_config .= "push \"ping-exit {$ovpnccd['psh_options']['pingexit_int']}\"\n";
+ }
+
+ /* Client push - inactive (set on client) */
+ if (isset ($ovpnccd['psh_options']['inact'])){
+ $ccd_config .= "inactive {$ovpnccd['psh_options']['inact_int']}\n";
+ $push_config .= "push \"inactive {$ovpnccd['psh_options']['inact_int']}\"\n";
+ }
+
+ if (isset($push_config))
+ $ccd_config .= $push_config;
+ }
+
+ if (!isset($ovpnccd['disable']) && is_array($ovpnccd['options'])) {
+ foreach ($ovpnccd['options']['option'] as $option) {
+ $ccd_config .= "{$option}\n";
+ }
+ }
+
+ /* Disable client from connecting */
+ if (isset($ovpnccd['disable']))
+ $ccd_config = "disable\n";
+
+ unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
+
+ if (isset($ccd_config) && isset($ovpnccd['enable'])) {
+ $fd = fopen("{$g['vardb_path']}/ccd/{$cn}", "w");
+ if ($fd) {
+ fwrite($fd, $ccd_config."\n");
+ fclose($fd);
}
- if (!$hit)
- return $type . $i;
}
- return false;
}
-function getnxt_client_port() {
- /* Get first unused port */
- global $config;
- $a_client = $config['ovpn']['client']['tunnel'];
- $port = 1194;
- while (true) {
- $hit = false;
- foreach ($a_client as $client) {
- if ($client['port'] == $port) {
- $hit = true;
- break;
+/* Delete client config file */
+function ovpn_server_ccd_del($cn) {
+ global $g;
+
+ unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
+ return 0;
+}
+
+/* Add CRL file */
+function ovpn_server_crl_add() {
+ global $config, $g, $d_ovpncrldirty_path;
+
+ if (is_array($config['ovpn']['server']['crl'])) {
+ foreach ($config['ovpn']['server']['crl'] as $id => $crlent) {
+ /* get crl file name */
+ $name = $crlent['crlname'];
+
+ if (isset($crlent['enable'])) {
+
+ /* add file */
+ ovpn_server_crl_generate($id);
+
+ if ($g['booting']) {
+ /* next crl file */
+ continue;
+ }
+
+ /* read dirtyfile */
+ if (is_readable($d_ovpncrldirty_path))
+ $lines = file($d_ovpncrldirty_path);
+
+ /* reconfigure crl file */
+ if (is_array($lines) && in_array($name, $lines)) {
+
+ /* restart running openvpn daemon */
+ foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+ $tun = $server['tun_iface'];
+
+ if ($server['enable'] &&
+ isset($server['crlname']) && $server['crlname'] == $name)
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+ }
+
+ }
+
+ /* next crl file */
+ continue;
}
+
+ /* crl file disabled: remove file */
+ ovpn_server_crl_del($name);
}
- if (!$hit)
- if (!ovpn_port_inuse_server($port))
- return $port;
- $port++;
}
- return false; /* should never get here */
+ return 0;
}
-/* Port in use */
-function ovpn_port_inuse_client($port){
+/* Write CRL to file */
+function ovpn_server_crl_generate($id) {
+ global $config, $g;
+
+ $ovpncrl = $config['ovpn']['server']['crl'][$id];
+
+ $fd = fopen("{$g['vardb_path']}/{$ovpncrl['crlname']}.crl.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($ovpncrl['crl_list'])."\n");
+ fclose($fd);
+ }
+}
+
+/* Delete CRL file */
+function ovpn_server_crl_del($name) {
+ global $config, $g;
+
+ /* have to wipe out the crl from the server config */
+ foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+ if (isset($server['crlname']) && $server['crlname'] == $name) {
+
+ /* get tunnel interface */
+ $tun = $server['tun_iface'];
+
+ /* remove crl file entry */
+ unset($config['ovpn']['server']['tunnel'][$id]['crlname']);
+ write_config();
+
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_server_certs_del($tun);
+
+ /* reconfigure daemon */
+ ovpn_srv_config_generate($id);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+ }
+ }
+
+ unlink_if_exists("{$g['vardb_path']}/{$name}.crl.pem");
+ return 0;
+}
+
+
+/* Get a list of crl files */
+function ovpn_get_crl_list() {
global $config;
- $a_client = $config['ovpn']['client']['tunnel'];
- foreach ($a_client as $client) {
- if ($client['port'] == $port) {
- return true;
+
+ $crl_list = array();
+
+ if (is_array($config['ovpn']['server']['crl'])) {
+ foreach ($config['ovpn']['server']['crl'] as $crlent) {
+ if (isset($crlent['enable']))
+ $crl_list[] = $crlent['crlname'];
}
}
- return false;
+ return $crl_list;
+}
+
+/* append interface to $_ovpnsrvdirty_path */
+function ovpn_srv_dirty($tun) {
+ global $d_ovpnsrvdirty_path;
+
+ $fd = fopen($d_ovpnsrvdirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $tun);
+ fclose($fd);
+ }
}
+/* append file name to $_ovpncrldirty_path */
+function ovpn_crl_dirty($name) {
+ global $d_ovpncrldirty_path;
+
+ $fd = fopen($d_ovpncrldirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $name);
+ fclose($fd);
+ }
+}
+
+
+/****************************/
+/* Client related functions */
+/****************************/
+
function ovpn_config_client() {
/* Boot time configuration */
- global $config, $g;
+ global $config, $g, $d_ovpnclidirty_path;;
foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
/* get tunnel interface */
$tun = $client['if'];
- /* kill any running openvpn daemon */
- killbypid($g['varrun_path']."/ovpn_cli_{$tun}.pid");
-
if (isset($client['enable'])) {
-
- if ($g['booting'])
+
+ if ($g['booting']) {
echo "Starting OpenVPN client $id... ";
- /* Remove old certs & keys */
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
-
- /* Copy the TLS-Client certs & keys to disk */
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['ca_cert'])."\n");
- fclose($fd);
- }
- else
- trigger_error("OVPN: No open for CA", E_USER_NOTICE);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['cli_cert'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['cli_key'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
- fclose($fd);
- }
-
- /* Start openvpn for this client */
- mwexec("/usr/local/sbin/openvpn " . ovpn_cli_config_generate($id));
+ /* define configuration options */
+ ovpn_cli_config_generate($id);
+
+ /* Start openvpn for this client */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
- if ($g['booting'])
/* Send the boot message */
echo "done\n";
- }
- else {
- if (!$g['booting']){
- /* stop any processes, unload the tap module */
- /* Remove old certs & keys */
+
+ /* next client */
+ continue;
+ }
+
+ /* read dirtyfile */
+ if (is_readable($d_ovpnclidirty_path))
+ $lines = file($d_ovpnclidirty_path);
+
+ /* reconfigure client */
+ if (is_array($lines) && in_array($tun, $lines)) {
+
+ /* kill running client */
ovpn_client_kill($tun);
- if ($client['type'] == "tap")
- ovpn_unlink_tap();
+ /* remove old certs & keys */
+ ovpn_client_certs_del($tun);
+
+ /* define configuration options */
+ ovpn_cli_config_generate($id);
}
+
+ /* Start the openvpn daemon */
+ if (!is_readable("{$g['varrun_path']}/ovpn_cli_{$tun}.pid"))
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
+
+ /* next client */
+ continue;
+ }
+
+ /* client disabled */
+ if (!$g['booting']) {
+ /* kill running client */
+ ovpn_client_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_client_certs_del($tun);
+
+ /* stop any processes, unload the tap module */
+ //if ($client['type'] == "tap")
+ // ovpn_unlink_tap();
}
}
return 0;
-
}
/* Kill off a running client process */
-function ovpn_client_kill($tun) {
+function ovpn_client_certs_del($tun) {
global $g;
- killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
-
/* Remove old certs & keys */
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_cli_{$tun}.conf");
return 0;
}
+/* Kill off a running client process */
+function ovpn_client_kill($tun) {
+ global $g;
+
+ /* kill running client */
+ killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
+}
+
/* Generate the config for a OpenVPN client */
function ovpn_cli_config_generate($id) {
/* configure the named client */
@@ -583,65 +862,151 @@ function ovpn_cli_config_generate($id) {
/* get tunnel interface */
$tun = $client['if'];
-
+
/* get optional interface name */
$iface = ovpn_get_opt_interface($tun);
- /* Client support in 2.0 is very simple */
- $ovpn_config = "--client --daemon --verb 1 --status /var/log/openvpn_{$tun}.log 60 ";
-
- /* pid file */
- $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid ";
-
- /* interface */
- $ovpn_config .= "--dev {$client['if']} ";
-
- /* protocol */
- /* Set protocol being used (p = udp (default), tcp-client)
- if ($client['proto'] == 'tcp') {
- $ovpn_config .= "--proto tcp-client ";
+ /* Copy the TLS-Client certs & keys to disk */
+ if ($client['authentication_method'] != "pre_shared_key" ) {
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['ca_cert'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_cert'])."\n");
+ fclose($fd);
+ }
+
+ touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_key'])."\n");
+ fclose($fd);
+ }
}
-
- /* port */
- $ovpn_config .= "--lport {$client['port']} ";
-
- /* server location */
- $ovpn_config .= "--remote {$client['saddr']} {$client['sport']} ";
-
- /* bridging enabled? */
- if (($ifname = $config['interfaces'][$iface]['bridge']) && $client['type'] == "tap") {
- $lastdigits = substr($tun, 3) + 2;
- $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
- $fd = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
+ if ($client['authentication_method'] == "pre_shared_key" || isset($client['tlsauth'])) {
+ touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
if ($fd) {
- fwrite($fd, $ovpn_cli_up);
- fclose($fd);
- chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
- $ovpn_config .= "--up /var/etc/ovpn_cli_up_{$tun}.sh ";
+ fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
+ fclose($fd);
}
}
+ $fd = fopen("{$g['varetc_path']}/ovpn_cli_{$tun}.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open ovpn_cli_{$tun}.conf in ovpn_cli_config_generate($id).\n");
+ return 1;
+ }
+
+ /* Client support in 2.0 is very simple */
+ $ovpn_config = "";
+ $ovpn_config .= <<<EOD
+daemon
+verb 1
+status /var/log/openvpn_{$tun}.log 60
+writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid
+dev {$client['if']}
+lport {$client['cport']}
+remote {$client['saddr']} {$client['sport']}
+cipher {$client['crypto']}
+
+EOD;
+
+ /* Version 1.0 compatibility; http://openvpn.net/compat.html */
+ if ($client['ver'] != "2") {
+ $ovpn_config .= <<<EOD
+key-method 1
+tun-mtu 1500
+tun-mtu-extra 32
+mssfix 1450
+
+EOD;
+ }
+
+ /* Set protocol being used (p = udp (default), tcp-client) */
+ if ($client['proto'] == "tcp")
+ $ovpn_config .= "proto tcp-client\n";
+
/* TLS-Client params */
- $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem ";
- $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem ";
- $ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem ";
+ if ($client['authentication_method'] != "pre_shared_key") {
+ $ovpn_config .= <<<EOD
+ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem
+cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem
+key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem
- /* TLS auth */
- if (isset($client['tlsauth']))
- $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1 ";
+EOD;
- /* Data channel encryption cipher*/
- $ovpn_config .= "--cipher {$client['crypto']} ";
-
- //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
- return $ovpn_config;
+ if (isset($client['pull']))
+ $ovpn_config .= "client\n";
+ else
+ $ovpn_config .= "tls-client\n";
+
+ /* TLS auth */
+ if (isset($client['ns_cert_type']))
+ $ovpn_config .= "ns-cert-type server\n";
+
+ /* TLS auth */
+ if (isset($client['tlsauth']))
+ $ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1\n";
+
+ /* bridging enabled? */
+ if ($client['bridge'] && $client['type'] == "tap") {
+ $lastdigits = substr($tun, 3) + 2;
+ $ovpn_cli_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+ $fdo = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
+ if ($fdo) {
+ fwrite($fdo, $ovpn_cli_up);
+ fclose($fdo);
+ chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
+ $ovpn_config .= "up /var/etc/ovpn_cli_up_{$tun}.sh\n";
+ }
+ }
+
+ } else {
+ /* 'authentication_method' == "pre_shared_key" */
+ $ovpn_config .= "secret {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 0\n";
+
+ $network = gen_subnet($client['lipaddr'], $client['netmask']);
+ $netmask = gen_subnet_mask($client['netmask']);
+
+ if (strstr($client['type'], "tap"))
+ $ovpn_config .= "ifconfig {$client['lipaddr']} {$netmask}\n";
+ else
+ $ovpn_config .= "ifconfig {$client['lipaddr']} {$client['ripaddr']}\n";
+
+ } /* end authentication_method */
+
+ /* Expert mode paramters */
+ if (isset($client['expertmode_enabled']) && is_array($client['expertmode'])) {
+ $ovpn_config .= ";begin expertmode\n";
+ foreach ($client['expertmode']['option'] as $option) {
+ $ovpn_config .= "{$option}\n";
+ }
+ $ovpn_config .= ";end expertmode\n";
+ }
+
+ fwrite($fd, $ovpn_config);
+ fclose($fd);
+
+ /* trigger_error("OVPN: $ovpn_config", E_USER_NOTICE); */
}
/* Define an OVPN tunnel interface in the interfaces array for each client */
function ovpn_client_iface(){
global $config;
+ unset($filter_configure);
+ unset($bridge_configure);
+
foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
if (isset($client['enable'])) {
@@ -656,23 +1021,41 @@ function ovpn_client_iface(){
&& ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
/* Already an interface defined - overwrite */
break;
- }
- else {
+ } else {
+
/* No existing entry, this is first unused */
$config['interfaces'][$ifname] = array();
+
+ /* add new filter rules */
+ $filter_configure = true;
break;
}
$i++;
}
- $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+ $config['interfaces'][$ifname]['descr'] = strtoupper($client['if']);
$config['interfaces'][$ifname]['if'] = $client['if'];
$config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
$config['interfaces'][$ifname]['subnet'] = "0";
+ if (isset($client['bridge'])) {
+ $config['interfaces'][$ifname]['bridge'] = $client['bridge'];
+ $bridge_configure = true;
+ } else if (isset($config['interfaces'][$ifname]['bridge'])) {
+ /* bridge config removed */
+ unset ($config['interfaces'][$ifname]['bridge']);
+ $bridge_configure = true;
+ }
$config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
$config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
write_config();
}
}
+
+ /* do we have to reconfigure filter rules? */
+ if (isset($bridge_configure))
+ interfaces_optional_configure();
+ else if (isset($filter_configure))
+ filter_configure();
+
return "OpenVPN client interfaces defined";
}
@@ -689,7 +1072,6 @@ function ovpn_client_iface_del($tun) {
}
}
-
/* shift down other OPTn interfaces to get rid of holes */
$i++;
@@ -701,15 +1083,165 @@ function ovpn_client_iface_del($tun) {
unset($config['interfaces']['opt' . $i]);
$i++;
}
+
+ /* reconfigure filter rules */
+ interfaces_optional_configure();
+}
+
+/* append interface to ovpndirty_path */
+function ovpn_cli_dirty($tun) {
+ global $d_ovpnclidirty_path;
+
+ $fd = fopen($d_ovpnclidirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $tun);
+ fclose($fd);
+ }
}
/******************/
/* Misc functions */
+/******************/
+
+/* find the first available device of type $type */
+function getnxt_if($type) {
+ global $config;
+
+ /* initialize variables */
+ $iface_list = array();
+ $max = ($type == 'tun') ? 17 : 4;
+
+ /* construct list of valid interfaces */
+ for ($i = 0; $i < $max ; $i++)
+ array_push($iface_list, $type . $i);
+
+ /* delete interface in use from the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ $entry = array();
+ array_push($entry, $server['tun_iface']);
+ $iface_list = array_diff($iface_list, $entry);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ $entry = array();
+ array_push($entry, $client['if']);
+ $iface_list = array_diff($iface_list, $entry);
+ }
+ }
+
+ /* return first element of list, if list of interfaces isn't empty */
+ if (count($iface_list))
+ return array_shift($iface_list);
+ else
+ return false;
+}
+
+/* find the next best available port */
+function getnxt_port() {
+
+ /* construct list of valid ports */
+ $port_list = free_port_list();
+
+ /* return first element of list, if list of ports isn't empty */
+ if (count($port_list))
+ return array_shift($port_list);
+ else
+ return false;
+}
+
+/* construct list of free ports */
+function free_port_list() {
+ global $config;
+
+ /* initialize variables */
+ $port_list = array();
+ $first_port = 1194;
+ $max = $first_port + 21;
+
+ for ($i = $first_port; $i < $max; $i++)
+ array_push($port_list, $i);
+
+ /* delete port in use from the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ $entry = array();
+ array_push($entry, $server['port']);
+ $port_list = array_diff($port_list, $entry);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ $entry = array();
+ array_push($entry, $client['cport']);
+ $port_list = array_diff($port_list, $entry);
+ }
+ }
+
+ return $port_list;
+}
+
+/* construct list of used ports */
+function used_port_list() {
+ global $config;
+
+ /* initialize variables */
+ $port_list = array();
+
+ /* add used ports to the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if (isset($server['enable']))
+ array_push($port_list, $server['port']);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ if (isset($client['enable']))
+ array_push($port_list, $client['cport']);
+ }
+ }
+
+ return $port_list;
+}
+
+/* construct list of bindings used for a specified port */
+function used_bind_list($port) {
+ global $config;
+
+ /* initialize variables */
+ $bind_list = array();
+
+ /* add used bindings to the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if (isset($server['enable']) && $server['port'] == $port)
+ array_push($bind_list, $server['bind_iface']);
+ }
+ }
+
+ /* client daemon always binds to 0.0.0.0 */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ if (isset($client['enable']) && $client['cport'] == $port)
+ array_push($bind_list, "all");
+ }
+ }
+
+ /* return list of bindings */
+ return $bind_list;
+}
/* Calculate the last address in a range given the start and /prefix */
function ovpn_calc_end($start, $prefix){
-
$first = ip2long($start);
$last = pow(2,(32 - $prefix)) - 1 + $first;
return long2ip($last);
@@ -717,17 +1249,17 @@ function ovpn_calc_end($start, $prefix){
/* Calculate a mask given a /prefix */
function ovpn_calc_mask($prefix){
-
return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
}
/* Port in use */
function ovpn_port_inuse_server($port){
global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- foreach ($a_server as $server) {
- if ($server['port'] == $port) {
- return true;
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if ($server['port'] == $port) {
+ return true;
+ }
}
}
return false;
@@ -824,6 +1356,83 @@ function ovpn_real_interface_list(){
return $interfaces;
}
+/* called by interfaces_opt.php */
+function ovpn_ccd_sort() {
+ global $g, $config;
+
+ function ccdcmp($a, $b) {
+ return strcmp($a['cn'][0], $b['cn'][0]);
+ }
+
+ usort($config['ovpn']['server']['ccd'], "ccdcmp");
+
+}
+
+/* called by interfaces_opt.php */
+function ovpn_config_post() {
+ global $_POST, $optcfg, $pconfig;
+
+ unset($input_errors);
+
+ /* bridge check */
+ if ($_POST['bridge'] && strstr($optcfg['if'], "tun"))
+ $input_errors[] = "Bridging a tun interface isn't possible.";
+
+ if (($_POST['enable'] && !isset($optcfg['enable'])) || (!$_POST['enable'] && isset($optcfg['enable'])))
+ $input_errors[] = "Enabling or disabling a tunneling interface isn't supported on this page.";
+
+ if ($_POST['ipaddr'] != $optcfg['ipaddr'])
+ $input_errors[] = "Changing the IP address of a tunneling interfaces isn't supported on this page.";
+
+ if ($_POST['subnet'] != $optcfg['subnet'])
+ $input_errors[] = "Changing the subnet mask of a tunneling interfaces isn't supported on this page.";
+
+ if ($input_errors) {
+ $pconfig['ipaddr'] = $optcfg['ipaddr'];
+ $pconfig['subnet'] = $optcfg['subnet'];
+ $pconfig['bridge'] = $optcfg['bridge'];
+ $pconfig['enable'] = isset($optcfg['enable']);
+ }
+
+ return $input_errors;
+}
+
+function check_bridging($bridge) {
+ global $config;
+ unset($input_errors);
+
+ /* double bridging? */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index) {
+ if ($config['interfaces']['opt' . $i]['bridge'] == $bridge) {
+ $input_errors = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "the specified interface.";
+ } else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
+ $input_errors = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "this interface.";
+ }
+ }
+ }
+
+ if ($config['interfaces'][$bridge]['bridge'])
+ $input_errors = "The specified interface is already bridged to another interface.";
+
+ return $input_errors;
+}
+
+/*
+function is_specialnet($net) {
+ $specialsrcdst = explode(" ", "lan");
+
+ if (in_array($net, $specialsrcdst))
+ return true;
+ else
+ return false;
+}
+*/
+
/* lock openvpn information, decide that the lock file is stale after
10 seconds */
OpenPOWER on IntegriCloud