大象鲨,一个监控Postgres网络流量的工具
Elephantshark, a tool to monitor Postgres network traffic

原始链接: https://neon.com/blog/elephantshark-monitor-postgres-network-traffic

## 大象鲨:Postgres网络流量故障排除 大象鲨是由Neon开发的开源Ruby脚本,用于监控和故障排除Postgres网络流量——包括服务器、客户端、驱动程序和ORM。它通过拦截和记录Postgres协议交换、解密SSL/TLS加密连接以及提供详细的消息分析来工作。 与难以处理加密流量的Wireshark不同,大象鲨会解密和重新加密连接,或者可以将密钥写入SSLKEYLOGFILE以便*与*Wireshark一起使用。这允许全面检查进出Postgres数据库的数据流,即使是使用SSL的数据库。 要使用大象鲨,您在一个终端中运行它,并在另一个终端中连接到您的Postgres数据库(例如Neon),并按照说明修改主机名和SSL设置。然后,该工具会记录交换的字节,提供关于连接建立、身份验证、查询和响应的见解。对于需要深入了解Postgres通信的开发人员和数据库管理员来说,它是一个有价值的工具。 更多信息和安装说明请访问其GitHub页面:[https://github.com/neondatabase-labs/elephantshark](https://github.com/neondatabase-labs/elephantshark)

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Elephantshark,一个监控Postgres网络流量的工具 (neon.com) 38点 由 gmac 23小时前 | 隐藏 | 过去 | 收藏 | 2评论 alhirzel 16小时前 [–] 好名字!回复 gmac 15小时前 | 父评论 [–] 谢谢。:) 我是楼主。Elephantshark建立在一些我用了一段时间的简单的Postgres代理Ruby脚本之上。回复 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文
Post image

Elephantshark helps you monitor, understand and troubleshoot Postgres network traffic: that’s Postgres servers, clients, drivers and ORMs talking to Postgres servers, proxies and poolers.

Elephantshark sits between the two parties in a Postgres-protocol exchange, forwarding messages in both directions while parsing and logging them. It is an open-source Ruby script published by Neon and works with any and all Postgres-protocol network traffic. That includes, but isn’t limited to, traffic to and from Neon databases.

https://github.com/neondatabase-labs/elephantshark

Ordinarily Wireshark is great for this kind of thing, but using Wireshark is difficult if a connection is SSL/TLS-encrypted. SSLKEYLOGFILE support was recently merged into libpq, but it won’t be available in a release version for some time. Plus, not all Postgres connections are made with libpq.

To get round this problem, Elephantshark decrypts and re-encrypts a Postgres connection. It then logs and annotates the messages passing through. Or if you prefer to use Wireshark, Elephantshark can enable that too by writing keys to an SSLKEYLOGFILE.

Run elephantshark in one terminal:

% elephantshark
listening ...

In a second terminal, connect to and query a Neon Postgres database via Elephantshark by (1) appending .local.neon.build to the host name and (2) changing channel_binding=require to channel_binding=disable:

% psql 'postgresql://neondb_owner:fake_password@ep-crimson-sound-a8nnh11s.eastus2.azure.neon.tech.local.neon.build/neondb?sslmode=require&channel_binding=disable'
psql (17.5 (Homebrew))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off, ALPN: postgresql)
Type "help" for help.

neondb=> SELECT now();
              now              
-------------------------------
 2025-07-02 11:51:01.721628+00
(1 row)

neondb=> \q

Back in the first terminal, see what bytes got exchanged:

% elephantshark listening … connected at t0 = 2025-09-18 09:19:05 +0100 client -> script: "\x00\x00\x00\x08\x04\xd2\x16\x2f" = SSLRequest script -> client: "S" = SSL supported TLSv1.3/TLS_AES_256_GCM_SHA384 connection established with client server name via SNI: ep-aged-night-a80vx88s.eastus2.azure.neon.tech.local.neon.build client -> script: "\x00\x00\x00\x56" = 86 bytes of startup message "\x00\x03\x00\x00" = protocol version "user\x00" = key "neondb_owner\x00" = value "database\x00" = key "neondb\x00" = value "application_name\x00" = key "psql\x00" = value "client_encoding\x00" = key "UTF8\x00" = value "\x00" = end connecting to Postgres server: ep-aged-night-a80vx88s.eastus2.azure.neon.tech script -> server: "\x00\x00\x00\x08\x04\xd2\x16\x2f" = SSLRequest server -> script: "S" = SSL supported TLSv1.3/TLS_AES_256_GCM_SHA384 connection established with server forwarding client startup message to server script -> server: "\x00\x00\x00\x56" = 86 bytes of startup message "\x00\x03\x00\x00" = protocol version "user\x00" = key "neondb_owner\x00" = value "database\x00" = key "neondb\x00" = value "application_name\x00" = key "psql\x00" = value "client_encoding\x00" = key "UTF8\x00" = value "\x00" = end forwarding all later traffic server -> client: "R" = Authentication "\x00\x00\x00\x2a" = 42 bytes "\x00\x00\x00\x0a" = AuthenticationSASL "SCRAM-SHA-256-PLUS\x00" = SASL mechanism "SCRAM-SHA-256\x00" = SASL mechanism "\x00" = end ^^ 43 bytes forwarded at +0.55s, 0 bytes left in buffer client -> server: "p" = SASLInitialResponse "\x00\x00\x00\x36" = 54 bytes "SCRAM-SHA-256\x00" = selected mechanism "\x00\x00\x00\x20" = 32 bytes follow "n,,n=,r=oyCbUH3BAFTR5K7ky/6sT6sl" = SCRAM client-first-message ^^ 55 bytes forwarded at +0.55s, 0 bytes left in buffer server -> client: "R" = Authentication "\x00\x00\x00\x5c" = 92 bytes "\x00\x00\x00\x0b" = AuthenticationSASLContinue "r=oyCbUH3BAFTR5K7ky/6sT6slO/L2RQWlqi8k5hbEe9Ch4TW1,s=sua0GGw9khvJmqzfirvr4w==,i=4096" = SCRAM server-first-message ^^ 93 bytes forwarded at +0.65s, 0 bytes left in buffer client -> server: "p" = SASLResponse "\x00\x00\x00\x6c" = 108 bytes "c=biws,r=oyCbUH3BAFTR5K7ky/6sT6slO/L2RQWlqi8k5hbEe9Ch4TW1,p=F4I92rJgKR987t7tf93xdumCRuktShWrNvh6MY/rj8M=" = SCRAM client-final-message ^^ 109 bytes forwarded at +0.65s, 0 bytes left in buffer server -> client: "R" = Authentication "\x00\x00\x00\x36" = 54 bytes "\x00\x00\x00\x0c" = AuthenticationSASLFinal "v=ZKr8JIlFdYKw/3GVRnZ1epdKZIfMjXW2Ep3I5JsvNbQ=" = SCRAM server-final-message server -> client: "R" = Authentication "\x00\x00\x00\x08" = 8 bytes "\x00\x00\x00\x00" = AuthenticationOk server -> client: "S" = ParameterStatus "\x00\x00\x00\x17" = 23 bytes "in_hot_standby\x00" = key "off\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x19" = 25 bytes "integer_datetimes\x00" = key "on\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x11" = 17 bytes "TimeZone\x00" = key "GMT\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x1b" = 27 bytes "IntervalStyle\x00" = key "postgres\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x20" = 32 bytes "search_path\x00" = key "\"$user\", public\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x15" = 21 bytes "is_superuser\x00" = key "off\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x1a" = 26 bytes "application_name\x00" = key "psql\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x26" = 38 bytes "default_transaction_read_only\x00" = key "off\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x1a" = 26 bytes "scram_iterations\x00" = key "4096\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x17" = 23 bytes "DateStyle\x00" = key "ISO, MDY\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x23" = 35 bytes "standard_conforming_strings\x00" = key "on\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x27" = 39 bytes "session_authorization\x00" = key "neondb_owner\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x19" = 25 bytes "client_encoding\x00" = key "UTF8\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x22" = 34 bytes "server_version\x00" = key "17.5 (a42a079)\x00" = value server -> client: "S" = ParameterStatus "\x00\x00\x00\x19" = 25 bytes "server_encoding\x00" = key "UTF8\x00" = value server -> client: "K" = BackendKeyData "\x00\x00\x00\x0c" = 12 bytes "\x16\xee\x00\x6a" = process ID "\xa0\x00\x89\x24" = secret key server -> client: "Z" = ReadyForQuery "\x00\x00\x00\x05" = 5 bytes "I" = idle ^^ 514 bytes forwarded at +0.76s, 0 bytes left in buffer client -> server: "Q" = Query "\x00\x00\x00\x12" = 18 bytes "SELECT now();\x00" = query ^^ 19 bytes forwarded at +2.17s, 0 bytes left in buffer server -> client: "T" = RowDescription "\x00\x00\x00\x1c" = 28 bytes "\x00\x01" = 1 columns follow "now\x00" = column name "\x00\x00\x00\x00" = table OID: 0 "\x00\x00" = table attrib no: 0 "\x00\x00\x04\xa0" = type OID: 1184 "\x00\x08" = type length: 8 "\xff\xff\xff\xff" = type modifier: -1 "\x00\x00" = format: text server -> client: "D" = DataRow "\x00\x00\x00\x27" = 39 bytes "\x00\x01" = 1 columns follow "\x00\x00\x00\x1d" = 29 bytes "2025-09-18 08:19:08.270142+00" = column value server -> client: "C" = CommandComplete "\x00\x00\x00\x0d" = 13 bytes "SELECT 1\x00" = command tag server -> client: "Z" = ReadyForQuery "\x00\x00\x00\x05" = 5 bytes "I" = idle ^^ 89 bytes forwarded at +2.3s, 0 bytes left in buffer client -> server: "X" = Terminate "\x00\x00\x00\x04" = 4 bytes ^^ 5 bytes forwarded at +3.7s, 0 bytes left in buffer client hung up connection end listening …

To find out more and/or to install Elephantshark, check out the README on GitHub. You can also find out more about Neon, or sign up today for free.

联系我们 contact @ memedata.com