在 PostgreSQL 中设置调试情况以更好地理解 OpenSSL API

打印 上一主题 下一主题

主题 1933|帖子 1933|积分 5799

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 概述

本文将介绍如何设置一个 gdb 调试情况,以深入了解 TLS 毗连并更好地理解 PostgreSQL 中使用的 OpenSSL API。
2. 使用调试符号构建 OpenSSL

首先,检出 OpenSSL 源代码并切换到您想要使用的版本。在本例中,我想使用 OpenSSL 3.0.2 版原来编译 PostgreSQL,因此我切换到 openssl-3.0.2 版本标签。
  1. $ git clone https://github.com/openssl/openssl.git
  2. $ cd openssl
  3. $ git checkout openssl-3.0.2
复制代码
接着,使用以下选项编译带有 gdb 调试支持的 OpenSSL:
  1. $ ./config --prefix=/tmp/ssl --openssldir=/tmp/ssl -d shared -g3 -ggdb -fno-inline -O0 -fno-omit-frame-pointer
  2. $ make -j
  3. $ make install
复制代码
编译带有调试符号的 OpenSSL 可能需要一段时间,最好将 prefix 设置为某个路径,这样可以确保该调试版本得以保存并重复使用。
3. 使用调试版 OpenSSL 库编译 PostgreSQL

同样,首先检出 PostgreSQL 源代码并切换到您感兴趣的分支。在本文中,我将使用 master 分支举行演示:
  1. $ git clone https://github.com/postgres/postgres.git
复制代码
然后,使用启用调试选项的下令编译 PostgreSQL,并特别指定要链接的 OpenSSL 源代码和调试库:
  1. $ ./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
  2. $ make -j
  3. $ make install
复制代码
在这里,必须指定 LDFLAGS="-Wl,-rpath=/tmp/openssl",以确保 PostgreSQL 链接到您指定的 OpenSSL 库,否则它将链接到系统的库。为了进一步确认 PostgreSQL 链接的是您想要的 OpenSSL 库,通常可以运行以下下令:
  1. $ which postgres
  2. /tmp/pgapp/bin/postgres
  3. $ ldd /tmp/pgapp/bin/postgres
  4.     linux-vdso.so.1 (0x00007ffd8a3c1000)
  5.     libssl.so.3 => /tmp/openssl/libssl.so.3 (0x00007f6878dc6000)
  6.     libcrypto.so.3 => /tmp/openssl/libcrypto.so.3 (0x00007f6877c00000)
  7.     libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f68781cf000)
  8.     libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f68780e8000)
  9.     libicui18n.so.70 => /lib/x86_64-linux-gnu/libicui18n.so.70 (0x00007f6877800000)
  10.     libicuuc.so.70 => /lib/x86_64-linux-gnu/libicuuc.so.70 (0x00007f6877605000)
  11.     libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6877200000)
  12.     /lib64/ld-linux-x86-64.so.2 (0x00007f6878e75000)
  13.     libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f6876e00000)
  14.     libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f68780c8000)
  15.     libicudata.so.70 => /lib/x86_64-linux-gnu/libicudata.so.70 (0x00007f6875000000)
复制代码
在这里,检查 libssl.so.3 和 libcrypto.so.3 库,以确保 PostgreSQL 和 psql 链接的是您期望的 OpenSSL 库。在上面的示例中,我的 PostgreSQL 链接到了刚刚编译并安装的、带有调试符号的 OpenSSL 库。
4. 享受调试

要在 TLS 毗连设置或初始化过程中调试 OpenSSL API,您需要一些证书。您可以按照PostgreSQL 文档设置您本身的证书,或者按照以下步调使用 SSL 回归测试文件夹下预构建的证书。步调如下:
  1. $ initdb -D /tmp/pgdata
  2. $ cd postgres/src/test/ssl/ssl
  3. $ cp -pr root_ca.crt server-cn-only+server_ca.crt server-cn-only.key /tmp/pgdata/
  4. $ chmod 600 /tmp/pgdata/server-cn-only.key
复制代码
然后,编辑 postgresql.conf 文件以启用 SSL 并指定证书相关的文件。例如:
  1. $ vim pgdata/postgresql.conf
  2. ssl = on
  3. ssl_ca_file = 'root_ca.crt'
  4. ssl_cert_file = 'server-cn-only+server_ca.crt'
  5. ssl_key_file = 'server-cn-only.key'
复制代码
在这里,启用了 SSL,根 CA 证书指向 root_ca.crt,并使用实体证书 server-cn-only 和中心 CA server_ca 作为 PostgreSQL 服务器的证书,同时对应的私钥文件也已设置。
如今,我们已经准备好使用 gdb 调试 OpenSSL API。
  1. $ gdb -args postgres -D pgdata
  2. ...
  3. (gdb) b be_tls_init
  4. Breakpoint 1 at 0x419bf2: file be-secure-openssl.c, line 95.
  5. (gdb) b SSL_CTX_use_certificate_chain_file
  6. Breakpoint 2 at 0xd9970
  7. Breakpoint 1, be_tls_init (isServerStart=true) at be-secure-openssl.c:95
  8. 95      int         ssl_ver_min = -1;
  9. (gdb) c
  10. Continuing.
  11. Breakpoint 2, SSL_CTX_use_certificate_chain_file (ctx=0x5555561e9ba0, file=0x5555561ddc08 "server-cn-only+server_ca.crt") at ssl/ssl_rsa.c:534
  12. 534     return use_certificate_chain_file(ctx, NULL, file);
  13. (gdb) s
  14. use_certificate_chain_file (ctx=0x5555561e9ba0, ssl=0x0, file=0x5555561ddc08 "server-cn-only+server_ca.crt") at ssl/ssl_rsa.c:419
  15. 419 {
  16. 420     BIO *in;
  17. 421     int ret = 0;
  18. 422     X509 *x = NULL;
  19. 423     pem_password_cb *passwd_callback;
  20. (gdb) l
  21. 414  * Read a file that contains our certificate in "PEM" format, possibly
  22. 415  * followed by a sequence of CA certificates that should be sent to the peer
  23. 416  * in the Certificate message.
  24. 417  */
  25. 418 static int use_certificate_chain_file(SSL_CTX *ctx, SSL *ssl, const char *file)
  26. 419 {
  27. 420     BIO *in;
  28. 421     int ret = 0;
  29. 422     X509 *x = NULL;
  30. 423     pem_password_cb *passwd_callback;
  31. (gdb) p file
  32. $2 = 0x5555561ddc08 "server-cn-only+server_ca.crt"
  33. (gdb) pt ctx
  34. type = struct ssl_ctx_st {
  35.     OSSL_LIB_CTX *libctx;
  36.     const SSL_METHOD *method;
  37.     struct stack_st_SSL_CIPHER *cipher_list;
  38.     struct stack_st_SSL_CIPHER *cipher_list_by_id;
  39.     struct stack_st_SSL_CIPHER *tls13_ciphersuites;
  40.     struct x509_store_st *cert_store;
复制代码
在上面的示例中,我启用了两个断点:be_tls_init 和 SSL_CTX_use_certificate_chain_file。be_tls_init 用来确保 PostgreSQL 已启用调试符号,而 SSL_CTX_use_certificate_chain_file 用来深入分析 OpenSSL。在这里,我们可以输出这个复杂的 ctx 对象作为示例。
通过这个调试情况设置,您应该可以或许调试 psql 客户端端,深入了解整个 TLS 过程。
5. 总结

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我可以不吃啊

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表