It can be difficult to trace network traffic from a Node.js application. Typically, folks will just instrument some logging to check that everything is working as it is supposed to. Unfortunately, sometimes there are too many abstractions or possible race conditions to accurately get a good trace. To get the most objective possible trace of network traffic Wireshark can be used.
Wireshark is a network protocol analyzer that makes it extremely simple to capture and trace network activity from any source on your computer. It also has tools built in to decrypt traffic like that of HTTPS (TLS / SSL).
In the case of capturing HTTPS (TLS / SSL) traffic, there is some setup before capturing traffic. If all you need is to capture unencrypted HTTP, then skip to the Wireshark installation, since Wireshark can do so out-of-the-box.
If you'd like to decrypt HTTPS (TLS / SSL) you will need to set a path via an environmental variable to collect SSL keys for use in Wireshark. This same environmental variable works for most browsers and some other applications as well.
export SSLKEYLOGFILE=/path/to/ssl_key_log_file.log
Set the path and file name to whatever you would like.
You can use NODE_OPTIONS to instruct Node to log TLS keyfile information: NODE_OPTIONS='--tls-keylog="/path/to/ssl_key_log_file.log"'
That can be used with tools like yarn to log TLS key material:
NODE_OPTIONS='--tls-keylog="/path/to/ssl_key_log_file.log"' yarn yourcommand
I've used this to check for network calls in unit tests
First things first, you must install Wireshark program. On macOS you can use
brew
to not only install the CLI, but the UI app as well:
brew cask install wireshark
For Wireshark to be able to decrypt HTTPS (TLS / SSL) traffic it needs to read
the SSL Key log generated by Node.js or other applications. To configure this
for Wireshark, open up the application and then open the preferences for
Wireshark. Once the preferences are open, open the "Protocols" dropdown in the
left sidebar menu listing and scroll down to "TLS", then click on it. On older
versions of Wireshark, look for "SSL" instead of "TLS". Once the settings for
"TLS" (or "SSL" for older versions) is open, look for the "(Pre)-Master-Secret
log filename" setting and set the path to the same one that was configured above
via the SSLKEYLOGFILE
environmental variable. You might need to create an
empty file at the path given.
Now that you are all setup, you can begin capturing traffic. Open up Wireshark
and select the capture interface, which for macOS is usually en0
(Wi-Fi).
Once capturing has begun you should start to see logs of all sorts of traffic to be listed, unless you are not connected to the internet.
This traffic can be overwhelming and mostly unrelated to Node.js or the application you are trying to inspect. This where filters come in handy.
For example, to filter requests on a domain:
http.host matches "google.com"
Or to filter on a certain IP address:
ip.addr = 255.255.255.255
Filters can also be combined with conditional operators &&
and ||
.
Once capturing has begun, you can start your app up as normal and try to cause network activity that is in need of being traced.
Hopefully, with a combination with the filters you will be able to find the exact requests and responses you are looking for. If you find either a request or a response you can right click on a line item and select "Follow > HTTP Stream" to see the both of the request and response.
Additionally, you can save any traffic captured for later use or to send to peers for inspection.
Forked and updated info on NodeJS keyhole logging. I found that an absolute path worked when a relative
~
path did not, perhaps an issue on the NODE_OPTIONS side?