smtp.gmail.com do bash fornece "Erro no certificado: o emissor do certificado do par não é reconhecido".


11

Eu precisava do meu script para enviar um email para o administrador se houver algum problema, e a empresa usar apenas o Gmail. Seguindo algumas instruções, eu consegui configurar o mailx usando um arquivo .mailrc. primeiro houve o erro do nss-config-dir, resolvi isso copiando alguns arquivos .db de um diretório do firefox. para ./certs e com o objetivo em mailrc. Um email foi enviado.

No entanto, o erro acima surgiu. Por algum milagre, havia um certificado do Google no .db. Ele apareceu com este comando:

~]$ certutil -L -d certs

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

GeoTrust SSL CA                                              ,,
VeriSign Class 3 Secure Server CA - G3                       ,,
Microsoft Internet Authority                                 ,,
VeriSign Class 3 Extended Validation SSL CA                  ,,
Akamai Subordinate CA 3                                      ,,
MSIT Machine Auth CA 2                                       ,,
Google Internet Authority                                    ,,

Provavelmente, isso pode ser ignorado, porque o email funcionou de qualquer maneira. Finalmente, depois de puxar um pouco de cabelo e de muitos óculos, descobri como me livrar do aborrecimento.

Primeiro, exporte o certificado existente para um arquivo ASSCII:

~]$ certutil -L -n 'Google Internet Authority'  -d certs -a > google.cert.asc

Agora reimporte esse arquivo e marque-o como confiável para certificados SSL, ala:

~]$ certutil -A -t "C,," -n 'Google Internet Authority'  -d certs -i google.cert.asc

Depois disso, a listagem mostra que é confiável:

~]$ certutil -L -d certs

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI
...
Google Internet Authority                                    C,,

E o mailx envia sem problemas.

~]$ /bin/mailx -A gmail -s "Whadda ya no" somebody@acompany.com
ho ho ho
EOT
~]$

Espero que seja útil para alguém que deseja concluir o erro.

Além disso, estou curioso sobre algumas coisas.

Como eu poderia obter esse certificado, se não estivesse no banco de dados do mozilla por acaso? Existe, por exemplo, algo assim?

    ~]$ certutil -A -t "C,," \
                 -n 'gmail.com'  \
                 -d certs \
                 -i 'http://google.com/cert/this...'

Respostas:


13

Bem, não é o único liner que eu queria, mas é como buscar e importar um certificado do zero:

# Create a certificate directory
~]$ mkdir certs

# Create a new database in the certs dir
~]$ certutil -N -d certs 

# Need now a chain certificate - May 18, 2015
~]$ wget https://www.geotrust.com/resources/root_certificates/certificates/GeoTrust_Global_CA.cer

# Need now a chain certificate part 2 - May 18, 2015
~]$ mv GeoTrust_Global_CA.cer certs/

# Fetch the certificate from Gmail, saving in the text file GMAILCERT
# Added the CA opion - May 18, 2015
~]$ echo -n | openssl s_client -connect smtp.gmail.com:465 -CAfile certs/GeoTrust_Global_CA.cer | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > GMAILCERT

# Import the new cert file into the new database in the new dir
~]$ certutil -A -n "Google Internet Authority" -t "C,," -d certs -i GMAILCERT 

# Double Check
~]$ certutil -L -d certs

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

Google Internet Authority                                    C,,  

Yaa! e graças à resposta deste bilhete


1
Estou recebendo um erro novamente: "Erro no certificado: o emissor do certificado do par não é reconhecido". O certificado do gmail que eu ingeri havia expirado, parece que o novo é um certificado em cadeia. openssl s_client -showcerts -connect smtp.gmail.com:465 </dev/nullpara vê-los todos.
Spazm

1
Atualizou a resposta com uma etapa para baixar o arquivo cer dos emissores.
Ndsusers


7

Esta postagem precisa ser atualizada novamente. Eu estava tendo problemas com a instalação do mailx na minha caixa do CentOS 7. O correio seria enviado, mas eu ainda estava recebendo o "Erro na certificação: o emissor do certificado do par não é reconhecido". erro.

Eu encontrei a solução aqui , tive que traduzi-lo embora.

