Usar rotas de VPN como backup no pfSense



  • Olá pessoal, sou novo no fórum e ainda me considero novato no pfSense, pois cada dia que passa descubro algo novo nele!!

    Bom, meu problema é o seguinte, vejam se podem me ajudar!

    Na empresa temos 4 endereços distintos espalhados por SP. A empresa tem links da embratel interligando os escritórios, links MPLS.

    O ponto concentrador é o site A, e todos os sites tem um link de internet que é usado para a navegação e serviços web dos sites.

    Configurei o pfSense com sucesso de maneira que caso o link de internet pare de funcionar a navegação é roteada automaticamente pelo MPLS da embratel saindo pelo ponto central.

    O problema é a situação contrária. Estabeleci links de VPN com o IPSec entre o site A e os demais sites (Site A -> Site B / Site A -> Site C / Site A -> Site D), porém quando ativo a VPN todo o tráfego entre os sites sai automaticamente pela VPN, e não é isso que quero, na verdade quero que o tráfego interno continue saindo pela embratel e só venha a sair pela VPN caso o link de embratel pare de funcionar.

    Estou estudando algumas alternativas mas gostaria de saber a opinião de vocês. Pensei em utilizar o BGP (mas nunca configurei ele antes, e não faço idéia de como funciona), ou então criar um script que aproveitasse os dados de monitoramento do lnik que o pfsense já faz para quando cair o link ativar o ipsec, porém não faço a mínima idéia de onde começar com esse script.

    Qualquer ajuda é bem vinda e obviamente se chegarmos há alguma solução me comprometo a fazer um tutorial e disponibilizar para todos, pois acho que não sou apenas eu que tem uma situação como essa certo!!

    Muitissimo obrigado a todos antecipadamente!!



  • Continuando o que conversamos no outro tópico.

    A interface do pfsense é toda em php, já fiz alterações e evoluções em dois pacotes e estou aguardando o core team(ermal) compilar o mailscanner para publicar um novo pacote.
    Neste tempo, pude observar que fazer pequenas Alterações via script php pode automatizar muita coisa nele.

    Instalando o pacote cron, Voce consegue ver e alterar o crontab do pfsense, podendo incluir seu script php que habilita o túnel IPSec quando seu MPLS cair.

    Acredito que isso seja mais que uma gambiarra, pode ser o inicio de uma alteração no IPSec do pfsense, podendo virar um pacote ou ate entrar na versão 2.1 deste incrível firewall.

    Podemos começar procurando a opção do XML que marca se o túnel esta a habilitado ou Nao.
    Depois disso basta fazer um php para ativar/desativar este túnel.

    Att,
    Marcello Coutinho



  • Então Marcelo, "viajando nas idéias" mais um pouco, imaginei de repente criar um pacote que habilitasse triggers configuráveis no pfSense, por exemplo, uma interface onde pudesse configurar mais ou menos o seguinte:

    se "variável/ação/condição" acontecer execute "ação" para "serviço/regra/fila" e etc…

    Entendeu!! Definitivamente não tenho conhecimentos sobre o esquema de API e programação no pfSense, mas se você puder pelo menos me dar uma direção de onde procurar informações ou de como começar, pode ter certeza que vou me dedicar no assunto. Preciso resolver isso sem falta!!!

    Faz muito tempo que não programo em PHP, mas já desenvolvi um sistema de gestão de provedor totalmente em PHP há alguns anos então acho que não sou tão tapado assim para não conseguir pelo menos fazer uma interface tosca para isso certo!!



  • Excelente noticia.

    A estrutura básica dos pacotes do pfsense sao arquivos xml que que montam as telas da framework do pfsense e um arquivo inc que na verdade é um script php que executa as ações do pacote tais como

    • gerar arquivo de configuração

    • criticar dados digitados na gui

    • iniciar ou parar o serviço

    • sincronizar configurações com outros pfsenses

    Da uma olhada no repositório do pfsense e do pfsense-packages no github.com



  • Talvez viajei na ideia, mas basicamente voce deve ter posto o ipsec como gateway default por isso na os outros pontos usavam a net do ponto A, uma saída simples utilizar o sistema de load balance pra quando o link cair jogar pelo outro ponto, o pf já monitora o link principal mesmo, acho que cabe a mesma solução de load balance já visto em vários tópicos, se viajei mesmo desculpe…  :)



  • Olhei hoje as opções do Ipsec e aparentemente, so temos a opção de habilitar ou desabilitar o ipsec como um todo.

    Para este caso específico, é melhor deixar a verificacao nas pontas.

    vou fazer uns testes aqui e posto o resultado.



  • fneto,

    Testa por favor a primeira versão do 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'];
    
    if (! is_ipaddr($argv[1])){
    	print "invalid ip address!\n";
    	exit(1);
    }
    exec("/sbin/ping -c 1 -t 1 $argv[1]",$ret,$exit1);
    if ($exit1 == 0) exec("/sbin/ping -c 1 -t 1 $argv[1]",$ret,$exit2);
    if ($exit2 == 0) exec("/sbin/ping -c 1 -t 1 $argv[1]",$ret,$exit3);
    $exit = ($exit1 + $exit2 + $exit3);
    if ($exit == 0){
    	#link online
    	if (array_key_exists("enable",$ipsec)){
    	 	print "link online, disabling ipsec\n";
    	 	unset ($config['ipsec']['enable']);
    	 	write_config();
    	 	vpn_ipsec_configure();
    	 	vpn_ipsec_refresh_policies();
    	 	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";
    }
    ?>
    

    salva ele em /var/www/check_mpls.php ou qualquer outro nome que voce preferir.

    Ele pinga o ip passado como argumento, se o ping falhar, ele habilita o ipsec e aplica as configurações.
    Durante o tempo offline ele mantem o ipsec ativo e assim que o ping respoder ele desativa o ipsec.

    Nota:
    Antes de rodar o script, desabilite manualmente o ipsec na gui.
    Rode primeiro na mão php -q ./check_mpls.php 172.16.5.6 e veja o comportamento dele.

    Aguardo o feedback

    att,
    Marcello Coutinho



  • Marcello, eu mal comecei a entender o esquema de programação do pfSense e você já vem com a solução pronta!!!

    Estou até envergonhado!!

    Vou fazer a instalação remotamente e testar o script. Como estou remoto, vou desabilitar o ipsec e fazer o ping em um ip que está online apenas para ver se o script vai permanecer sem chamar o ipsec.

    Depois vou fazer o teste pingando em um ip off-line para ver se o ipsec sobe.

    Assim que tiver um retorno já te falo. Abraços!



  • Olá Marcello!

    Acabei de rodar o script e ele funcionou corretamente, porém gostaria de lhe mostrar uma coisa. Com o script up, verifiquei o status do ipsec e ele mostrou um link para iniciar a VPN backup do mpls individualmente. Segue abaixo o screen shot e o link do botão de start.

    Parece que o primeiro link de vpn sobe automaticamente, mas o secundário pode ser iniciado ou pausado individualmente independente do ipsec já estar ativo!!

    https://200.x.x.x:8443/diag_ipsec.php?act=connect&remoteid=10.0.16.0&source=172.28.1.1




  • Voce acha que a url que Voce colou resolve o problema? Nao entendi direito o resultado do seu teste.



  • Veja bem, são 2 coisas diferentes!!

    1 - O script rodou ok!!!

    • Desliguei o ipsec na GUI
    • Rodei o scrip com um ip que estava online e ele reportou que o ip estava on line e não desligou
    • Rodei o script novamente com um ip que estava offline e dai ele ativou o ipsec na gui!

    2 - Após ativar o ipsec na gui, percebi que o IPSEC oferece a opção de controle da VPN por vpn, então imaginei que ao invés do script ativer ou desativar todo o ipsec, ele poderia apenas ativar ou desativar apenas a conexão de vpn desejada sem parar todo o ipsec do sistema.
    Dessa maneira, imagine que 2 links cairam, mas apenas 1 voltou a funcionar, o que já estivesse ok voltaria para o MPLS, o que estivesse ainda com problemas continuaria no VPN.

    Outra coisa, o script precisa aceitar como parâmetro a interface de rede que você deseja usar para fazer o teste de ping, pois quando  a VPN estiver no ar o ping vai continuar dando ok pois estará indo pela VPN!!

    Abraços!



  • Entendi.

    Faz este teste para ver se a url individual resolve o problema:

    Desabilita o script  e o ipsec.

    Depois roda só a url que você colou com os parametros da sua vpn backup do MPLS e vê se alem dela subir, ela se mantem no ar apos alguns updates ou algumas horas.



  • Após dar um paste na URL ele pensa um pouco mas não conecta não!!

    Chequei a gui e o ipsec continua desligado após clicar no start da conexão de vpn, que continua aparecendo (porem com o x vermelho) no status do ipsec!



  • Nesta segunda versao do script, voce coloca qualquer parametro de ping como argumento e por ultimo o ip de destino.

    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'];
    $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 ipsec\n";
                    unset ($config['ipsec']['enable']);
                    write_config();
                    vpn_ipsec_configure();
                    vpn_ipsec_refresh_policies();
                    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";
    }
    ?>
    
    

    ex: php -q ./check_ipsec.php -S 172.16.5.6 172.16.5.7

    veja se assim voce consegue forçar a interface de saida do ping.



  • @rafael.cardoso:

    Talvez viajei na ideia, mas basicamente voce deve ter posto o ipsec como gateway default por isso na os outros pontos usavam a net do ponto A.

    Oi Rafael,

    Onde você altera a prioridade de rota do ipsec e como faríamos neste caso para o pfsense escolher entre dois caminhos para a mesma rede de destino?



  • Olá Marcello fiz o teste com a nova versão do script e está funcionando corretamente. vou instalar o pacote cron no pfsense e configurar o script para rodar.

    Quero ver se começo a estudar os plugins e programação hoje, durante a semana é muito corrido para mim!!

    Muitíssimo obrigado!!



  • Olá Marcelloc, tudo bem?

    Rapaz lembra do script check_mpls que você fez para mim, então estou tentando ajustar aquele script para ao invés de desligar toda a estrutura do ipsec desligar apenas os túneis que passei como parâmetro.

    Estou apanhando com isso a tarde toda mas até agora não entendi como fazer isso, poderia me dar uma força? Se estiver disponível eu te mando o script com as alterações ok!

    Abraços!



  • fneto,

    A opção de desabilitar o ipsec ou não envolve todos os tuneis, por isso o script roda nas pontas, onde só existe um túnel.

    para derrubar somente um link, você vai precisar suar os comando do proprio ipsec, racoon-alguma coisa. Não tenho muita experiência com isso.

    att,

    Marcello Coutinho



  • Então Marcello, na verdade não, o que quero é apenas habilitar a opção  "Disable this phase1" e "Disable this phase 2" na interface do pfsense, feito isso salvo a configuração e ele mata somente o túnel que eu passar o id como parâmetro entendeu!!

    Não quero mexer com racoon nem nada disso, como você desabilitou o ipsec todo na interface achei que talvez pudesse me ajudar a encontrar a opção de desabilitar apenas os túneis.

    Na verdade eu já identifiquei as variáveis nos array estudando os arquivos do pfSense, o que não estou conseguindo fazer é gravar as configurações!



  • 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>
    


  • @fneto

    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


Log in to reply