From 1ab6bdb5ffcf052241f58af87efef9fe077b38c7 Mon Sep 17 00:00:00 2001 From: jim-p Date: Tue, 8 Nov 2011 16:57:32 -0500 Subject: [PATCH] Fix up OpenVPN server tap modes, support various options for providing or passing through DHCP. (Work in progress) --- etc/inc/openvpn.inc | 36 ++++-- usr/local/www/vpn_openvpn_server.php | 160 +++++++++++++++++++++++++-- 2 files changed, 179 insertions(+), 17 deletions(-) diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc index fb0b98ff0e..ab30200248 100644 --- a/etc/inc/openvpn.inc +++ b/etc/inc/openvpn.inc @@ -409,23 +409,41 @@ function openvpn_reconfigure($mode, $settings) { // If the CIDR is less than a /30, OpenVPN will complain if you try to // use the server directive. It works for a single client without it. // See ticket #1417 - if ($cidr < 30) { + if (($settings['dev_mode'] != "tap") && ($cidr < 30)) { $conf .= "server {$ip} {$mask}\n"; $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; } case 'p2p_shared_key': - $baselong = ip2long32($ip) & ip2long($mask); - $ip1 = long2ip32($baselong + 1); - $ip2 = long2ip32($baselong + 2); - $conf .= "ifconfig $ip1 $ip2\n"; + if ($settings['dev_mode'] != "tap") { + $baselong = ip2long32($ip) & ip2long($mask); + $ip1 = long2ip32($baselong + 1); + $ip2 = long2ip32($baselong + 2); + $conf .= "ifconfig $ip1 $ip2\n"; + } break; case 'server_tls': case 'server_user': case 'server_tls_user': - $conf .= "server {$ip} {$mask}\n"; - if(is_ipaddr($ipv6)) - $conf .= "server-ipv6 {$ipv6}/{$prefix}\n"; - $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; + if ($settings['dev_mode'] != "tap") { + $conf .= "server {$ip} {$mask}\n"; + if(is_ipaddr($ipv6)) + $conf .= "server-ipv6 {$ipv6}/{$prefix}\n"; + $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; + } else { + if ($settings['serverbridge_dhcp']) { + if ((!empty($settings['serverbridge_interface'])) && (strcmp($settings['serverbridge_interface'], "none"))) { + $biface_ip=get_interface_ip($settings['serverbridge_interface']); + $biface_sm=gen_subnet_mask(get_interface_subnet($settings['serverbridge_interface'])); + if (is_ipaddrv4($biface_ip) && is_ipaddrv4($settings['serverbridge_dhcp_start']) && is_ipaddrv4($settings['serverbridge_dhcp_end'])) { + $conf .= "server-bridge {$biface_ip} {$biface_sm} {$settings['serverbridge_dhcp_start']} {$settings['serverbridge_dhcp_end']}\n"; + } else { + $conf .= "mode server\n"; + } + } else { + $conf .= "mode server\n"; + } + } + } break; } diff --git a/usr/local/www/vpn_openvpn_server.php b/usr/local/www/vpn_openvpn_server.php index a166048c12..be1255c0f3 100644 --- a/usr/local/www/vpn_openvpn_server.php +++ b/usr/local/www/vpn_openvpn_server.php @@ -137,6 +137,7 @@ if($_GET['act']=="edit"){ $pconfig['tunnel_network'] = $a_server[$id]['tunnel_network']; $pconfig['tunnel_networkv6'] = $a_server[$id]['tunnel_networkv6']; + $pconfig['remote_network'] = $a_server[$id]['remote_network']; $pconfig['gwredir'] = $a_server[$id]['gwredir']; $pconfig['local_network'] = $a_server[$id]['local_network']; @@ -149,6 +150,11 @@ if($_GET['act']=="edit"){ $pconfig['dynamic_ip'] = $a_server[$id]['dynamic_ip']; $pconfig['pool_enable'] = $a_server[$id]['pool_enable']; + $pconfig['serverbridge_dhcp'] = $a_server[$id]['serverbridge_dhcp']; + $pconfig['serverbridge_interface'] = $a_server[$id]['serverbridge_interface']; + $pconfig['serverbridge_dhcp_start'] = $a_server[$id]['serverbridge_dhcp_start']; + $pconfig['serverbridge_dhcp_end'] = $a_server[$id]['serverbridge_dhcp_end']; + $pconfig['dns_domain'] = $a_server[$id]['dns_domain']; if ($pconfig['dns_domain']) $pconfig['dns_domain_enable'] = true; @@ -190,7 +196,6 @@ if($_GET['act']=="edit"){ $pconfig['duplicate_cn'] = isset($a_server[$id]['duplicate_cn']); } } - if ($_POST) { unset($input_errors); @@ -286,9 +291,20 @@ if ($_POST) { $reqdfieldsn = array(gettext('Shared key')); } - $reqdfields[] = 'tunnel_network'; - $reqdfieldsn[] = gettext('Tunnel network'); - + if ($pconfig['dev_mode'] != "tap") { + $reqdfields[] = 'tunnel_network'; + $reqdfieldsn[] = gettext('Tunnel network'); + } else { + if (($pconfig['serverbridge_dhcp_start'] && !$pconfig['serverbridge_dhcp_end']) + || (!$pconfig['serverbridge_dhcp_start'] && $pconfig['serverbridge_dhcp_end'])) + $input_errors[] = gettext("Server Bridge DHCP Start and End must both be empty, or defined."); + if (($pconfig['serverbridge_dhcp_start'] && !is_ipaddrv4($pconfig['serverbridge_dhcp_start']))) + $input_errors[] = gettext("Server Bridge DHCP Start must be an IPv4 address."); + if (($pconfig['serverbridge_dhcp_end'] && !is_ipaddrv4($pconfig['serverbridge_dhcp_end']))) + $input_errors[] = gettext("Server Bridge DHCP End must be an IPv4 address."); + if (ip2ulong($pconfig['serverbridge_dhcp_start']) > ip2ulong($pconfig['serverbridge_dhcp_end'])) + $input_errors[] = gettext("The Server Bridge DHCP range is invalid (start higher than end)."); + } do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); if (!$input_errors) { @@ -345,6 +361,11 @@ if ($_POST) { $server['dynamic_ip'] = $pconfig['dynamic_ip']; $server['pool_enable'] = $pconfig['pool_enable']; + $server['serverbridge_dhcp'] = $pconfig['serverbridge_dhcp']; + $server['serverbridge_interface'] = $pconfig['serverbridge_interface']; + $server['serverbridge_dhcp_start'] = $pconfig['serverbridge_dhcp_start']; + $server['serverbridge_dhcp_end'] = $pconfig['serverbridge_dhcp_end']; + if ($pconfig['dns_domain_enable']) $server['dns_domain'] = $pconfig['dns_domain']; @@ -563,6 +584,58 @@ function netbios_change() { } } +function tuntap_change() { + + mindex = document.iform.mode.selectedIndex; + mvalue = document.iform.mode.options[mindex].value; + + switch(mvalue) { + case "p2p_tls": + case "p2p_shared_key": + p2p = true; + break; + default: + p2p = false; + break; + } + + index = document.iform.dev_mode.selectedIndex; + value = document.iform.dev_mode.options[index].value; + switch(value) { + case "tun": + document.getElementById("ipv4_tunnel_network").style.display=""; + document.getElementById("ipv6_tunnel_network").style.display=""; + document.getElementById("serverbridge_dhcp").style.display="none"; + document.getElementById("serverbridge_interface").style.display="none"; + document.getElementById("serverbridge_dhcp_start").style.display="none"; + document.getElementById("serverbridge_dhcp_end").style.display="none"; + break; + case "tap": + document.getElementById("ipv4_tunnel_network").style.display="none"; + document.getElementById("ipv6_tunnel_network").style.display="none"; + if (!p2p) { + document.getElementById("serverbridge_dhcp").style.display=""; + document.getElementById("serverbridge_interface").style.display=""; + document.getElementById("serverbridge_dhcp_start").style.display=""; + document.getElementById("serverbridge_dhcp_end").style.display=""; + if (document.iform.serverbridge_dhcp.checked) { + document.iform.serverbridge_interface.disabled = false; + document.iform.serverbridge_dhcp_start.disabled = false; + document.iform.serverbridge_dhcp_end.disabled = false; + } else { + document.iform.serverbridge_interface.disabled = true; + document.iform.serverbridge_dhcp_start.disabled = true; + document.iform.serverbridge_dhcp_end.disabled = true; + } + } else { + document.iform.serverbridge_dhcp.disabled = true; + document.iform.serverbridge_interface.disabled = true; + document.iform.serverbridge_dhcp_start.disabled = true; + document.iform.serverbridge_dhcp_end.disabled = true; + } + break; + } +} //--> - $desc): $selected = ""; @@ -670,7 +743,7 @@ if ($savemsg) - - + @@ -993,7 +1066,7 @@ if ($savemsg) "to connecting clients. (see Address Pool)"); ?> - + @@ -1007,6 +1080,76 @@ if ($savemsg) "to connecting clients. (see Address Pool)"); ?> + + + + + + + + +
+ + onchange='tuntap_change()' /> + + +
+
+
+ + + + + +
+ + + + + + + +
+ + + + + + + +
+ + + @@ -1518,6 +1661,7 @@ dns_server_change(); wins_server_change(); ntp_server_change(); netbios_change(); +tuntap_change(); //-->