如何检查 PostgreSQL 服务器的 SSL 证书?

csd*_*csd 19 postgresql ssl postgresql-9.4

假设有一个 PostgreSQL 服务器正在运行并且它启用了 SSL。使用“标准”Linux 和 PostgreSQL 工具,如何检查其 SSL 证书?

我希望输出类似于您从 running 中获得的输出openssl x509 -text ...。而且我希望有一个单行或两行的命令行答案,这样我就不必求助于运行数据包嗅探器了。

我无权访问 PostgreSQL 服务器,因此无法直接查看其配置文件。

我没有超级用户登录,所以我无法获得ssl_cert_file设置的值,然后pg_read_file就可以了。

使用openssl s_client -connect ...不起作用,因为 PostgreSQL 似乎不想立即进行 SSL 握手。

通过快速查看psql文档,我找不到使其在启动时显示该信息的命令行参数。(虽然它确实向我展示了某些密码信息。)

小智 14

看起来 OpenSSL 的s_client工具-starttls在 1.1.1 中添加了 Postgres 支持,因此您现在可以使用 OpenSSL 命令行工具的全部功能,而无需额外的帮助脚本:

openssl s_client -starttls postgres -connect my.postgres.host:5432 # etc...
Run Code Online (Sandbox Code Playgroud)

参考:

  • 回声-n | openssl s_client -starttls postgres -connect my.postgres.host:5432 | openssl s_client -starttls postgres -connect my.postgres.host:5432 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/.postgresql/root.crt (3认同)

csd*_*csd 11

遵循 Craig Ringer 评论中的想法:

一种选择是修补openssl s_client以与 PostgreSQL 协议握手。通过将自定义 SSLSocketFactory 传递给 PgJDBC,您也可以使用 Java 来实现。我不确定是否有任何简单的选择。

...我写了一个简单的 SSL 套接字工厂。我复制了 PgJDBC 自己的NonValidatingFactory类的代码,只是添加了打印证书的代码。

这是它的样子,当这一切都说完了:

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());
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


miv*_*ivk 10

如果你不想安装java和编译,并且你已经有了python,你可以试试这个python脚本:https : //github.com/thusoy/postgres-mitm/blob/master/postgres_get_server_cert.py

我用它来检查证书日期:

postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -dates
Run Code Online (Sandbox Code Playgroud)

或者对于作为文本的完整证书:

postgres_get_server_cert.py example.com:5432 | openssl x509 -noout -text
Run Code Online (Sandbox Code Playgroud)

  • 要在不安装的情况下使用它:`curl https://raw.githubusercontent.com/thusoy/postgres-mitm/master/postgres_get_server_cert.py | python - example.com:5432`(但请确保您以这种方式执行什么!!) (2认同)