1) $input_errors[] = "Maximum number of simultaneous clients should not be greater than \"1\"."; /* checked also by javascript */ if ($_POST['method'] != "static") $input_errors[] = "Only static address assignment is supported."; } else { /* rsa */ $reqdfields = array_merge($reqdfields, explode(" ", "ca_cert srv_cert srv_key dh_param")); $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "CA certificate,Server certificate,Server key,DH parameters")); if ($_POST['type'] == "tap") { /* tap*/ if (!$_POST['bridge']) { if ($_POST['method'] == "ovpn") { $reqdfields = array_merge($reqdfields, "ipblock"); $reqdfieldsn = array_merge($reqdfieldsn, "IP address block"); $check_ipblock = 1; } else { $input_errors[] = "Only supported address assignment is \"Managed by OpenVPN\"."; } } else { if ($_POST['method'] == "ovpn") { $reqdfields = array_merge($reqdfields, explode(" ", "range_from range_to gateway")); $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Range begin,Range end,Gateway")); if (intval($_POST['maxcli']) > (ip2long($_POST['range_to']) - ip2long($_POST['range_from']) + 1)) $input_errors[] = "IP range to small for maximum number of simultaneous clients."; } else if ($_POST['method'] != "dhcp") { $input_errors[] = "Wrong or emtpy OpenVPN address assignment."; } } } else { /* tun*/ $reqdfields = array_merge($reqdfields, "ipblock"); $reqdfieldsn = array_merge($reqdfieldsn, "IP address block"); /* checked also by javascript */ if ($_POST['method'] != "ovpn") $input_errors[] = "Only supported address assignment is \"Managed by OpenVPN\"."; $check_ipblock = 1; } /* valid IP */ if ($_POST['ipblock'] && $check_ipblock) { if (!is_ipaddr($_POST['ipblock'])) { $input_errors[] = "A valid IP netblock must be specified."; } else if ($_POST['type'] == "tun" && intval($_POST['prefix']) > 29) { $input_errors[] = "Network mask too high for tun-style tunnels."; } else { $network = ip2long(gen_subnet($_POST['ipblock'], $_POST['prefix'])); $broadcast = ip2long(gen_subnet_max($_POST['ipblock'], $_POST['prefix'])); if ($_POST['maxcli']) { if ($_POST['type'] == "tap") { if (intval($_POST['maxcli']) > ($broadcast - $network - 3)) $input_errors[] = "Maximum number of simultaneous clients too high"; } else { if (intval($_POST['maxcli']) > floor(($broadcast - $network) / 4)) $input_errors[] = "Maximum number of simultaneous clients too high"; } } } } /* Sort out the cert+key files */ if (!empty($_POST['ca_cert']) && (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))) $input_errors[] = "The CA certificate does not appear to be valid."; if (!empty($_POST['srv_cert']) && (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['srv_cert'], "END CERTIFICATE"))) $input_errors[] = "The server certificate does not appear to be valid."; if (!empty($_POST['srv_key']) && (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['srv_key'], "END RSA PRIVATE KEY"))) $input_errors[] = "The server key does not appear to be valid."; if (!empty($_POST['dh_param']) && (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") || !strstr($_POST['dh_param'], "END DH PARAMETERS"))) $input_errors[] = "The DH parameters do not appear to be valid."; if (isset($_POST['tlsauth']) && empty($_POST['pre-shared-key'])) $input_errors[] = "The field 'Pre-shared secret' is required."; } do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); if (($_POST['range_from'] && !is_ipaddr($_POST['range_from']))) $input_errors[] = "A valid range must be specified."; if (($_POST['range_to'] && !is_ipaddr($_POST['range_to']))) $input_errors[] = "A valid range must be specified."; if ($_POST['gateway'] && !is_ipaddr($_POST['gateway'])) $input_errors[] = "A valid gateway IP address must be specified."; /* make sure the range lies within the bridged subnet */ if ($_POST['bridge']) { if ($_POST['method'] == "ovpn") { $ipaddr = $config['interfaces'][$_POST['bridge']]['ipaddr']; $subnet = $config['interfaces'][$_POST['bridge']]['subnet']; $subnet_start = (ip2long($ipaddr) & gen_subnet_mask_long($subnet)); $subnet_end = (ip2long($ipaddr) | (~gen_subnet_mask_long($subnet))); if (!ip_in_subnet($_POST['gateway'], gen_subnet($ipaddr, $subnet) . "/" . $subnet)) $input_errors[] = "The specified gateway lies outside of the bridged subnet."; if ((ip2long($_POST['range_from']) < $subnet_start) || (ip2long($_POST['range_from']) > $subnet_end) || (ip2long($_POST['range_to']) < $subnet_start) || (ip2long($_POST['range_to']) > $subnet_end)) { $input_errors[] = "The specified range lies outside of the bridged subnet."; } if (ip2long($_POST['range_from']) > ip2long($_POST['range_to'])) $input_errors[] = "The range is invalid (first element higher than second element)."; } } /* valid Port */ if (empty($_POST['port'])) $input_errors[] = "You must provide a server in between 1 and 65535."; else if (!is_port($_POST['port'])) $input_errors[] = "The server port must be an integer between 1 and 65535."; /* check if dynip is set correctly */ if ($_POST['dynip'] && $_POST['bind_iface'] != 'all') $input_errors[] = "Dynamic IP address can only be set with interface binding set to ALL."; if (!empty($_POST['pre-shared-key'])) if (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") || !strstr($_POST['pre-shared-key'], "END OpenVPN Static key")) $input_errors[] = "Pre-shared secret does not appear to be valid."; if ($_POST['psh_pingrst'] && $_POST['psh_pingexit']) $input_errors[] = "Ping-restart and Ping-exit are mutually exclusive and cannot be used together"; if ($_POST['psh_rtedelay'] && !is_numeric($_POST['psh_rtedelay_int'])) $input_errors[] = "Route-delay needs a numerical interval setting."; if ($_POST['psh_inact'] && !is_numeric($_POST['psh_inact_int'])) $input_errors[] = "Inactive needs a numerical interval setting."; if ($_POST['psh_ping'] && !is_numeric($_POST['psh_ping_int'])) $input_errors[] = "Ping needs a numerical interval setting."; if ($_POST['psh_pingexit'] && !is_numeric($_POST['psh_pingexit_int'])) $input_errors[] = "Ping-exit needs a numerical interval setting."; if ($_POST['psh_pingrst'] && !is_numeric($_POST['psh_pingrst_int'])) $input_errors[] = "Ping-restart needs a numerical interval setting."; /* Editing an existing entry? */ if (isset($id) && $ovpnsrv[$id]) { $ovpnent = $ovpnsrv[$id]; /* bridging changed */ if ($ovpnent['bridge'] != $_POST['bridge']) { /* double bridging? */ if ($_POST['bridge'] && $_POST['type'] == "tap" && $_POST['authentication_method'] == "rsasig") $retval = check_bridging($_POST['bridge']); if (!empty($retval)) $input_errors[] = $retval; } /* port number syntactically valid, so lets check, if it is free */ if (isset($ovpnent['enable']) && !isset($_POST['disabled']) && $ovpnent['port'] != $_POST['port']) { /* port number has changed */ if (in_array($_POST['port'], used_port_list())) { /* port in use, check binding */ /* return interfaces bind to this port */ $bind_list = used_bind_list($_POST['port']); /* check if binding is in use */ if (($_POST['bind_iface'] == "all") || in_array("all", $bind_list) || in_array($_POST['bind_iface'], $bind_list) ) { $input_errors[] = "OpenVPN binding already in use by another OpenVPN daemon."; } } } /* binding free? */ if (isset($ovpnent['enable']) && !isset($_POST['disabled']) && $ovpnent['bind_iface'] != $_POST['bind_iface']) { /* binding has changed, remove existing old entry from list */ $entry = array(); array_push($entry, $ovpnent['bind_iface']); $bind_list = array_diff(used_bind_list($_POST['port']), $entry); if (count($bind_list)) { if ($_POST['bind_iface'] == "all") $input_errors[] = "Interface binding is already in use."; else if (in_array("all", $bind_list) || in_array($_POST['bind_iface'], $bind_list)) $input_errors[] = "Interface binding is already in use."; } } /* Test Server type hasn't changed */ if ($ovpnent['type'] != $_POST['type']) { $input_errors[] = "Delete this interface first before changing the type of the tunnel to " . strtoupper($_POST['type']) ."."; } /* status changed to enable */ if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) { /* check if port number is free */ if (in_array($_POST['port'], used_port_list())) { /* port in use, check binding */ /* return interfaces bind to this port */ $bind_list = used_bind_list($_POST['port']); if (($_POST['bind_iface'] == "all") || in_array("all", $bind_list ) || in_array($_POST['bind_iface'], $bind_list) ) { /* binding in use */ $input_errors[] = "OpenVPN binding already in use by another OpenVPN daemon."; } } } } else { /* Creating a new entry */ $ovpnent = array(); /* port number syntactically valid, so lets check, if it is free */ if ($_POST['port']) { /* new port number */ $bind_list = used_bind_list($_POST['port']); if (in_array($_POST['port'], used_port_list())) { /* port in use, check binding */ if (($_POST['bind_iface'] == "all") || in_array("all", $bind_list ) || in_array($_POST['bind_iface'], $bind_list) ) { /* binding in use */ $input_errors[] = "Port {$_POST['port']} is already used for another interface."; } } } if (!($ovpnent['tun_iface'] = getnxt_if($_POST['type']))) $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}"; /* double bridging? */ if ($ovpnent['bridge'] != $_POST['bridge']) { /* double bridging? */ if ($_POST['bridge'] && $_POST['type'] == "tap" && $_POST['authentication_method'] == "rsasig") $retval = check_bridging($_POST['bridge']); if (!empty($retval)) $input_errors[] = $retval; } } if (!$input_errors) { $ovpnent['enable'] = isset($_POST['disabled']) ? false : true; $ovpnent['bind_iface'] = $_POST['bind_iface']; $ovpnent['port'] = $_POST['port']; $ovpnent['proto'] = $_POST['proto']; $ovpnent['type'] = $_POST['type']; $ovpnent['method'] = $_POST['method']; $ovpnent['authentication_method'] = $_POST['authentication_method']; /* convert IP address block to a correct network IP address */ $ovpnent['ipblock'] = gen_subnet($_POST['ipblock'], $_POST['prefix']); $ovpnent['prefix'] = $_POST['prefix']; $ovpnent['lipaddr'] = $_POST['lipaddr']; $ovpnent['ripaddr'] = $_POST['ripaddr']; $ovpnent['netmask'] = $_POST['netmask']; $ovpnent['range_from'] = $_POST['range_from']; $ovpnent['range_to'] = $_POST['range_to']; $ovpnent['gateway'] = $_POST['gateway']; $ovpnent['bridge'] = $_POST['bridge']; $ovpnent['descr'] = $_POST['descr']; $ovpnent['verb'] = $_POST['verb']; $ovpnent['maxcli'] = $_POST['maxcli']; $ovpnent['crypto'] = $_POST['crypto']; $ovpnent['comp_method'] = $_POST['comp_method']; $ovpnent['cli2cli'] = $_POST['cli2cli'] ? true : false; $ovpnent['dupcn'] = $_POST['dupcn'] ? true : false; $ovpnent['dynip'] = $_POST['dynip'] ? true : false; $ovpnent['tlsauth'] = $_POST['tlsauth'] ? true : false; $ovpnent['crlname'] = $_POST['crlname']; unset($ovpnent['pre-shared-key']); if ($_POST['pre-shared-key']) $ovpnent['pre-shared-key'] = base64_encode($_POST['pre-shared-key']); $ovpnent['psh_options']['redir'] = $_POST['psh_redir'] ? true : false; $ovpnent['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false; $ovpnent['psh_options']['rtedelay'] = $_POST['psh_rtedelay'] ? true : false; $ovpnent['psh_options']['inact'] = $_POST['psh_inact'] ? true : false; $ovpnent['psh_options']['ping'] = $_POST['psh_ping'] ? true : false; $ovpnent['psh_options']['pingrst'] = $_POST['psh_pingrst'] ? true : false; $ovpnent['psh_options']['pingexit'] = $_POST['psh_pingexit'] ? true : false; unset($ovpnent['psh_options']['rtedelay_int']); unset($ovpnent['psh_options']['inact_int']); unset($ovpnent['psh_options']['ping_int']); unset($ovpnent['psh_options']['pingrst_int']); unset($ovpnent['psh_options']['pingexit_int']); if ($_POST['psh_rtedelay_int']) $ovpnent['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int']; if ($_POST['psh_inact_int']) $ovpnent['psh_options']['inact_int'] = $_POST['psh_inact_int']; if ($_POST['psh_ping_int']) $ovpnent['psh_options']['ping_int'] = $_POST['psh_ping_int']; if ($_POST['psh_pingrst_int']) $ovpnent['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int']; if ($_POST['psh_pingexit_int']) $ovpnent['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int']; $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']); $ovpnent['srv_cert'] = base64_encode($_POST['srv_cert']); $ovpnent['srv_key'] = base64_encode($_POST['srv_key']); $ovpnent['dh_param'] = base64_encode($_POST['dh_param']); /* expertmode params */ $ovpnent['expertmode_enabled'] = $_POST['expertmode_enabled'] ? true : false; if (!is_array($options)) $options = array(); if (!is_array($ovpnent['expertmode'])) $ovpnent['expertmode'] = array(); $options['option'] = array_map('trim', explode("\n", trim($_POST['expertmode_options']))); $ovpnent['expertmode'] = $options; if (isset($id) && $ovpnsrv[$id]) $ovpnsrv[$id] = $ovpnent; else $ovpnsrv[] = $ovpnent; write_config(); ovpn_srv_dirty($ovpnent['tun_iface']); header("Location: vpn_openvpn_srv.php"); exit; } else { $pconfig = $_POST; $pconfig['enable'] = "true"; if (isset($_POST['disabled'])) unset($pconfig['enable']); $pconfig['pre-shared-key'] = base64_encode($_POST['pre-shared-key']); $pconfig['ca_cert'] = base64_encode($_POST['ca_cert']); $pconfig['srv_cert'] = base64_encode($_POST['srv_cert']); $pconfig['srv_key'] = base64_encode($_POST['srv_key']); $pconfig['dh_param'] = base64_encode($_POST['dh_param']); $pconfig['psh_options']['redir'] = $_POST['psh_redir']; $pconfig['psh_options']['redir_loc'] = $_POST['psh_redir_loc']; $pconfig['psh_options']['rtedelay'] = $_POST['psh_rtedelay']; $pconfig['psh_options']['inact'] = $_POST['psh_inact']; $pconfig['psh_options']['ping'] = $_POST['psh_ping']; $pconfig['psh_options']['pingrst'] = $_POST['psh_pingrst']; $pconfig['psh_options']['pingexit'] = $_POST['psh_pingexit']; $pconfig['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int']; $pconfig['psh_options']['inact_int'] = $_POST['psh_inact_int']; $pconfig['psh_options']['ping_int'] = $_POST['psh_ping_int']; $pconfig['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int']; $pconfig['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int']; } } $pgtitle = array("VPN","OpenVPN","Edit server"); include("head.inc"); ?>
WARNING: This feature is experimental and modifies your optional interface configuration. Backup your configuration before using OpenVPN, and restore it before upgrading.
 
