Como reiniciar um serviço Java sem interrupção usando o firewall / iptables?

1

Se ativar esta regra

iptables -t nat -A PREROUTING -p tcp --dport 80  -j REDIRECT --to 8080

Em seguida, as conexões que chegam à porta do servidor 80 são redirecionadas para localhost: 8080. Se eu quiser reiniciar o serviço, posso apenas iniciar o serviço em outra porta? Diga a porta 8081 e redirecione o firewall para

iptables -t nat -A PREROUTING -p tcp --dport 80  -j REDIRECT --to 8081 # Apparently -A won't work. I have to replace the rule, not add it. But I don't know how to do it yet

No entanto, e as conexões de soquete TCP estabelecidas na porta NAT 8080? Eles serão descartados imediatamente após as alterações do firewall? Alternativamente, eles continuarão trabalhando até que um soquete TCP normal seja fechado?

Em caso afirmativo, isso funciona como uma reinicialização do aplicativo sem interrupção por ter a instância antiga na porta 8080 em um encerramento normal e a nova na porta 8081 com os novos recursos.

Este raciocínio está correto?

    
por David Hofmann 08.08.2016 / 21:32

2 respostas

3

Você perguntou: " Este raciocínio está correto? "

Minha resposta é: "Para ser parcialmente correto, você precisa corrigir vários detalhes entre suas suposições e ações. Não sendo 100% correto, isso também significa que ... é basicamente um abordagem errada ! " E eu digo tal declaração devido aos seguintes fatores (em ordem mais ou menos aleatória):

  1. IMHO, você resolverá um problema (reiniciar um servidor / serviço TCP sem interromper as conexões TCP estabelecidas) usando a abordagem incorreta. O que me parece uma abordagem "natural" é resolver o problema em "nível de aplicativo". Como você está falando sobre um aplicativo TCP / Server, as chances são muito altas de serem "multithreaded" ou "multiprocess". Em tal ambiente, nada impede que você "reinicie" threads / processos não utilizados, enquanto espera por threads / processos "ocupados" para completar suas atividades. Claro, é mais complexo do que colocar um par de regras do iptables, mas ... é o que parece "natural" (para mim). BTW: esta é exatamente a abordagem que os desenvolvedores "apache" implementaram em suas " graciosas reiniciar "para o daemon httpd TCP
Tendo dito o acima, quanto à abordagem iptables em que você está interessado, aqui estão os meus comentários:

  1. como já foi mencionado por @iain, você não pode usar -A , mas precisa substituir a regra existente. Dê uma olhada na página de manual iptables e procure pelo -R ou - se você tiver problemas para identificar a regra a ser substituída - o par -D + -A ;

  2. iptables é realmente poderoso , portanto, deve ser possível corresponder apenas a novas conexões. Em outras palavras, você pode reescrever sua regra NAT para corresponder a somente novas conexões (dê uma olhada em estados de conexão e correspondência conntrack ). Com essa abordagem, a conexão existente permanecerá na "antiga" PORT, enquanto as novas conexões serão redirecionadas para a "nova" PORT. Infelizmente, a "nova" conexão se tornará "estabelecida" muito em breve e ... será reconhecida pela primeira regra (redirecionada para a porta OLD, já que lida com conexões "estabelecidas"). De qualquer forma, você deve ser capaz de resolver esse problema com uma mistura de 1) mangling os pacotes de entrada / saída; 2) seleção adequada da faixa de portas; 3) gerenciamento de espaço de usuário do rastreamento de conexão ; 4) outras coisas que eu certamente ignorarei. Tendo dito isso, por favor, não me peça detalhes, pois eu não sou um especialista em netfilters (mas aposto que isso pode ser feito);

  3. você perguntou: " o que acontece com as conexões de soquete TCP estabelecidas na porta NAT 8080? Elas serão descartadas imediatamente após as alterações do firewall? Alternativamente, elas continuarão trabalhando até que um soquete TCP normal seja fechado? "

    4.1 " eles serão descartados imediatamente ": aqui você está usando indevidamente a palavra "DROP" que, no contexto iptables / netfilter, é um conceito-chave, em par com o " REJECT "prazo. Consulte aqui como um começo para investigação pessoal. No seu caso particular (onde você altera a regra NAT subjacente enquanto a conexão é estabelecida) eu acho que assim que o primeiro pacote TCP da conexão estabelecida ("estabelecido" para o "antigo" TCP / Server) for recebido pelo "novo" TCP / servidor devido à regra DNAT atualizada, o "novo" TCP / servidor simplesmente " encerra "a conexão (com um sinalizador" RESET ", eu acho), já que não reconhecerá tais pacotes. Eu não acho que isso pode ser classificado como um "DROP", como um RST será enviado (eu acho).

    4.2 " eles continuarão trabalhando até o fechamento normal do soquete TCP ": Eu aposto que eles não irão! Se você aplicar alguma "violência" a pacotes TCP aleatórios de uma conexão TCP estabelecida, não apenas removendo pacotes, mas enviando-os para um TCP / servidor diferente ... você pode ter certeza de que algo estranho acontecerá. E, no mínimo, as palavras " elas continuam funcionando " não podem ser aplicadas! BTW: essa é exatamente a razão para um software como conntrackd existe, portanto, para garantir o alinhamento dos dados de rastreamento de conexão entre um cluster de firewall HA iptables de dois nós.

por 09.08.2016 / 01:00
2

Como você está usando -A , está adicionando uma regra para que as regras anteriores não sejam afetadas.

Com o iptables, a primeira regra que coincide ganha de fato com as regras conforme declarado, qualquer conexão que atinja a porta 80 será encaminhada para a porta 8080.

Se, no entanto, você decidir excluir a regra que encaminha a porta 80 para a porta 8080, os pacotes destinados à porta 80 serão encaminhados para a porta 8081. Isso interromperá as conexões existentes, pois o servidor na porta 8081 não terá uma ideia sobre eles.

    
por 08.08.2016 / 21:41