在 PostgreSQL 中设置调试环境以更好地理解 OpenSSL API

1. 概述

本文将介绍如何设置一个 gdb 调试环境,以深入了解 TLS 连接并更好地理解 PostgreSQL 中使用的 OpenSSL API。

2. 使用调试符号构建 OpenSSL

首先,检出 OpenSSL 源代码并切换到您想要使用的版本。在本例中,我想使用 OpenSSL 3.0.2 版本来编译 PostgreSQL,因此我切换到 openssl-3.0.2 版本标签。

$ git clone https://github.com/openssl/openssl.git
$ cd openssl
$ git checkout openssl-3.0.2

接着,使用以下选项编译带有 gdb 调试支持的 OpenSSL:

$ ./config --prefix=/tmp/ssl --openssldir=/tmp/ssl -d shared -g3 -ggdb -fno-inline -O0 -fno-omit-frame-pointer
$ make -j
$ make install

编译带有调试符号的 OpenSSL 可能需要一段时间,最好将 prefix 设置为某个路径,这样可以确保该调试版本得以保存并重复使用。

3. 使用调试版 OpenSSL 库编译 PostgreSQL

同样,首先检出 PostgreSQL 源代码并切换到您感兴趣的分支。在本文中,我将使用 master 分支进行演示:

$ git clone https://github.com/postgres/postgres.git

然后,使用启用调试选项的命令编译 PostgreSQL,并特别指定要链接的 OpenSSL 源代码和调试库:

$ ./configure --prefix=/tmp/pgapp --enable-tap-tests --enable-debug CC="gcc -std=gnu99" CFLAGS="-O0 -fno-omit-frame-pointer -I/tmp/openssl/include" LDFLAGS="-Wl,-rpath=/tmp/openssl" --with-openssl
$ make -j
$ make install

在这里,必须指定 LDFLAGS="-Wl,-rpath=/tmp/openssl",以确保 PostgreSQL 链接到您指定的 OpenSSL 库,否则它将链接到系统的库。为了进一步确认 PostgreSQL 链接的是您想要的 OpenSSL 库,通常可以运行以下命令:

$ which postgres
/tmp/pgapp/bin/postgres
$ ldd /tmp/pgapp/bin/postgres
    linux-vdso.so.1 (0x00007ffd8a3c1000)
    libssl.so.3 => /tmp/openssl/libssl.so.3 (0x00007f6878dc6000)
    libcrypto.so.3 => /tmp/openssl/libcrypto.so.3 (0x00007f6877c00000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f68781cf000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f68780e8000)
    libicui18n.so.70 => /lib/x86_64-linux-gnu/libicui18n.so.70 (0x00007f6877800000)
    libicuuc.so.70 => /lib/x86_64-linux-gnu/libicuuc.so.70 (0x00007f6877605000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6877200000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6878e75000)
    libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6876e00000)
    libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f68780c8000)
    libicudata.so.70 => /lib/x86_64-linux-gnu/libicudata.so.70 (0x00007f6875000000)

在这里,检查 libssl.so.3libcrypto.so.3 库,以确保 PostgreSQL 和 psql 链接的是您期望的 OpenSSL 库。在上面的示例中,我的 PostgreSQL 链接到了刚刚编译并安装的、带有调试符号的 OpenSSL 库。

4. 享受调试

要在 TLS 连接设置或初始化过程中调试 OpenSSL API,您需要一些证书。您可以按照PostgreSQL 文档设置您自己的证书,或者按照以下步骤使用 SSL 回归测试文件夹下预构建的证书。步骤如下:

$ initdb -D /tmp/pgdata
$ cd postgres/src/test/ssl/ssl
$ cp -pr root_ca.crt server-cn-only+server_ca.crt server-cn-only.key /tmp/pgdata/
$ chmod 600 /tmp/pgdata/server-cn-only.key

然后,编辑 postgresql.conf 文件以启用 SSL 并指定证书相关的文件。例如:

$ vim pgdata/postgresql.conf
ssl = on
ssl_ca_file = 'root_ca.crt'
ssl_cert_file = 'server-cn-only+server_ca.crt'
ssl_key_file = 'server-cn-only.key'

在这里,启用了 SSL,根 CA 证书指向 root_ca.crt,并使用实体证书 server-cn-only 和中间 CA server_ca 作为 PostgreSQL 服务器的证书,同时对应的私钥文件也已设置。

现在,我们已经准备好使用 gdb 调试 OpenSSL API。

$ gdb -args postgres -D pgdata
...

(gdb) b be_tls_init
Breakpoint 1 at 0x419bf2: file be-secure-openssl.c, line 95.
(gdb) b SSL_CTX_use_certificate_chain_file
Breakpoint 2 at 0xd9970

Breakpoint 1, be_tls_init (isServerStart=true) at be-secure-openssl.c:95
95      int         ssl_ver_min = -1;
(gdb) c
Continuing.

Breakpoint 2, SSL_CTX_use_certificate_chain_file (ctx=0x5555561e9ba0, file=0x5555561ddc08 "server-cn-only+server_ca.crt") at ssl/ssl_rsa.c:534
534     return use_certificate_chain_file(ctx, NULL, file);
(gdb) s
use_certificate_chain_file (ctx=0x5555561e9ba0, ssl=0x0, file=0x5555561ddc08 "server-cn-only+server_ca.crt") at ssl/ssl_rsa.c:419
419 {
420     BIO *in;
421     int ret = 0;
422     X509 *x = NULL;
423     pem_password_cb *passwd_callback;

(gdb) l
414  * Read a file that contains our certificate in "PEM" format, possibly
415  * followed by a sequence of CA certificates that should be sent to the peer
416  * in the Certificate message.
417  */
418 static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
419 {
420     BIO *in;
421     int ret = 0;
422     X509 *x = NULL;
423     pem_password_cb *passwd_callback;

(gdb) p file
$2 = 0x5555561ddc08 "server-cn-only+server_ca.crt"

(gdb) pt ctx
type = struct ssl_ctx_st {
    OSSL_LIB_CTX *libctx;
    const SSL_METHOD *method;
    struct stack_st_SSL_CIPHER *cipher_list;
    struct stack_st_SSL_CIPHER *cipher_list_by_id;
    struct stack_st_SSL_CIPHER *tls13_ciphersuites;
    struct x509_store_st *cert_store;

在上面的示例中,我启用了两个断点:be_tls_initSSL_CTX_use_certificate_chain_filebe_tls_init 用来确保 PostgreSQL 已启用调试符号,而 SSL_CTX_use_certificate_chain_file 用来深入分析 OpenSSL。在这里,我们可以输出这个复杂的 ctx 对象作为示例。

通过这个调试环境设置,您应该能够调试 psql 客户端端,深入了解整个 TLS 过程。

5. 总结

在本文中,解释了如何设置一个简单的 gdb 调试环境,以深入了解 OpenSSL,希望它对您有所帮助。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值