Disabled > Disable this server
Set this option to disable this server without removing it from the list.
OpenVPN protocol/port > UDP  > TCP

Port:
Enter the port number to use for the server (default is 1194).
Interface binding
Choose an interface for the OpenVPN server to listen on.
Dynamic IP address > Dynamic IP address
Set this option to on, if your IP addresses are being assigned dynamically. Can only be used with interface binding set to ALL.
Description
You may enter a description here for your reference (not parsed).
Cryptographic options
Authentication method
Must match the setting chosen on the remote side.
CA certificate
Paste a CA certificate in X.509 PEM format here.
Server certificate
Paste a server certificate in X.509 PEM format here.
Server key
Paste the server RSA private key here.
DH parameters
Paste the Diffie-Hellman parameters in PEM format here.
Crypto
Select a data channel encryption cipher.
TLS auth onclick="tls_change(false)"> TLS auth
The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification.
Pre-shared secret
Paste your own pre-shared secret here.
CRL
You can choose a CRL (certificate revocation list) file in PEM format here. Each peer certificate is checked against this file.
IP configuration
Tunnel type > TUN  > TAP
Bridge with
Only supported with authentication method set to RSA signature.
OpenVPN address assignment
> Managed by OpenVPN
> Configure manually or by DHCP Server
> Static assignment
   
