Usar rotas de VPN como backup no pfSense
-
as funções que gravam a configuração e aplicam os filtros estão todas juntas
write_config();
e as demais.
Dá uma olhada neste pedaço de código do dansguardian.
Nele eu vefico os valores do array e salvo caso haja alterações$count=0; if (is_array($config['installedpackages']['dansguardianphraseacl']['config'])) foreach($config['installedpackages']['dansguardianphraseacl']['config'] as $dansguardian_phrase){ #bannedphraselist if($dansguardian_phrase['banned_phraselist'] == "" && file_exists ($dansguardian_dir.'/lists/bannedphraselist.sample')){ $config['installedpackages']['dansguardianphraseacl']['config'][$count]['banned_phraselist']=base64_encode(file_get_contents($dansguardian_dir.'/lists/bannedphraselist.sample')); $load_samples++; } $includes=preg_replace($match,$replace,$dansguardian_phrase['banned_includes']); file_put_contents($dansguardian_dir."/lists/bannedphraselist.".$dansguardian_phrase['name'],($dansguardian_phrase['banned_enabled']?dg_text_area_decode($config['installedpackages']['dansguardianphraseacl']['config'][$count]['banned_phraselist']).$includes:""),LOCK_EX); #weightedphraselist if($dansguardian_phrase['weighted_phraselist'] == "" && file_exists ($dansguardian_dir.'/lists/weightedphraselist.sample')){ $config['installedpackages']['dansguardianphraseacl']['config'][$count]['weighted_phraselist']=base64_encode(file_get_contents($dansguardian_dir.'/lists/weightedphraselist.sample')); $load_samples++; } $includes=preg_replace($match,$replace,$dansguardian_phrase['weighted_includes']); file_put_contents($dansguardian_dir."/lists/weightedphraselist.".$dansguardian_phrase['name'],($dansguardian_phrase['weighted_enabled']?dg_text_area_decode($config['installedpackages']['dansguardianphraseacl']['config'][$count]['weighted_phraselist']).$includes:""),LOCK_EX); #exceptionphraselist if($dansguardian_phrase['exception_phraselist'] == "" && file_exists ($dansguardian_dir.'/lists/exceptionphraselist.sample')){ $config['installedpackages']['dansguardianphraseacl']['config'][$count]['exception_phraselist']=base64_encode(file_get_contents($dansguardian_dir.'/lists/exceptionphraselist.sample')); $load_samples++; } file_put_contents($dansguardian_dir."/lists/exceptionphraselist.".$dansguardian_phrase['name'],($dansguardian_phrase['exception_enabled']?dg_text_area_decode($config['installedpackages']['dansguardianphraseacl']['config'][$count]['exception_phraselist']):""),LOCK_EX); $count++; } if($load_samples > 0) write_config();
-
Meu código não está muito diferente na verdade está bem simples veja!
```
print "link online, disabling Tunnel\n";
//unset ($config['ipsec']['enable']);
$a_phase1 = $config['ipsec']['phase1'];
$p1index = $VPN_ID;
$a_phase1[$p1index]['disabled']=true;
//print "\nVPNID: ".$VPN_ID;
//print "\nHOST: ".$host;
//print "\nPhase1: ".$ph1ent['disabled'];
//print "\nPhase2: ".$ph2ent['disabled'];
write_config();
vpn_ipsec_configure();
vpn_ipsec_refresh_policies();
filter_configure(); -
Esse código executa sem dar erro nenhum, mas também não faz nada!
-
Já saquei, você esta alterando sua variável $a_phase1 e não a $config['ipsec']['phase1']
você tem duas opções, atribuir de volta o $a_phase1 para $config['ipsec']['phase1']
$config['ipsec']['phase1']=$a_phase1;
write_config();
.
.
.ou fazer o loop direto no array como te mostrei no exemplo do dansguardian.
Termine o loop antes de salvar as configurações, é mais saudável. :)
E é claro, sempre faça backup do seu xml antes de começar a programar.
-
Cara to quase lá, estou conseguindo desligar a phase 1 do tunnel sem problema nenhum, já a fase 2 fiz um código que funcionou, daí fui tentar melhorar o código e parou de funcionar de vez!
Segue abaixo o novo trecho de código, esse codigo desliga a phase 1 que escolho, mas não desliga a phase2!
Por que tenho que desligar a fase 1 e 2: porque se desligo apenas a fase 1 o pfsense não desativa as politicas SPD e a rota continua bagunçada, se desligo a fase 2 e 1 aí da certo!
require_once("util.inc"); require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); require_once("filter.inc"); require_once("shaper.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); $ipsec=$config['ipsec']; $VPN_ID=array_pop($argv); $a_phase1 = &$config['ipsec']['phase1']; $a_phase2 = &$config['ipsec']['phase2']; $ikeid = $a_phase1[$VPN_ID]['ikeid']; //print_r(array_values($a_phase2)); $host=array_pop($argv); if (! is_ipaddr($host)){ print "invalid ip address!\n"; exit(1); } array_shift($argv); $args=implode(" ", $argv); exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit1); if ($exit1 == 0) exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit2); if ($exit2 == 0) exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit3); $exit = ($exit1 + $exit2 + $exit3); if ($exit == 0){ #link online if (array_key_exists("enable",$ipsec)){ print "link online, disabling Tunnel\n"; //unset ($config['ipsec']['enable']); $a_phase1[$VPN_ID]['disabled']=""; //write_config(); if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as $phase2) { if ($phase2['ikeid'] == $ikeid) { $a_phase2['disabled']=""; print "\n**************\n"; print_r(array_values($a_phase2)); //write_config(); } } } write_config(); vpn_ipsec_configure(); vpn_ipsec_refresh_policies(); filter_configure();
-
Neste ponto não seria o unset para sumir com a variavel disabled?
//unset ($config['ipsec']['enable']); $a_phase1[$VPN_ID]['disabled']="";
-
Não Marcelo, na verdade a variável disabled não existe por padrao. Quando eu marco a caixa na interface ele cria o valor no array!
De toda maneira deixa eu te adiantar meu progresso.
Consegui arrumar tudo e agora está tudo funcionando, eu consigo desativar a fase 1 e a fase 2 passando por parametro o número da VPN que quero desativar, no caso começa em 0 as políticas e vai aumentando de 1 em 1 as seguintes.
O problema agora está no fato de mesmo fazendo tudo isso as políticas de SPD criadas não estão sumindo, só somem se eu desligar o ipsec salvar e ligar novamente. Acho que essa solução é muito porca então estou tentando descobrir qual a função que recarrega os SPD's e chamar do nosso script.
require_once("util.inc"); require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); require_once("filter.inc"); require_once("shaper.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); $ipsec=$config['ipsec']; $VPN_ID=array_pop($argv); $a_phase1 = &$config['ipsec']['phase1']; $a_phase2 = &$config['ipsec']['phase2']; $ikeid = $a_phase1[$VPN_ID]['ikeid']; //print_r(array_values($a_phase2)); $host=array_pop($argv); if (! is_ipaddr($host)){ print "invalid ip address!\n"; exit(1); } array_shift($argv); $args=implode(" ", $argv); exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit1); if ($exit1 == 0) exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit2); if ($exit2 == 0) exec("/sbin/ping -c 1 -t 1 $args $host",$ret,$exit3); $exit = ($exit1 + $exit2 + $exit3); if ($exit == 0){ #link online if (array_key_exists("enable",$ipsec)){ print "link online, disabling Tunnel\n"; //unset ($config['ipsec']['enable']); $a_phase1[$VPN_ID]['disabled']=""; //write_config(); if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { $phase2['disabled']=""; //print "\n**************\n"; //print_r(array_values($a_phase2)); //write_config(); } } } vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); //reload_tunnel_spd_policy($a_phase1, $a_phase2, $a_phase1, $a_phase2); write_config(); filter_configure(); } else print "link online\n"; } else{ if (! array_key_exists("enable",$ipsec)){ print "link offline, enabling ipsec\n"; $config['ipsec']['enable']=""; write_config(); vpn_ipsec_configure(); vpn_ipsec_refresh_policies(); filter_configure(); } else print "link offline\n"; } ?>
-
ok.
Ainda estou envolvido com o dansguardian, posso te ajudar quando terminar.
uma dica para publicar códigos, é usar o botão # (code). Assim fica mais fácil analisar o post.
-
Beleza, enquanto isso vou continuar tentando por aqui. Obrigado pela dica do code!
-
Olá Marcelloc gostaria de dizer que depois de muita briga consegui resolver totalmente o meu problema. Estou postando abaixo o script que gerei em PHP para ativar e/ou desativer os túneis IPSec individualmente apagando as políticas SPD quando necessário e servindo de maneira excelente para utilizar o tunel VPN como backup caso o link dedicado de comunicação de empresas pare de funcionar.
Obviamente que se tiver sugestões de melhoria por favor fique a vontade para fazer e melhorar o script. Este é o meu primeir script totalmente funcional para o pfSense, então testem em ambientes de homologação antes de colocar em produção!
Abraço a todos e Marcelloc, muito obrigado pelo script inicial que gerou esse aqui, sem ele nada disso seria possível.
exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit1); if ($exit1 == 0) exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit2); if ($exit2 == 0) exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit3); $exit = ($exit1 + $exit2 + $exit3); if ($exit == 0){ #link online if (! isset($a_phase1[$VPN_ID]['disabled'])) { print "Link online, Disabling Tunnel!\n"; $a_phase1[$VPN_ID]['disabled']=""; if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { $phase2['disabled']=""; } } } write_config(); /* flush SPD and SAD */ mwexec("/usr/local/sbin/setkey -F"); mwexec("/usr/local/sbin/setkey -FP"); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); } else print "Link online, Tunnel already Disabled!\n"; } else{ if (isset($a_phase1[$VPN_ID]['disabled'])){ print "Link offline, Enabling Tunnel!\n"; unset ($a_phase1[$VPN_ID]['disabled']); if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { unset ($phase2['disabled']); } } } write_config(); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); } else print "Link offline, Tunnel already Enabled!\n"; } ?>
-
Foi mal, no último post o script saiu pela metade, segue agora o script completo!
/* check_mpls.php Este script tem como funcao habilitar ou desabilitar tuneis de VPN para serem usados como backup em caso de falhas em linhas dedicadas ou links ponto-a-ponto. Este script deve ser instalado no diretorio /usr/local/www, ter permisao de execucao e devera ser chamado atraves do cron na peridiocidade desejada. O script recebe como parametro o IP de origem para determinar a interface pela qual o teste sera realizado, o IP de destino que sera verificado se esta on-line ou n## e o nummero da VPN. No caso o numero da VPN e obtido contando-se apenas os itens de Fase 1 na configuracao do IPSec do pfSense de cima para baixo comecando do 0. Exemplo: php -q /usr/local/www/check_mpls.php <ip de="" origem=""> <ip a="" ser="" testado=""> <numero da="" vpn="" ipsec=""> php -q /usr/local/www/check_mpls.php 192.168.0.1 192.168.10.3 0 */ require_once("util.inc"); require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); require_once("filter.inc"); require_once("shaper.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); $VPN_ID=array_pop($argv); $a_phase1 = &$config['ipsec']['phase1']; $a_phase2 = &$config['ipsec']['phase2']; $ikeid = $a_phase1[$VPN_ID]['ikeid']; $host=array_pop($argv); if (! is_ipaddr($host)){ print "invalid ip address!\n"; exit(1); } array_shift($argv); $args=implode(" ", $argv); exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit1); if ($exit1 == 0) exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit2); if ($exit2 == 0) exec("/sbin/ping -c 1 -t 1 -S $args $host",$ret,$exit3); $exit = ($exit1 + $exit2 + $exit3); if ($exit == 0){ #link online if (! isset($a_phase1[$VPN_ID]['disabled'])) { print "Link online, Disabling Tunnel!\n"; $a_phase1[$VPN_ID]['disabled']=""; if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { $phase2['disabled']=""; } } } write_config(); /* flush SPD and SAD */ mwexec("/usr/local/sbin/setkey -F"); mwexec("/usr/local/sbin/setkey -FP"); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); } else print "Link online, Tunnel already Disabled!\n"; } else{ if (isset($a_phase1[$VPN_ID]['disabled'])){ print "Link offline, Enabling Tunnel!\n"; unset ($a_phase1[$VPN_ID]['disabled']); if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { unset ($phase2['disabled']); } } } write_config(); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); } else print "Link offline, Tunnel already Enabled!\n"; } ?></numero></ip></ip>
-
Boa noite
Sei que é pedir muito mas tem como montar um tutorial para a instalação e configuração do IPSEC?
abs
e desde já agradeço
Souza Linux
-
Souzalinux,
Você já olhou estes tutoriais aqui do forum
http://forum.pfsense.org/index.php/topic,44270.msg229704.html#msg229704 -
vlw
irei montar o laboratorio para teste amanhã com 2 pfsense
obrigado
-
Andei aperfeiçoando o script ontem e hoje para diminuir ao máximo o uso de processamento do servidor e realmente só fazer as alterações no pfSense quando realmente for necessário, evitando assim dores de cabeça.
Também deixei o script todo comentado para facilitar o entendimento do mesmo. Novamente gostaria de ressaltar que sugestões são bem vindas para melhorar este script ok!
Abraço a todos!
/* check_mpls.php Versao 1.1 Este script tem como funcao habilitar ou desabilitar tuneis de VPN para serem usados como backup em caso de falhas em linhas dedicadas ou links ponto-a-ponto. Este script deve ser instalado no diretorio /usr/local/www, ter permisao de execucao e devera ser chamado atraves do cron na peridiocidade desejada. O script recebe como parametro o IP de origem para determinar a interface pela qual o teste sera realizado, o IP de destino que sera verificado se esta on-line ou n## e o nummero da VPN. No caso o numero da VPN e obtido contando-se apenas os itens de Fase 1 na configuracao do IPSec do pfSense de cima para baixo comecando do 0. Exemplo: php -q /usr/local/www/check_mpls.php <ip de="" origem=""><ip a="" ser="" testado=""><numero da="" vpn="" ipsec="">php -q /usr/local/www/check_mpls.php 192.168.0.1 192.168.10.3 0 */ require_once("util.inc"); require_once("functions.inc"); require_once("pkg-utils.inc"); require_once("globals.inc"); require_once("filter.inc"); require_once("shaper.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); /* Pega o ultimo parametro informado na chamada, e armazena na variavel $VPN_ID */ $VPN_ID=array_pop($argv); /* Pega o IP de destino informado e checa se e valido, se sim continua o programa */ $dsthost=array_pop($argv); if (! is_ipaddr($dsthost)){ print "Invalid Destination IP address!\n"; exit(1); } /* Pega o IP de origem informado e checa se e valido, se sim continua o programa */ $srchost=array_pop($argv); if (! is_ipaddr($srchost)){ print "Invalid Source IP address!\n"; exit(1); } /* Verifica se o IPSec esta ligado no pfSense, se sim continua o programa */ $ipsec=&$config['ipsec']; if (! isset($ipsec['enable'])) { exit(1); } /* Armazena as configuracoes das fases 1 e 2 do IPSec nas variaveis e verifica se a VPN informada existe ou nao */ $a_phase1 = &$config['ipsec']['phase1']; $a_phase2 = &$config['ipsec']['phase2']; if (isset($a_phase1[$VPN_ID]['ikeid'])) { $ikeid = $a_phase1[$VPN_ID]['ikeid']; } else { print "VPN Tunnel didn't exist!\n"; exit(1); } /* Determina a quantidade de pings que serao realizados, o tunel sera ativado se a quantdade de erros for maior ou igual a 50% desse valor */ $qtdping=10; $exit=0; for ($i=1; $i<=$qtdping; $i++) { exec("/sbin/ping -c 1 -t 1 -S $srchost $dsthost",$ret,$exit1); if ($exit1 <> 0) { $exit=$exit+1; } } /* Se a quantidade for menor que 50% o link esta online, se a VPN estiver ativada sera desligada, caso contrario imprime a mensagem informativa e encerra o programa. */ if ($exit < ($qtdping/2)) { #link online if (! isset($a_phase1[$VPN_ID]['disabled'])) { print "Link online, Disabling Tunnel!\n"; $a_phase1[$VPN_ID]['disabled']=""; if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { $phase2['disabled']=""; } } unset($phase2); } write_config(); /* flush SPD and SAD */ mwexec("/usr/local/sbin/setkey -F"); mwexec("/usr/local/sbin/setkey -FP"); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); exit(0); } else { print "Link online, Tunnel already Disabled!\n"; exit(0); } } /* Se a quantidade de erros for maior ou igual a 50% o link esta offline, então a VPN sera ativada. Caso ela ja esteja ligada, imprime a mensagem informativa e encerra o programa */ else { if (isset($a_phase1[$VPN_ID]['disabled'])) { print "Link offline, Enabling Tunnel!\n"; unset ($a_phase1[$VPN_ID]['disabled']); if (is_array($a_phase2) && (count($a_phase2))) { foreach ($a_phase2 as &$phase2) { if ($phase2['ikeid'] == $ikeid) { unset ($phase2['disabled']); } } unset($phase2); } write_config(); /* flush SPD and SAD */ mwexec("/usr/local/sbin/setkey -F"); mwexec("/usr/local/sbin/setkey -FP"); vpn_ipsec_refresh_policies(); vpn_ipsec_configure(); filter_configure(); exit(0); } else { print "Link offline, Tunnel already Enabled!\n"; exit(0); } } ?></numero></ip></ip>
-
fneto,
Este post pode te ajudar a desconectar a vpn depois de desmarcar o xml
http://forum.pfsense.org/index.php/topic,45314.0/topicseen.html
att,
Marcello Coutinho