Aqui está uma maneira rápida de fazer isso:

# Create a certificate directory
mkdir ~/.certs

# Create a new database in the certs dir (dont forget to enter your pass phrase!)
certutil -N -d ~/.certs 

# Create three files for the cert chain
touch ~/.certs/google ~/.certs/geotrust ~/.certs/equifax

# Copy the cert chain for smtp.google.com:465 over to my_certs file (don't forget the -showcerts option, CTRL + C to end this command)
openssl s_client -showcerts -connect smtp.gmail.com:465 > ~/.certs/my_certs

Agora copie cada certificado, incluindo o --BEGIN CERTIFICATE-- e --END CERTIFICATE-- e cole-os nos respectivos arquivos que você criou anteriormente (google, geotrust, equifax) e salve esses arquivos.

# Open your my_certs file you made earlier and copy the google cert (usually the first one)
nano ~/.certs/my_certs

# Open your google file, paste the google cert that you just copied, and save and close
nano ~/.certs/google

# Open your my_certs file you made earlier and copy the geotrust cert (usually the second one)
nano ~/.certs/my_certs

# Open your geotrust file, paste the geotrust cert that you just copied, and save and close
nano ~/.certs/geotrust

# Open your my_certs file you made earlier and copy the equifax cert (usually the third one)
nano ~/.certs/my_certs

# Open your equifax file, paste the equifax cert that you just copied, and save and close
nano ~/.certs/equifax

Agora temos que importar cada um desses certificados para o banco de dados.

# Import the google cert into the db
certutil -A -n "Google Internet Authority" -t "TC,," -d ~/.certs -i ~/.certs/google

# Import the geotrust cert into the db
certutil -A -n "GeoTrust Global CA" -t "TC,," -d ~/.certs -i ~/.certs/geotrust

# Import the equifax cert into the db
certutil -A -n "Equifax Secure Certificate Authority" -t "TCP,," -d ~/.certs -i ~/.certs/equifax

# Double check to make sure everything imported correctly into the db
certutil -L -d ~/.certs

Exemplo de saída:

Certificate Nickname                                         Trust Attributes
                                                             SSL,S/MIME,JAR/XPI

Google Internet Authority                                    CT,,
GeoTrust Global CA                                           CT,,
Equifax Secure Certificate Authority                         CT,,

Tempo de limpeza (opcional)

# Remove all unnecessary files since the db has the certs :)
rm -rf ~/.certs/google ~/.certs/geotrust ~/.certs/equifax ~/.certs/my_certs

# Now run a test to make sure mailx is sending correctly now (don't forget to change yourname@example.com to the email address you'd like to send to)
echo "Your message" | mail -s "Message Subject" yourname@example.com

Nesse caso, você não deve receber o "Erro no certificado: o emissor do certificado do par não é reconhecido". erro mais!

Notas:

Você deve ter notado que eu mudei o dir de /certspara ~/.certs. mailx é executado como root, então eu apenas fiz essas alterações como root /. "~ /" Significa PRINCIPAL diretório juntar tudo ~/.certsmeio /root/.certs/. Tenho certeza que você sabia disso, mas ei, apenas no caso de você nunca saber quem pode estar lendo isso!

Caso você precise, aqui estão as opções de configuração que adicionei na parte inferior do /etc/mail.rc

# /etc/mail.rc options added to the bottom
set smtp-use-starttls
set smtp-auth=login
set smtp=smtp://smtp.gmail.com:587
set from="your.from.user@gmail.com(Web01 Server)"
set smtp-auth-user=your.smtp.user@gmail.com
set smtp-auth-password=your.pass
set ssl-verify=ignore
set nss-config-dir=/root/.certs

Certifique-se de alterar your.from.user, your.smtp.user e your.pass para as respectivas variáveis.


Obrigado opterons, isso funcionou como charme, não sei por que @ndasusers não funcionou.
Abhishek Madhani

Alguém sabe como resolver o problema quando os servidores de email estão com balanceamento de carga e são executados como um cluster? por exemplo, Office 365 O certificado receberá um erro intermitentemente porque o servidor no final da conexão muda de conexão para conexão.
Brad

