AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 108710
Accepted
csd
csd
Asked: 2015-08-01 11:24:11 +0800 CST2015-08-01 11:24:11 +0800 CST 2015-08-01 11:24:11 +0800 CST

Como examinar o certificado SSL do servidor PostgreSQL?

  • 772

Suponha que haja um servidor PostgreSQL em execução e com SSL ativado. Usando ferramentas Linux e PostgreSQL "padrão", como posso examinar seu certificado SSL?

Espero uma saída semelhante à que você obteria executando openssl x509 -text .... E espero uma resposta de linha de comando de uma ou duas linhas, para não ter que recorrer à execução de um farejador de pacotes.

Não tenho acesso ao servidor PostgreSQL, portanto não posso consultar seus arquivos de configuração diretamente.

Não tenho login de superusuário, então não consigo pegar o valor da ssl_cert_fileconfiguração e depois pg_read_filenele.

Usar openssl s_client -connect ...não funciona porque o PostgreSQL parece não querer fazer o handshake SSL imediatamente.

Em uma rápida olhada na psqldocumentação, não consegui encontrar um parâmetro de linha de comando que mostre essas informações na inicialização. (Embora me mostre certas informações cifradas.)

postgresql postgresql-9.4
  • 5 5 respostas
  • 16647 Views

5 respostas

  • Voted
  1. Best Answer
    Adam Batkin
    2019-07-18T17:41:59+08:002019-07-18T17:41:59+08:00

    Parece que a s_clientferramenta do OpenSSL adicionou suporte ao Postgres usando o -starttlsem 1.1.1, então agora você pode usar todo o poder das ferramentas de linha de comando do OpenSSL sem scripts auxiliares adicionais:

    openssl s_client -starttls postgres -connect my.postgres.host:5432 # etc...
    

    Referências:

    • Git commit
    • página de manual s_client
    • 18
  2. csd
    2015-08-04T12:10:19+08:002015-08-04T12:10:19+08:00

    Seguindo a ideia do comentário de Craig Ringer:

    Uma opção é corrigir openssl s_cliento handshake com o protocolo PostgreSQL. Você provavelmente também pode fazer isso com Java, passando um SSLSocketFactory personalizado para PgJDBC. Não tenho certeza se existem opções simples.

    ...Eu escrevi uma fábrica de soquete SSL simples. Copiei o código da própria NonValidatingFactoryclasse do PgJDBC e apenas adicionei código para imprimir os certificados.

    Aqui está o que parecia, quando tudo foi dito e feito:

    import java.security.GeneralSecurityException;
    import java.security.cert.X509Certificate;
    import java.sql.Connection;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.postgresql.ds.PGSimpleDataSource;
    import org.postgresql.ssl.WrappedFactory;
    
    public class ShowPostgreSQLCert {
        public static void main(String[] args) throws Throwable {
            PGSimpleDataSource ds = new PGSimpleDataSource();
            ds.setServerName( ... );
            ds.setSsl(true);
            ds.setUser( ... );
            ds.setDatabaseName( ... );
            ds.setPassword( ... );
            ds.setSslfactory(DumperFactory.class.getName());
            try (Connection c = ds.getConnection()) { }
        }
    
        public static class DumperFactory extends WrappedFactory {
            public DumperFactory(String arg) throws GeneralSecurityException {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[] { new DumperTM() }, null);
                _factory = ctx.getSocketFactory();
            }
        }
    
        public static class DumperTM implements X509TrustManager {
            public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                for (int i=0; i<certs.length; ++i) {
                    System.out.println("Cert " + (i+1) + ":");
                    System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                    System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
                }
            }
        }
    }
    
    • 11
  3. mivk
    2016-11-13T09:46:42+08:002016-11-13T09:46:42+08:00

    Se você não quiser se preocupar em instalar o java e compilar e já tiver o python, tente este script python: https://github.com/thusoy/postgres-mitm/blob/master/postgres_get_server_cert.py

    Eu o uso para verificar as datas dos certificados:

    postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -dates
    

    Ou para o certificado completo como texto:

    postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -text
    
    • 11
  4. vidarsk
    2016-04-27T01:49:27+08:002016-04-27T01:49:27+08:00

    A resposta de csd realmente me salvou. Aqui está um passo a passo mais detalhado para aqueles de nós que não conhecem ou se esqueceram do java.

    1. Certifique-se de que seu servidor pode compilar java. Tente o comando "which javac", se ele gerar algo como "... no javac in ..." então você precisa instalar um JDK (o JRE não funcionará, ele tem "java" mas não "javac").

    2. Instale o postgresql-jdbc se ainda não o tiver. Para RHEL6, o comando é "yum install postgresql-jdbc". Descubra onde os arquivos jar estão instalados. Haverá vários deles, um para cada versão. Eu usei "/usr/share/java/postgresql-jdbc3.jar".

    3. Copie o código do csd e insira as informações do banco de dados (a outra resposta) ou use minha versão ligeiramente modificada no final desta resposta. Salve-o em um arquivo chamado exatamente "ShowPostgreSQLCert.java". Maiúsculas/minúsculas importam, chame de qualquer outra coisa e não compilará.

    4. No diretório com o arquivo ShowPostgreSQLCert.java, execute o seguinte comando (modifique o local de postgresql-jdbc3.jar, se necessário): "javac -cp /usr/share/java/postgresql-jdbc3.jar ShowPostgreSQLCert.java". Agora você deve ter 3 arquivos .class no mesmo diretório.

    5. Por fim, execute o seguinte comando: "java -cp .:/usr/share/java/postgresql-jdbc3.jar ShowPostgreSQLCert". O "." depois de "-cp" significa que ele deve procurar no diretório atual pelos arquivos .class. Você pode inserir o caminho completo para os arquivos de classe aqui, apenas lembre-se de manter o ":" entre o caminho e o local do arquivo .jar.

    6. Se você precisa executar o comando em uma máquina diferente, você precisa ter o mesmo arquivo jar instalado (postgresql-jdbc3.jar), ou provavelmente pode apenas copiá-lo do servidor em que você compilou os arquivos .class. Em seguida, basta copiar os arquivos .class e executar o comando de 5. depois de modificar os caminhos.

    Modifiquei ligeiramente o código para que você possa passar as informações do banco de dados na linha de comando em vez de compilá-las no arquivo .class. Basta executá-lo sem nenhum argumento e ele exibirá uma mensagem mostrando quais argumentos ele espera. o código + modificações do csd é:

    import java.security.GeneralSecurityException;
    import java.security.cert.X509Certificate;
    import java.sql.Connection;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.postgresql.ds.PGSimpleDataSource;
    import org.postgresql.ssl.WrappedFactory;
    
    public class ShowPostgreSQLCert {
        public static void main(String[] args) throws Throwable {
            PGSimpleDataSource ds = new PGSimpleDataSource();
            if( args.length != 4 ) {
                System.out.println("Not enough arguments. Usage: ShowPostgreSQLCert ServerName User DatabaseName Password");
                System.exit(1);
            }
            ds.setServerName( args[0] );
            ds.setSsl(true);
            ds.setUser( args[1] );
            ds.setDatabaseName( args[2] );
            ds.setPassword( args[3] );
            ds.setSslfactory(DumperFactory.class.getName());
            try (Connection c = ds.getConnection()) { }
        }
    
        public static class DumperFactory extends WrappedFactory {
            public DumperFactory(String arg) throws GeneralSecurityException {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[] { new DumperTM() }, null);
                _factory = ctx.getSocketFactory();
            }
        }
    
        public static class DumperTM implements X509TrustManager {
            public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                for (int i=0; i<certs.length; ++i) {
                    System.out.println("Cert " + (i+1) + ":");
                    System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                    System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
                }
            }
        }
    }
    
    • 3
  5. Cameron Kerr
    2016-10-21T17:33:37+08:002016-10-21T17:33:37+08:00

    Adicionei algum código de https://stackoverflow.com/questions/3313020/write-x509-certificate-into-pem-formatted-string-in-java para gerar os certificados como PEM e removi a necessidade de especificar um db, nome de usuário ou senha (não são necessários para obter o certificado).

    Usando isso, pude verificar que uma reinicialização do PostgreSQL infelizmente parece necessária para mudar para um novo certificado.

    Não sendo um desenvolvedor Java, minhas etapas para construir e executar provavelmente não são tão boas, mas funcionam, desde que você encontre um postgresql jdbc

    # locate postgresql | grep jar
    /path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar   <-- this one will do
    ...
    

    Compilar:

    javac -cp /path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar ./ShowPostgreSQLCert.java
    

    Para correr:

    java -cp /path/to/a/lib/postgresql-9.1-901-1.jdbc4.jar:. ShowPostgreSQLCert 127.0.0.1
    

    Exemplo de saída:

    Cert 1:
        Subject: CN=...
        Issuer: CN=...
        Not Before: Fri Oct 21 11:14:06 NZDT 2016
        Not After: Sun Oct 21 11:24:00 NZDT 2018
    -----BEGIN CERTIFICATE-----
    MIIHEjCCBfqgAwIBAgIUUbiRZjruNAEo2j1QPqBh6GzcNrwwDQYJKoZIhvcNAQEL
    ...
    IcIXcVQxPzVrpIDT5G6jArVt+ERLEWs2V09iMwY7//CQb0ivpVg=
    -----END CERTIFICATE-----
    
    Cert 2:
    ...
    

    Fonte:

    import java.security.GeneralSecurityException;
    import java.security.cert.X509Certificate;
    import java.sql.Connection;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    import org.postgresql.ds.PGSimpleDataSource;
    import org.postgresql.ssl.WrappedFactory;
    
    import javax.xml.bind.DatatypeConverter;
    import java.security.cert.X509Certificate;
    import java.io.StringWriter;
    
    public class ShowPostgreSQLCert {
        public static void main(String[] args) throws Throwable {
            PGSimpleDataSource ds = new PGSimpleDataSource();
            if( args.length != 1 ) {
                System.out.println("Not enough arguments.");
                System.out.println("Usage: ShowPostgreSQLCert ServerName");
                System.exit(1);
            }
            ds.setServerName( args[0] );
            ds.setSsl(true);
            ds.setUser( "" );
            ds.setDatabaseName( "" );
            ds.setPassword( "" );
            ds.setSslfactory(DumperFactory.class.getName());
            try (Connection c = ds.getConnection()) { }
            catch (org.postgresql.util.PSQLException e) {
                // Don't actually want to login
            }
        }
    
        public static class DumperFactory extends WrappedFactory {
            public DumperFactory(String arg) throws GeneralSecurityException {
                SSLContext ctx = SSLContext.getInstance("TLS");
                ctx.init(null, new TrustManager[] { new DumperTM() }, null);
                _factory = ctx.getSocketFactory();
            }
        }
    
        public static String certToString(X509Certificate cert) {
            StringWriter sw = new StringWriter();
            try {
                sw.write("-----BEGIN CERTIFICATE-----\n");
                sw.write(DatatypeConverter.printBase64Binary(cert.getEncoded()).replaceAll("(.{64})", "$1\n"));
                sw.write("\n-----END CERTIFICATE-----\n");
            } catch (java.security.cert.CertificateEncodingException e) {
                e.printStackTrace();
            }
            return sw.toString();
        }
    
        public static class DumperTM implements X509TrustManager {
            public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                for (int i=0; i<certs.length; ++i) {
    
                    System.out.println("Cert " + (i+1) + ":");
                    System.out.println("    Subject: " + certs[i].getSubjectX500Principal().getName());
                    System.out.println("    Issuer: " + certs[i].getIssuerX500Principal().getName());
                    System.out.println("    Not Before: " + certs[i].getNotBefore().toString());
                    System.out.println("    Not After: " + certs[i].getNotAfter().toString());
    
                    System.out.println(certToString(certs[i]));
                }
            }
        }
    }
    
    • 1

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve