From 979cd6db9c6a81493498660f7205faabf25ed6ec Mon Sep 17 00:00:00 2001 From: Scott Ullrich Date: Mon, 17 Dec 2007 00:30:54 +0000 Subject: Adding dnswatch support. Obtained-from: m0n0wall --- etc/inc/util.inc | 19 ++ etc/inc/vpn.inc | 924 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 576 insertions(+), 367 deletions(-) diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 487efed..7c46eac 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -555,4 +555,23 @@ function mac_format($clientmac) { } } +function resolve_retry($hostname, $retries = 5) { + + if (is_ipaddr($hostname)) + return $hostname; + + for ($i = 0; $i < $retries; $i++) { + $ip = gethostbyname($hostname); + + if ($ip && $ip != $hostname) { + /* success */ + return $ip; + } + + sleep(1); + } + + return false; +} + ?> \ No newline at end of file diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index a984c5b..2c30acf 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -1,7 +1,8 @@ "") - foreach($config['installedpackages']['sasyncd']['config'] as $sasyncd) { - $enabled = isset($sasyncd['enable']); - if(!$enabled) + if ($config['installedpackages']['sasyncd'] <> "") + foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) { + $enabled = isset ($sasyncd['enable']); + if (!$enabled) return; - if($sasyncd['peerip'] <> "") + if ($sasyncd['peerip'] <> "") $sasyncd_text .= "peer {$sasyncd['peerip']}\n"; - if($sasyncd['interface']) + if ($sasyncd['interface']) $sasyncd_text .= "carp interface {$sasyncd['interface']}\n"; - if($sasyncd['sharedkey'] <> "") + if ($sasyncd['sharedkey'] <> "") $sasyncd_text .= "sharedkey {$sasyncd['sharedkey']}\n"; - if($sasyncd['mode'] <> "") + if ($sasyncd['mode'] <> "") $sasyncd_text .= "mode {$sasyncd['mode']}\n"; - if($sasyncd['listenon'] <> "") + if ($sasyncd['listenon'] <> "") $sasyncd_text .= "listen on {$sasyncd['listenon']}\n"; - if($sasyncd['flushmodesync'] <> "") + if ($sasyncd['flushmodesync'] <> "") $sasyncd_text .= "flushmode sync {$sasyncd['flushmodesync']}\n"; } @@ -74,40 +78,39 @@ function vpn_ipsec_failover_configure() { mwexec("killall sasyncd"); /* launch sasyncd, oh wise one */ - /* mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v"); */ + mwexec_bg("/usr/local/sbin/sasyncd -d -v -v -v"); } function find_last_gif_device() { - $regs = ""; - $last_gif_found = -1; - if (!($fp = popen("/sbin/ifconfig -l", "r"))) return -1; - $ifconfig_data = fread($fp, 4096); - pclose($fp); - $ifconfig_array = split(" ", $ifconfig_data); - foreach ($ifconfig_array as $ifconfig) { - ereg("gif(.)", $ifconfig, $regs); - if($regs[0]) { - if($regs[0] > $last_gif_found) - $last_gif_found = $regs[1]; - } - } - return $last_gif_found; + $last_gif_found = -1; + $regs = ""; + if (!($fp = popen("/sbin/ifconfig -l", "r"))) + return -1; + $ifconfig_data = fread($fp, 4096); + pclose($fp); + $ifconfig_array = split(" ", $ifconfig_data); + foreach ($ifconfig_array as $ifconfig) { + ereg("gif(.)", $ifconfig, $regs); + if ($regs[0] && $regs[0] > $last_gif_found) { + $last_gif_found = $regs[1]; + } + } + return $last_gif_found; } function vpn_ipsec_configure($ipchg = false) { global $config, $g, $sa, $sn; - mwexec("/sbin/ifconfig enc0 create"); mwexec("/sbin/ifconfig enc0 up"); /* get the automatic /etc/ping_hosts.sh ready */ unlink_if_exists("/var/db/ipsecpinghosts"); touch("/var/db/ipsecpinghosts"); - if($g['booting'] == true) { + if ($g['booting'] == true) { /* determine if we should load the via padlock module */ - $dmesg_boot = `cat /var/log/dmesg.boot | grep CPU`; - if(stristr($dmesg_boot, "ACE") == true) { + $dmesg_boot = `/usr/bin/grep CPU {$g['varlog_path']}/dmesg.boot`; + if (stristr($dmesg_boot, "ACE") == true) { //echo "Enabling [VIA Padlock] ..."; //mwexec("/sbin/kldload padlock"); //mwexec("/sbin/sysctl net.inet.ipsec.crypto_support=1"); @@ -124,7 +127,7 @@ function vpn_ipsec_configure($ipchg = false) { } $number_of_gifs = find_last_gif_device(); - for($x=0; $x<$number_of_gifs; $x++) { + for ($x = 0; $x < $number_of_gifs; $x++) { mwexec("/sbin/ifconfig gif" . $x . " delete"); } @@ -137,14 +140,16 @@ function vpn_ipsec_configure($ipchg = false) { $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']); $lansn = $lancfg['subnet']; + if (!isset($ipseccfg['enable'])) { mwexec("/sbin/ifconfig enc0 down"); mwexec("/sbin/ifconfig enc0 destroy"); /* kill racoon */ mwexec("/usr/bin/killall racoon"); - - /* wait for process to die */ + killbypid("{$g['varrun_path']}/dnswatch-ipsec.pid"); + + /* wait for racoon process to die */ sleep(2); /* send a SIGKILL to be sure */ @@ -161,10 +166,9 @@ function vpn_ipsec_configure($ipchg = false) { echo "Configuring IPsec VPN... "; } - if (isset($ipseccfg['enable'])) { - + if (isset ($ipseccfg['enable'])) { /* fastforwarding is not compatible with ipsec tunnels */ - system("/sbin/sysctl net.inet.ip.fastforwarding=0 >/dev/null 2>&1"); + mwexec("/sbin/sysctl net.inet.ip.fastforwarding=0"); if (!$curwanip) { /* IP address not configured yet, exit */ @@ -174,10 +178,12 @@ function vpn_ipsec_configure($ipchg = false) { } if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) || - isset($ipseccfg['mobileclients']['enable'])) { - + isset ($ipseccfg['mobileclients']['enable'])) { + + $dnswatch_list = array(); + $rgmap = array(); + if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) { - /* generate spd.conf */ $fd = fopen("{$g['varetc_path']}/spd.conf", "w"); if (!$fd) { @@ -191,21 +197,32 @@ function vpn_ipsec_configure($ipchg = false) { $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; foreach ($ipseccfg['tunnel'] as $tunnel) { - - if (isset($tunnel['disabled'])) + if (isset ($tunnel['disabled'])) continue; + /* see if this tunnel has a hostname for the remote-gateway, and if so, + try to resolve it now and add it to the list for dnswatch */ + if (!is_ipaddr($tunnel['remote-gateway'])) { + $dnswatch_list[] = $tunnel['remote-gateway']; + $rgip = resolve_retry($tunnel['remote-gateway']); + + if (!$rgip) + continue; + + } else { + $rgip = $tunnel['remote-gateway']; + } + $rgmap[$tunnel['remote-gateway']] = $rgip; + $ep = vpn_endpoint_determine($tunnel, $curwanip); - if (!$ep) { - log_error("Could not deterimine VPN endpoint for {$tunnel['descr']}"); - continue; - } + if (!$ep) + continue; vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn); - if(is_domain($tunnel['remote-gateway'])) { + if (is_domain($tunnel['remote-gateway'])) { $tmp = gethostbyname($tunnel['remote-gateway']); - if($tmp) + if ($tmp) $tunnel['remote-gateway'] = $tmp; } @@ -225,31 +242,28 @@ function vpn_ipsec_configure($ipchg = false) { fclose($pfd); } - if(isset($tunnel['creategif'])) { + if (isset ($tunnel['creategif'])) { $number_of_gifs = find_last_gif_device(); $number_of_gifs++; $curwanip = get_current_wan_address(); - + if ($config['installedpackages']['sasyncd']['config'] <> "") + foreach ($config['installedpackages']['sasyncd']['config'] as $sasyncd) { + if ($sasyncd['ip'] <> "") + $curwanip = $sasyncd['ip']; + } mwexec("/sbin/ifconfig gif" . $number_of_gifs . " tunnel" . $curwanip . " " . $tunnel['remote-gateway']); mwexec("/sbin/ifconfig gif" . $number_of_gifs . " {$lansa}/{$lansn} {$lanip}/32"); } $spdconf .= "spdadd {$sa}/{$sn} " . - "{$tunnel['remote-subnet']} any -P out ipsec " . - "{$tunnel['p2']['protocol']}/tunnel/{$ep}-" . - "{$tunnel['remote-gateway']}/unique;\n"; + "{$tunnel['remote-subnet']} any -P out ipsec " . + "{$tunnel['p2']['protocol']}/tunnel/{$ep}-" . + "{$rgip}/unique;\n"; $spdconf .= "spdadd {$tunnel['remote-subnet']} " . - "{$sa}/{$sn} any -P in ipsec " . - "{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" . - "{$ep}/unique;\n"; - - if($tunnel['interface'] <> "wan") { - /* static route needed? */ - if(strstr("carp", $tunnel['interface'])) { - - } - } + "{$sa}/{$sn} any -P in ipsec " . + "{$tunnel['p2']['protocol']}/tunnel/{$rgip}-" . + "{$ep}/unique;\n"; } fwrite($fd, $spdconf); @@ -272,11 +286,11 @@ function vpn_ipsec_configure($ipchg = false) { $cacertnum = 0; if (is_array($ipseccfg['cacert']) && count($ipseccfg['cacert'])) foreach ($ipseccfg['cacert'] as $cacert) { - ++$cacertnum; - if (isset($cacert['cert'])) { + ++ $cacertnum; + if (isset ($cacert['cert'])) { $cert = base64_decode($cacert['cert']); $x509cert = openssl_x509_parse(openssl_x509_read($cert)); - if(is_array($x509cert) && isset($x509cert['hash'])) { + if (is_array($x509cert) && isset ($x509cert['hash'])) { $fd1 = fopen("{$g['varetc_path']}/{$x509cert['hash']}.0", "w"); if (!$fd1) { printf("Error: cannot open {$x509cert['hash']}.0 in vpn.\n"); @@ -293,108 +307,118 @@ function vpn_ipsec_configure($ipchg = false) { if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) foreach ($ipseccfg['tunnel'] as $tunnel) { - ++$tunnelnumber; - - if (isset($tunnel['disabled'])) - continue; + ++ $tunnelnumber; - $ep = vpn_endpoint_determine($tunnel, $curwanip); - if (!$ep) - continue; + if (isset ($tunnel['disabled'])) + continue; - vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn); - if (isset($tunnel['p1']['myident']['myaddress'])) { - $myidentt = "address"; - $myident = $ep; - } else if (isset($tunnel['p1']['myident']['address'])) { - $myidentt = "address"; - $myident = $tunnel['p1']['myident']['address']; - } else if (isset($tunnel['p1']['myident']['fqdn'])) { - $myidentt = "fqdn"; - $myident = $tunnel['p1']['myident']['fqdn']; - } else if (isset($tunnel['p1']['myident']['ufqdn'])) { - $myidentt = "user_fqdn"; - $myident = $tunnel['p1']['myident']['ufqdn']; - } else if (isset($tunnel['p1']['myident']['asn1dn'])) { - $myidentt = "asn1dn"; - $myident = $tunnel['p1']['myident']['asn1dn']; - } else if (isset($tunnel['p1']['myident']['dyn_dns'])) { - $myidentt = "dyn_dns"; - $myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']); - } - - $nattline = ''; - if (isset($tunnel['natt'])) { - $nattline = "nat_traversal on;"; - } + $rgip = $rgmap[$tunnel['remote-gateway']]; + if (!$rgip) + continue; - if (isset($tunnel['p1']['authentication_method'])) { - $authmethod = $tunnel['p1']['authentication_method']; - } else {$authmethod = 'pre_shared_key';} + $ep = vpn_endpoint_determine($tunnel, $curwanip); + if (!$ep) + continue; - $certline = ''; + vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn); - if ($authmethod == 'rsasig') { - if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) { - $cert = base64_decode($tunnel['p1']['cert']); - $private_key = base64_decode($tunnel['p1']['private-key']); - } else { - /* null certificate/key */ - $cert = ''; - $private_key = ''; + if (isset ($tunnel['p1']['myident']['myaddress'])) { + $myidentt = "address"; + $myident = $ep; + } elseif (isset ($tunnel['p1']['myident']['address'])) { + $myidentt = "address"; + $myident = $tunnel['p1']['myident']['address']; + } elseif (isset ($tunnel['p1']['myident']['fqdn'])) { + $myidentt = "fqdn"; + $myident = $tunnel['p1']['myident']['fqdn']; + } elseif (isset ($tunnel['p1']['myident']['ufqdn'])) { + $myidentt = "user_fqdn"; + $myident = $tunnel['p1']['myident']['ufqdn']; + } else if (isset($tunnel['p1']['myident']['asn1dn'])) { + $myidentt = "asn1dn"; + $myident = $tunnel['p1']['myident']['asn1dn']; + } else if (isset($tunnel['p1']['myident']['asn1dn'])) { + $myidentt = "asn1dn"; + $myident = $tunnel['p1']['myident']['asn1dn']; + } elseif (isset ($tunnel['p1']['myident']['dyn_dns'])) { + $myidentt = "dyn_dns"; + $myident = gethostbyname($tunnel['p1']['myident']['dyn_dns']); } - if ($tunnel['p1']['peercert']) - $peercert = base64_decode($tunnel['p1']['peercert']); - else - $peercert = ''; - - $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w"); - if (!$fd1) { - printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n"); - return 1; + $nattline = ''; + if (isset($tunnel['natt'])) { + $nattline = "nat_traversal on;"; } - chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600); - fwrite($fd1, $cert); - fclose($fd1); - $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w"); - if (!$fd1) { - printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n"); - return 1; + if (isset ($tunnel['p1']['authentication_method'])) { + $authmethod = $tunnel['p1']['authentication_method']; + } else { + $authmethod = 'pre_shared_key'; } - chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600); - fwrite($fd1, $private_key); - fclose($fd1); - $certline = "certificate_type x509 \"server{$tunnelnumber}-signed.pem\" \"server{$tunnelnumber}-key.pem\";"; + $certline = ''; + + if ($authmethod == 'rsasig') { + if ($tunnel['p1']['cert'] && $tunnel['p1']['private-key']) { + $cert = base64_decode($tunnel['p1']['cert']); + $private_key = base64_decode($tunnel['p1']['private-key']); + } else { + /* null certificate/key */ + $cert = ''; + $private_key = ''; + } - if ($peercert!=''){ - $fd1 = fopen("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", "w"); + if ($tunnel['p1']['peercert']) + $peercert = base64_decode($tunnel['p1']['peercert']); + else + $peercert = ''; + + $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", "w"); if (!$fd1) { printf("Error: cannot open server{$tunnelnumber}-signed.pem in vpn.\n"); return 1; } - chmod("{$g['varetc_path']}/peer{$tunnelnumber}-signed.pem", 0600); - fwrite($fd1, $peercert); + chmod("{$g['varetc_path']}/server{$tunnelnumber}-signed.pem", 0600); + fwrite($fd1, $cert); + fclose($fd1); + + $fd1 = fopen("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", "w"); + if (!$fd1) { + printf("Error: cannot open server{$tunnelnumber}-key.pem in vpn.\n"); + return 1; + } + chmod("{$g['varetc_path']}/server{$tunnelnumber}-key.pem", 0600); + fwrite($fd1, $private_key); fclose($fd1); - $certline .= << 0) { + $interval = 60; + if ($ipseccfg['dns-interval']) + $interval = $ipseccfg['dns-interval']; + + $hostnames = ""; + foreach ($dnswatch_list as $dns) + $hostnames .= " " . escapeshellarg($dns); + + mwexec("/usr/local/bin/dnswatch {$g['varrun_path']}/dnswatch-ipsec.pid $interval " . + escapeshellarg("/etc/rc.newipsecdns") . $hostnames); + } + } + + if (is_array($ipseccfg['tunnel'])) { + foreach ($ipseccfg['tunnel'] as $tunnel) { + if (isset ($tunnel['auto'])) { + $remotehost = substr($tunnel['remote-subnet'], 0, strpos($tunnel['remote-subnet'], "/")); + $srchost = vpn_endpoint_determine($tunnel, $curwanip); + if ($srchost) + mwexec_bg("/sbin/ping -c 10 -S {$srchost} {$remotehost}"); + } + } } } } @@ -621,7 +675,7 @@ function vpn_pptpd_configure() { $syscfg = $config['system']; $pptpdcfg = $config['pptpd']; - $starting_ng = get_number_of_wan_netgraph_interfaces_needed(); + $starting_ng = get_number_of_wan_netgraph_interfaces_needed(); if ($g['booting']) { if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off")) @@ -630,81 +684,73 @@ function vpn_pptpd_configure() { echo "Configuring PPTP VPN service... "; } else { /* kill mpd */ - killbypid("{$g['varrun_path']}/mpd-pptpd.pid"); + killbypid("{$g['varrun_path']}/mpd-vpn.pid"); /* wait for process to die */ sleep(3); - if (is_process_running("mpd4 -b")) { - killbypid("{$g['varrun_path']}/mpd-pptpd.pid"); + if (is_process_running("mpd -b")) { + killbypid("{$g['varrun_path']}/mpd-vpn.pid"); log_error("Could not kill mpd within 3 seconds. Trying again."); } /* remove mpd.conf, if it exists */ - unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.conf"); - unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.links"); - unlink_if_exists("{$g['varetc_path']}/mpd-pptpd/mpd.secret"); + unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf"); + unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links"); + unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret"); } /* make sure mpd-vpn directory exists */ - if (!file_exists("{$g['varetc_path']}/mpd-pptpd")) - mkdir("{$g['varetc_path']}/mpd-pptpd"); + if (!file_exists("{$g['varetc_path']}/mpd-vpn")) + mkdir("{$g['varetc_path']}/mpd-vpn"); switch ($pptpdcfg['mode']) { - - case 'server': - + case 'server' : /* write mpd.conf */ - $fd = fopen("{$g['varetc_path']}/mpd-pptpd/mpd.conf", "w"); + $fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w"); if (!$fd) { printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n"); return 1; } - $mpdconf = << +?> \ No newline at end of file -- cgit v1.1