Liga-te à porta do registo através do túnel, observa a negociação começar e depois vê o JConsole a expirar mesmo assim. Isso acontece porque a primeira ligação TCP não é a ligação de gestão: é uma consulta. O registo RMI responde com uma referência que nomeia um anfitrião e uma segunda porta, e o JConsole vai então para onde lhe foi dito. Se o túnel só alcança a primeira porta do servidor, ou se a referência nomeia um endereço que só existe na LAN do próprio servidor, o cliente fica parado depois de aparentemente ter tido sucesso.

O mito: uma porta aberta é uma ligação

JMX remoto sobre RMI envolve pelo menos dois pontos finais, e são escolhidos por partes diferentes do sistema. A porta do registo é a que escreves no cliente, e existe para entregar o stub que descreve o conector real. Tomar o primeiro socket com sucesso como prova de que o caminho de gestão está aberto é o que transforma um diagnóstico de dois minutos numa tarde de pedidos de firewall.

Olha para o erro do próprio cliente em vez da lista de escutas do servidor. Uma falha depois de a negociação começar diz-te que a segunda ligação, e não a primeira, não foi concluída.

O que o registo devolve

O stub contém um endereço e uma porta, serializados no momento em que o conector foi criado. Num servidor com várias interfaces, a pilha pode ter escolhido um endereço alcançável a partir da rede local e não da tua. O cliente não conhece a diferença; limita-se a marcar o valor que lhe deram, e o pacote segue a rota que existir para esse endereço, que num cliente VPN muitas vezes não é nenhuma. É esse o momento em que a segunda ligação é tentada.

É também por isso que a falha é intermitente entre ambientes: o mesmo servidor pode comportar-se de forma diferente para um utilizador na LAN e para um utilizador no túnel, sem qualquer alteração na configuração do JMX.

Duas portas e duas propriedades que as fixam

A porta do registo vem de com.sun.management.jmxremote.port, e o conector pode ser fixado com com.sun.management.jmxremote.rmi.port em vez de ficar ao critério do que a pilha atribui. Define ambas explicitamente quando houver uma firewall ou um security group entre o cliente e o servidor, porque uma segunda porta imprevisível não pode ser autorizada antecipadamente, e um intervalo amplo aberto para a acomodar é pior do que fixar um único valor.

Confirma depois com ss -ltn ou netstat -an no servidor que ambas as portas estão à escuta e em que endereços. Um listener ligado ao loopback está correto para uma implementação apenas local e é inútil para esta.

Quando o nome anunciado está errado

O nome de anfitrião que aparece na referência remota é definido por java.rmi.server.hostname. Afeta o que o stub anuncia; não é, por si só, uma instrução para ligar todos os listeners a uma única interface, e é por isso que o definir nem sempre produz o comportamento de porta única que as pessoas esperam. Define-o, reinicia o processo e depois verifica o que o stub contém realmente. Escolhe um nome ou endereço que o cliente consiga resolver e alcançar através do túnel, e reinicia o processo para que o stub seja reconstruído.

As redes de contentores pioram isto, porque o endereço que o processo vê pode ser interno e não encaminhável a partir de fora do contentor. Publica explicitamente o nome de anfitrião pretendido em vez de deixar a plataforma escolher.

Se fizeres o túnel com SSH em vez de uma VPN, o mesmo problema aparece com outra roupagem: encaminhar só a porta do registo deixa o segundo ponto final a apontar para um endereço que o teu cliente não consegue alcançar. Encaminha as duas portas e faz com que o nome anunciado resolva para algo que o cliente consiga alcançar localmente.

Não desatives a segurança de gestão para simplificar

Os trechos que desativam a autenticação e o TLS são fáceis de encontrar e fazem a ligação funcionar de uma forma que terás de desfazer mais tarde. O JMX remoto é uma interface de gestão com os mesmos privilégios do processo que inspeciona; mantém os seus controlos de acesso e, se o cliente não conseguir apresentar credenciais, corrige isso em vez disso.

Quando os pontos finais estiverem corretos, guarda o próximo erro que vires. Uma rejeição do truststore ou da conta é uma fase posterior a um conector inalcançável e significa que o trabalho de rede está concluído.

Artigos relacionados