Isso está desatualizado novamente: -showcertsfornece dois certificados, não 3. O segundo é um GlobalSign. Ainda assim, esse procedimento é o único que funciona, então +1: use -showcerts, encontre todos os certificados nele (atualmente 2) e importe-os individualmente para o banco de dados.
EML

... e executar opensslcomo echo -n | openssl, ou trava, aguardando entrada
EML

@ EML + ou openssl s_client </dev/null. Sim, a partir de 2017, o Google (incluindo o gmail) passou do GIA2 sob GeoTrust / Equifax para GIA3 sob GlobalSign. Mas não há necessidade de armazenar todos os materiais da cadeia. E se qualquer criminoso ou impostor (como um governo intrometido) se passar pelo Gmail, esse método não apenas confia neles, mas o faz permanentemente - outros usuários podem ser temporariamente enganados por um certificado emitido de forma ilegítima, mas quando são revogados, eles deixam de confiar nele. Como você continua a enviar todo o seu email para os malfeitores.
Dave_thompson_085

0

Criei um pequeno script, com base nas respostas deste tópico, que automaticamente extrairá, analisará e instalará os certificados smtp atuais do gmail. Deve ser capaz de lidar com isso se o número de certificados mudar novamente.

Aqui está um pastebin com destaque de sintaxe também

#!/bin/bash

# This script pulls ssl certs for using gmail smtp. Adapted from the following config explaination:
# /server/498588/smtp-gmail-com-from-bash-gives-error-in-certificate-peers-certificate-issuer

certdirectory="/home/user/.certs"

# Functions

fail() {
    ec=$?
    [ "${ec}" == "0" ] && ec=1
    echo -e "FAILED[code=$ec]: $@"
    exit $ec
}

warn(){
echo -e "WARNING $@"
}

cleanup() {
  rm allgcert* || warn "Cleanup of files errored"
  rm gcert* || warn "Cleanup of files errored"
}

failclean() {
  cleanup
  fail "$@"
}

# Count number of certs currently being used (can change from time to time)
numcerts=$(echo -n | openssl s_client -showcerts -connect smtp.gmail.com:465 | grep -c "i:")

# Create the certs directory if it does not exist
mkdir -p $certdirectory || fail "Unable to create certificates directory"

# Pull certs to a local file for parsing
echo -n | openssl s_client -showcerts -connect smtp.gmail.com:465 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > allgcert || failclean "Unable to pull certs from smtp.gmail.com"

# Parses certs output based on the number of certs, and outputs to individual files
if (($numcerts > 1)) ; then
  # Pulls the first cert out as it needs one extra line
  sed '1,27!d' allgcert > gcert1
  # For subsequent certs, it multiplies the cert number by the number of lines in the file where it should exist
  for i in $(seq 2 $numcerts) ; do
    sed "$((2 + (((($i - 1)) * 26))))"','"$((1 + (($i * 26))))"'!d' allgcert > gcert${i}
  done
fi

# Parses out certificate issuer names for installation
echo -n | openssl s_client -showcerts -connect smtp.gmail.com:465 | grep i: | sed -e 's,.*=,,' > allgcertnames || failclean "Unable to output parsed names for certificates"

for i in $(seq 1 $numcerts) ; do
  certutil -A -n "$(sed -n ${i}p allgcertnames)" -t "TC,," -d $certdirectory -i gcert${i} || failclean "Unable to import certificates to database"
done

cleanup

Como acima esta é a coisa errada a fazer, mas se você quiser fazê-lo uma linha de awk é suficiente:openssl s_client </dev/null -showcerts -connect ... | awk '/^ i:/{n=substr($0,7)} /-BEGIN/,/-END/{print>"t"} /-END/{close("t"); system("certutil -A -n \"" n "\" -t TC,, -i t -d certdir || echo failed; rm t")}'
dave_thompson_085

Ah, eu não vi seu comentário antes de criar esse script. Obrigado! Edit: depois de reler seu one-liner, não vejo nenhuma diferença prática entre o meu script e esse. Estou assumindo que você acabou de me fornecer basicamente a versão de uma linha do meu script. Existe um "caminho certo" recomendado para fazer isso que não terá o problema da confiança permanente?
pyr0ball
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.