Ao desenvolver aplicações Java no Azure Functions (Linux, em planos dedicados), é comum encontrar o erro de handshake SSL ao tentar conectar serviços protegidos por certificados autoassinados (self-signed):
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Por padrão, a Java Virtual Machine (JVM) confia apenas em CAs reconhecidas. Para contornar isso em ambientes de produção, a estratégia mais recomendada — e de melhor governança — é injetar seu certificado em um truststore customizado, garantindo que ele persista em storage durável.
O desafio da persistência no Linux
No Azure App Service e no Azure Functions (Linux), o filesystem de sistema é efêmero. Alterações em pastas como /usr/lib/jvm serão perdidas a cada reinicialização, redeployment ou escala da infraestrutura. A solução reside no diretório /home, que possui persistência garantida. Ao apontar a JVM para um truststore criado dentro de /home, criamos uma configuração resiliente a qualquer alteração de estado do platform runtime.
Implementação: O passo a passo técnico
1. Preparação do seu Keystore customizado
Precisamos copiar o cacerts padrão da JVM para o diretório persistente e, a partir dele, criar o seu store customizado.
- Conecte-se via SSH pelo console do Kudu (
https://<seu-app-name>.scm.azurewebsites.net/webssh/host). - Identifique seu
JAVA_HOMEcomecho $JAVA_HOMEe replique o comando abaixo adaptando o caminho:
cp /usr/lib/jvm/msft-17-x64/lib/security/cacerts /home/site/wwwroot/my-truststore.jks
2. Importação do seu Certificado
Com o keystore criado, utilize o keytool para importar sua chave pública:
./keytool -import -alias my-self-signed-cert \
-file /home/self-signed.badssl.com.cer \
-keystore /home/site/wwwroot/my-truststore.jks \
-storepass changeit -noprompt
3. Verificação
Valide sempre se o alias foi inserido corretamente antes de aplicar a configuração:
./keytool -list -v \
-keystore /home/site/wwwroot/my-truststore.jks \
-storepass changeit -alias my-self-signed-cert
4. Aplicação via Application Settings
Para que a JVM utilize esse novo arquivo, configure a variável de ambiente JAVA_OPTS via Azure Portal (Configuration > Application Settings):
- Name:
JAVA_OPTS - Value:
-Djavax.net.ssl.trustStore=/home/site/wwwroot/my-truststore.jks -Djavax.net.ssl.trustStorePassword=changeit
Pontos de Atenção para Engenharia
Localização do Arquivo e Deployment:
Colocar o arquivo em /home/site/wwwroot/ é prático, mas note que métodos de deployment como ZipDeploy ou Run From Package podem sobrescrever esse diretório. Para maior segurança, utilize um subdiretório externo, como /home/my-certs/.
Diferença notável: Azure App Service vs. Azure Functions (Linux):
Tenha cuidado: enquanto o Azure App Service (Linux) muitas vezes importa automaticamente certificados carregados no portal para dentro da JVM, o Azure Functions não o faz. O sistema operacional pode validar o certificado (via curl ou openssl), mas sua aplicação Java falhará ao realizar o handshake. Você deve usar o truststore customizado ou injetar o certificado via código dentro do seu SSLContext.
Manutenção:
Lembre-se que ciclos de vida de certificados são responsabilidade do seu time de operações. Se o seu certificado expirar, basta repetir o comando keytool -import para atualizar o arquivo .jks sem necessidade de reconfigurar toda a infraestrutura.
Artigo originalmente publicado em Azure Updates - Latest from Azure Charts.