Maximum number of simultaneous clients:  
(leave blank to disable)
When using OpenVPN for address assignment, set aside a pool of subnets to be dynamically allocated to connecting clients, similar to a DHCP server.

For tun-style tunnels, each client will be given a /30 subnet (for interoperability with Windows clients).
For tap-style tunnels, individual addresses will be allocated, and the optional netmask parameter will also be pushed to clients.

IP address block:   /
For bridges interfaces OpenVPN will allocate an IP range in the bridged subnet to connecting clients.

The gateway and netmask parameters can be set to either the IP of the bridge interface, or to the IP of the default gateway/router on the bridged subnet.

Range:    to 
Gateway:  
  When using pre-shared keys, enter the IP address and subnet mask of the local and remote VPN endpoint here. For TAP devices, only the IP address of the local VPN endpoint is needed. The netmask is the subnet mask of the virtual ethernet segment which is being created or connected to.

Local IP address:   /
Remote IP address:  
Server Options
Internal routing mode > Enable client-to-client routing
If this option is on, clients are allowed to talk to each other.
Client authentication > Permit duplicate client certificates
If this option is on, clients with duplicate certificates will not be disconnected.
Compression method
Choose which compression method to use.

LZO compression generally improves performance on slow links, but may add up to 1 byte per packet for incompressible data.

With adaptive compression, OpenVPN will periodically sample the compression process to measure its efficiency. If the data being sent over the tunnel is already compressed, the compression efficiency will be very low. Choose 'LZO (no adaptive)' to disable OpenVPN's adaptive compression algorithm.
Client-push options
> Redirect-gateway   > Local
> Route-delay   seconds
> Inactive   seconds
> Ping   Interval: seconds
> Ping-exit   Interval: seconds
> Ping-restart   Interval: seconds
Expert mode > Enable expert OpenVPN mode
If this option is on, you can specify your own extra commands for the OpenVPN server.
Note:
Commands in expert mode aren't supported.