<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michael Placzek</title>
    <description>The latest articles on DEV Community by Michael Placzek (@heymaikol).</description>
    <link>https://dev.to/heymaikol</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4099690%2F3213ac26-f0bf-41d0-89b2-b85c85bca0ee.jpg</url>
      <title>DEV Community: Michael Placzek</title>
      <link>https://dev.to/heymaikol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/heymaikol"/>
    <language>en</language>
    <item>
      <title>I spent months building an open-source network diagnostic tool. Now I’m trying to make my first dollar.</title>
      <dc:creator>Michael Placzek</dc:creator>
      <pubDate>Sat, 19 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/heymaikol/i-spent-months-building-an-open-source-network-diagnostic-tool-now-im-trying-to-make-my-first-b1k</link>
      <guid>https://dev.to/heymaikol/i-spent-months-building-an-open-source-network-diagnostic-tool-now-im-trying-to-make-my-first-b1k</guid>
      <description>&lt;p&gt;For the last few months, I've been building &lt;strong&gt;Network Doctor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It's a cross-platform terminal application for answering a deceptively simple question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Where is this connection actually breaking?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When something on the network fails, the normal troubleshooting process tends to look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;ping&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;dig&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Try &lt;code&gt;curl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check the proxy&lt;/li&gt;
&lt;li&gt;Try another DNS server&lt;/li&gt;
&lt;li&gt;Run a traceroute&lt;/li&gt;
&lt;li&gt;Check TLS&lt;/li&gt;
&lt;li&gt;Try another network&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eventually, if you're experienced enough and collect enough evidence, you figure out whether the problem is your machine, your local network, DNS, the path, a proxy, or the service itself.&lt;/p&gt;

&lt;p&gt;I wanted one tool that could reason across those layers instead of making the user interpret each command independently.&lt;/p&gt;

&lt;p&gt;That became &lt;strong&gt;Network Doctor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Today it runs on &lt;strong&gt;Linux, macOS, and Windows&lt;/strong&gt; and checks things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;interfaces and local connectivity&lt;/li&gt;
&lt;li&gt;DNS&lt;/li&gt;
&lt;li&gt;public and encrypted DNS&lt;/li&gt;
&lt;li&gt;TCP&lt;/li&gt;
&lt;li&gt;TLS&lt;/li&gt;
&lt;li&gt;HTTP and HTTPS&lt;/li&gt;
&lt;li&gt;proxies&lt;/li&gt;
&lt;li&gt;routing&lt;/li&gt;
&lt;li&gt;path MTU&lt;/li&gt;
&lt;li&gt;service-specific connectivity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also has Watch Mode for intermittent failures, diagnostic snapshots, remote diagnosis, two-sided diagnosis, service profiles, and a network simulator with deliberately broken networks.&lt;/p&gt;

&lt;p&gt;I just released &lt;strong&gt;v1.17.3&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But this release also marks a different milestone for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project has made $0
&lt;/h2&gt;

&lt;p&gt;I've spent a lot of time building Network Doctor.&lt;/p&gt;

&lt;p&gt;People use it. People star it. People contribute to it. It's available through package managers.&lt;/p&gt;

&lt;p&gt;Other projects have even started pointing their own users toward it for network troubleshooting.&lt;/p&gt;

&lt;p&gt;But financially, it has made me &lt;strong&gt;$0&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I don't want to turn the useful parts of Network Doctor into paid features just because I want the project to become sustainable.&lt;/p&gt;

&lt;p&gt;So I'm trying something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paid help, not a paid binary
&lt;/h2&gt;

&lt;p&gt;Network Doctor can generate a sanitized support snapshot locally:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
netdoc --support support.ndoc example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>opensource</category>
      <category>devtools</category>
      <category>networking</category>
      <category>go</category>
    </item>
    <item>
      <title>Looking for Contributors: Good First Issues in Network Doctor</title>
      <dc:creator>Michael Placzek</dc:creator>
      <pubDate>Thu, 17 Sep 2026 05:02:39 +0000</pubDate>
      <link>https://dev.to/heymaikol/looking-for-contributors-good-first-issues-in-network-doctor-3fcb</link>
      <guid>https://dev.to/heymaikol/looking-for-contributors-good-first-issues-in-network-doctor-3fcb</guid>
      <description>&lt;p&gt;I’ve been working on Network Doctor, an open-source Go TUI for diagnosing network problems, and I’d like to get more people involved in the project.&lt;/p&gt;

&lt;p&gt;I currently have a few issues ready for contributors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good first issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  #110 - Make the causal-evidence golden mutation test non-vacuous
&lt;/h3&gt;

&lt;p&gt;A small, test-focused issue. No production behavior changes are needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/heymaikol/network-doctor/issues/110" rel="noopener noreferrer"&gt;https://github.com/heymaikol/network-doctor/issues/110&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  #111 - Add hermetic tests for macOS and Windows SSID command wrappers
&lt;/h3&gt;

&lt;p&gt;A slightly larger testing task involving the existing platform-specific SSID code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/heymaikol/network-doctor/issues/111" rel="noopener noreferrer"&gt;https://github.com/heymaikol/network-doctor/issues/111&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking for something more involved?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  #97 - Bound hunt shard inputs before &lt;code&gt;netdoc-sim merge&lt;/code&gt; decodes them
&lt;/h3&gt;

&lt;p&gt;This one involves input-size enforcement and is better suited to someone already comfortable with Go.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/heymaikol/network-doctor/issues/97" rel="noopener noreferrer"&gt;https://github.com/heymaikol/network-doctor/issues/97&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are also several field-validation issues for contributors who have access to environments I can’t easily reproduce, including macOS, IPv6-only networks, VPN split DNS, captive portals, and managed proxy networks.&lt;/p&gt;

&lt;p&gt;Network Doctor is here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/heymaikol/network-doctor" rel="noopener noreferrer"&gt;https://github.com/heymaikol/network-doctor&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The contributor setup is intentionally simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/heymaikol/network-doctor.git
&lt;span class="nb"&gt;cd &lt;/span&gt;network-doctor
go &lt;span class="nb"&gt;test&lt;/span&gt; ./...
go run &lt;span class="nb"&gt;.&lt;/span&gt; github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re new to open source, that’s completely fine. The good first issues are scoped so you shouldn’t need to understand the entire project before getting started.&lt;/p&gt;

&lt;p&gt;Questions are welcome too.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>go</category>
      <category>beginners</category>
      <category>networking</category>
    </item>
    <item>
      <title>Ping Works, but HTTPS Doesn't: How to Find What Actually Broke</title>
      <dc:creator>Michael Placzek</dc:creator>
      <pubDate>Sun, 13 Sep 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/heymaikol/ping-works-but-https-doesnt-how-to-find-what-actually-broke-5c6n</link>
      <guid>https://dev.to/heymaikol/ping-works-but-https-doesnt-how-to-find-what-actually-broke-5c6n</guid>
      <description>&lt;p&gt;You've probably seen this before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ping example.com
64 bytes from 93.184.216.34: icmp_seq=1 ttl=54 time=18 ms
64 bytes from 93.184.216.34: icmp_seq=2 ttl=54 time=17 ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the network works, right?&lt;/p&gt;

&lt;p&gt;Then:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ curl https://example.com
curl: (28) Connection timed out
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or your browser spins forever.&lt;/p&gt;

&lt;p&gt;This is one of the most common traps in network troubleshooting: treating a successful ping as proof that "the network is fine."&lt;/p&gt;

&lt;p&gt;It isn't.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ping&lt;/code&gt; answers one fairly narrow question. Your application depends on several other things succeeding after that.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ping actually proves
&lt;/h2&gt;

&lt;p&gt;Ping normally uses ICMP echo requests and replies.&lt;/p&gt;

&lt;p&gt;If a host responds, you've learned something useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;your machine has some working route toward the destination&lt;/li&gt;
&lt;li&gt;packets can travel across at least part of that path&lt;/li&gt;
&lt;li&gt;the destination, or something representing it, is responding to ICMP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But an HTTPS connection needs much more.&lt;/p&gt;

&lt;p&gt;A simplified path looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Network interface
      |
Routing
      |
DNS
      |
TCP connection
      |
TLS handshake
      |
HTTP
      |
Application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And real networks can add more:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Proxy
VPN
Firewall
NAT
MTU problems
IPv4 / IPv6 differences
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful ICMP echo doesn't prove all of those layers work.&lt;/p&gt;

&lt;p&gt;That's why "but I can ping it" often doesn't get you very far.&lt;/p&gt;

&lt;h2&gt;
  
  
  DNS can still be the problem
&lt;/h2&gt;

&lt;p&gt;There are a few variations here.&lt;/p&gt;

&lt;p&gt;Suppose you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping 1.1.1.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it works.&lt;/p&gt;

&lt;p&gt;That says nothing about DNS.&lt;/p&gt;

&lt;p&gt;Try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;getent ahosts example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If name resolution fails, applications using hostnames will still be broken even though you have basic IP connectivity.&lt;/p&gt;

&lt;p&gt;There's another wrinkle: your application and your diagnostic tool may not necessarily use DNS in exactly the same way.&lt;/p&gt;

&lt;p&gt;Your system resolver, a browser using encrypted DNS, a VPN-provided resolver, and a corporate DNS setup can produce different behavior.&lt;/p&gt;

&lt;p&gt;So "DNS works" can sometimes need a more specific question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which DNS, resolving what name, from which environment?&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TCP can fail even when ping succeeds
&lt;/h2&gt;

&lt;p&gt;HTTPS normally needs a TCP connection to port 443.&lt;/p&gt;

&lt;p&gt;That is a completely different exchange from ICMP.&lt;/p&gt;

&lt;p&gt;You can test it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-vz&lt;/span&gt; example.com 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A firewall might allow ICMP while blocking TCP 443.&lt;/p&gt;

&lt;p&gt;The server might be reachable but not listening on the expected port.&lt;/p&gt;

&lt;p&gt;A VPN route might send the application traffic somewhere different.&lt;/p&gt;

&lt;p&gt;A proxy might be involved.&lt;/p&gt;

&lt;p&gt;The path could simply behave differently for the traffic your application actually uses.&lt;/p&gt;

&lt;p&gt;So this situation is perfectly possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ICMP       PASS
TCP :443   FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no contradiction there.&lt;/p&gt;

&lt;p&gt;You're testing two different things.&lt;/p&gt;

&lt;h2&gt;
  
  
  TCP working still doesn't prove HTTPS works
&lt;/h2&gt;

&lt;p&gt;Let's say port 443 accepts a connection.&lt;/p&gt;

&lt;p&gt;Great.&lt;/p&gt;

&lt;p&gt;You're still not done.&lt;/p&gt;

&lt;p&gt;Before HTTP can happen over HTTPS, the client and server need to complete a TLS handshake.&lt;/p&gt;

&lt;p&gt;TLS can fail because of things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;certificate validation&lt;/li&gt;
&lt;li&gt;hostname mismatches&lt;/li&gt;
&lt;li&gt;TLS interception&lt;/li&gt;
&lt;li&gt;protocol incompatibility&lt;/li&gt;
&lt;li&gt;a middlebox interfering with the connection&lt;/li&gt;
&lt;li&gt;the wrong service running on the port&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can inspect that layer with tools such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; example.com:443 &lt;span class="nt"&gt;-servername&lt;/span&gt; example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you can have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DNS    PASS
TCP    PASS
TLS    FAIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is much more useful than saying "the internet is broken."&lt;/p&gt;

&lt;p&gt;You now know roughly where to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  And TLS working doesn't prove HTTP works
&lt;/h2&gt;

&lt;p&gt;Suppose DNS resolves, TCP connects, and TLS completes.&lt;/p&gt;

&lt;p&gt;The server can still return an HTTP error.&lt;/p&gt;

&lt;p&gt;You might get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;403 Forbidden
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;502 Bad Gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;503 Service Unavailable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a very different problem from a dead network path.&lt;/p&gt;

&lt;p&gt;The connection reached the service.&lt;/p&gt;

&lt;p&gt;The service responded.&lt;/p&gt;

&lt;p&gt;The failure has moved farther up the stack.&lt;/p&gt;

&lt;p&gt;That's why I like troubleshooting networking as a sequence of questions rather than one giant "does it work?" test.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget proxies
&lt;/h2&gt;

&lt;p&gt;Proxies make this even more interesting.&lt;/p&gt;

&lt;p&gt;Your shell might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;HTTPS_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://proxy.example:8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while also having something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NO_PROXY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;internal.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now two requests to different hosts may follow completely different paths.&lt;/p&gt;

&lt;p&gt;One can go directly to the destination.&lt;/p&gt;

&lt;p&gt;The other can go through a proxy.&lt;/p&gt;

&lt;p&gt;If the proxy is down, misconfigured, or excluded incorrectly, the symptoms can look like an ordinary network failure even though the direct network path is perfectly healthy.&lt;/p&gt;

&lt;p&gt;Testing both paths can matter.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and, when appropriate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--noproxy&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If one succeeds and the other doesn't, you've learned a lot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Path MTU problems are another nasty case
&lt;/h2&gt;

&lt;p&gt;Some failures are even stranger.&lt;/p&gt;

&lt;p&gt;Small packets work.&lt;/p&gt;

&lt;p&gt;Connections establish.&lt;/p&gt;

&lt;p&gt;Then larger transfers hang or behave unpredictably.&lt;/p&gt;

&lt;p&gt;This can happen when the effective MTU somewhere along the path is smaller than expected and Path MTU Discovery isn't working correctly.&lt;/p&gt;

&lt;p&gt;That's one reason a simple ping can be especially misleading.&lt;/p&gt;

&lt;p&gt;A tiny ICMP echo succeeding isn't proof that larger application traffic can make it through the same path successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  The useful question isn't "does the network work?"
&lt;/h2&gt;

&lt;p&gt;A better question is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the first layer that doesn't work?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Internet broken
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you want to reach something more like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Interface     PASS
DNS           PASS
TCP           PASS
TLS           FAIL
HTTP          SKIPPED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Interface     PASS
DNS           FAIL
TCP           SKIPPED
TLS           SKIPPED
HTTP          SKIPPED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those are very different problems.&lt;/p&gt;

&lt;p&gt;And once you know which layer failed, the number of possible causes becomes much smaller.&lt;/p&gt;

&lt;h2&gt;
  
  
  Doing this manually
&lt;/h2&gt;

&lt;p&gt;You absolutely can troubleshoot this with the standard tools.&lt;/p&gt;

&lt;p&gt;Depending on the problem, I regularly reach for things like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip route
ping
dig
nc
curl
openssl
traceroute
mtr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those tools are excellent.&lt;/p&gt;

&lt;p&gt;The difficult part isn't usually running them.&lt;/p&gt;

&lt;p&gt;It's deciding:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;which test to run next&lt;/li&gt;
&lt;li&gt;what its result actually proves&lt;/li&gt;
&lt;li&gt;which later tests are meaningful after an earlier failure&lt;/li&gt;
&lt;li&gt;whether two failures are related or independent&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is why I built &lt;strong&gt;Network Doctor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The project is open source: &lt;a href="https://github.com/heymaikol/network-doctor" rel="noopener noreferrer"&gt;Network Doctor on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instead of treating connectivity as one yes/no test, it probes the relevant layers independently and tries to identify where the evidence stops.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can check things including the local interface, DNS, TCP, TLS, HTTP, proxy connectivity, and path MTU, then give you a diagnosis based on those results.&lt;/p&gt;

&lt;p&gt;I still use the underlying tools when I need to dig deeper. Network Doctor isn't intended to replace &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;dig&lt;/code&gt;, &lt;code&gt;mtr&lt;/code&gt;, or the rest.&lt;/p&gt;

&lt;p&gt;The goal is to get to the right one faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reverse is also true: ping can fail while everything works
&lt;/h2&gt;

&lt;p&gt;There's another reason not to treat ping as the final authority.&lt;/p&gt;

&lt;p&gt;Some networks and servers simply block or deprioritize ICMP.&lt;/p&gt;

&lt;p&gt;You can see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ping: no reply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while this works perfectly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://example.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the application's perspective, that's not an outage.&lt;/p&gt;

&lt;p&gt;The traffic you actually care about succeeded.&lt;/p&gt;

&lt;p&gt;This is why good diagnostics need to test the protocol that matters instead of assuming ICMP represents every other kind of traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  A better troubleshooting habit
&lt;/h2&gt;

&lt;p&gt;The next time you hear:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It can't be the network. Ping works."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ask what layer has actually been tested.&lt;/p&gt;

&lt;p&gt;Work upward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Do I have an interface and route?
        ↓
Can I resolve the name?
        ↓
Can I reach the service's port?
        ↓
Can I complete TLS?
        ↓
Can I make the application request?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is a VPN or proxy involved, test that path too.&lt;/p&gt;

&lt;p&gt;The goal isn't to collect as much command output as possible.&lt;/p&gt;

&lt;p&gt;The goal is to find the boundary between &lt;strong&gt;working&lt;/strong&gt; and &lt;strong&gt;broken&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you know that boundary, network troubleshooting gets a lot less mysterious.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>networking</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Debugging a Network Problem From Another Machine</title>
      <dc:creator>Michael Placzek</dc:creator>
      <pubDate>Sat, 29 Aug 2026 13:00:00 +0000</pubDate>
      <link>https://dev.to/heymaikol/debugging-a-network-problem-from-another-machine-1fam</link>
      <guid>https://dev.to/heymaikol/debugging-a-network-problem-from-another-machine-1fam</guid>
      <description>&lt;p&gt;One of the most useful questions in network troubleshooting is also one of the simplest:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it fail from another machine too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If a website will not load on my laptop, trying it from another computer can immediately change the investigation.&lt;/p&gt;

&lt;p&gt;If it works there, the service probably is not down. Something about my machine, DNS configuration, VPN, firewall, route, or network path is different.&lt;/p&gt;

&lt;p&gt;If it fails there too, the problem may be farther upstream.&lt;/p&gt;

&lt;p&gt;I wanted Network Doctor to be able to ask that question directly.&lt;/p&gt;

&lt;p&gt;So I added remote diagnosis over SSH.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; ideapad github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of running the diagnosis locally, Network Doctor connects to &lt;code&gt;ideapad&lt;/code&gt;, runs the checks there, and reports the result back on my machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why another vantage point matters
&lt;/h2&gt;

&lt;p&gt;A network failure is always observed from somewhere.&lt;/p&gt;

&lt;p&gt;Suppose &lt;code&gt;github.com&lt;/code&gt; is unreachable from my workstation.&lt;/p&gt;

&lt;p&gt;I can test DNS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then TCP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-vz&lt;/span&gt; github.com 443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then TLS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openssl s_client &lt;span class="nt"&gt;-connect&lt;/span&gt; github.com:443
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Maybe I inspect my routes, VPN, proxy settings, or firewall.&lt;/p&gt;

&lt;p&gt;Those tests are useful, but they all share one property: they are observing the network from the same machine.&lt;/p&gt;

&lt;p&gt;Trying the same destination from another machine gives me a new piece of evidence.&lt;/p&gt;

&lt;p&gt;Imagine this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thelio:
DNS       PASS
TCP 443   FAIL

Ideapad:
DNS       PASS
TCP 443   PASS
TLS       PASS
HTTPS     PASS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That difference is interesting.&lt;/p&gt;

&lt;p&gt;GitHub clearly is not universally unreachable. The second machine just reached it.&lt;/p&gt;

&lt;p&gt;Now I have a much smaller problem to investigate: what is different about the path from Thelio?&lt;/p&gt;

&lt;p&gt;That is often more useful than running another five commands on Thelio.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning that into a command
&lt;/h2&gt;

&lt;p&gt;Network Doctor already runs network checks as a dependency graph.&lt;/p&gt;

&lt;p&gt;For an HTTPS target, for example, it can test things such as the local interface, DNS resolution, TCP connectivity, TLS, HTTP, routing, and path MTU.&lt;/p&gt;

&lt;p&gt;Normally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Diagnose github.com from this machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With &lt;code&gt;--via&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; ideapad github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;it becomes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Diagnose github.com from ideapad.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The SSH machine is the vantage point. My local machine is just controlling the run and displaying the result.&lt;/p&gt;

&lt;p&gt;That distinction becomes especially useful with service profiles.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; ideapad &lt;span class="nt"&gt;--profile&lt;/span&gt; github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The GitHub profile independently checks GitHub's website, API, normal SSH endpoint, and alternate SSH endpoint.&lt;/p&gt;

&lt;p&gt;So I can ask a more useful question than simply "can the other computer ping GitHub?"&lt;/p&gt;

&lt;p&gt;I can ask whether the actual service paths I care about work from there.&lt;/p&gt;

&lt;h2&gt;
  
  
  It also works across operating systems
&lt;/h2&gt;

&lt;p&gt;One of my tests involved a Linux workstation controlling a Windows machine over SSH.&lt;/p&gt;

&lt;p&gt;The command was still just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; ideapad &lt;span class="nt"&gt;--profile&lt;/span&gt; github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The remote worker ran on Windows, while I launched and viewed the diagnosis from Linux.&lt;/p&gt;

&lt;p&gt;I like this because the two machines do not need to be identical.&lt;/p&gt;

&lt;p&gt;In fact, sometimes it is more interesting when they are not.&lt;/p&gt;

&lt;p&gt;A Windows laptop and a Linux workstation might have different DNS configuration, routes, VPN software, firewall rules, interfaces, or network locations.&lt;/p&gt;

&lt;p&gt;Those differences are exactly what can make a second vantage point useful.&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not just "run the command over SSH"
&lt;/h2&gt;

&lt;p&gt;I could obviously do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh ideapad netdoc github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And sometimes that is perfectly sufficient.&lt;/p&gt;

&lt;p&gt;The reason I wanted remote execution inside Network Doctor is that the location of the probe becomes part of the diagnostic model.&lt;/p&gt;

&lt;p&gt;That means the same mechanism can be used with profiles and structured output instead of treating the remote command as an unrelated terminal session.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; ideapad &lt;span class="nt"&gt;--profile&lt;/span&gt; github
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;still means "run the GitHub diagnostic profile," while &lt;code&gt;ideapad&lt;/code&gt; answers the separate question of where those probes should originate.&lt;/p&gt;

&lt;p&gt;I think that separation is useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What should I test?     --profile github
Where should I test it? --via ideapad
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What this can tell you
&lt;/h2&gt;

&lt;p&gt;A second vantage point does not magically identify every network problem.&lt;/p&gt;

&lt;p&gt;But it can eliminate a lot of possibilities quickly.&lt;/p&gt;

&lt;p&gt;If the same destination fails from both machines in the same way, that is evidence that the issue may not be specific to one host.&lt;/p&gt;

&lt;p&gt;If it fails from one machine but works from another, host-specific or path-specific explanations become much more interesting.&lt;/p&gt;

&lt;p&gt;If DNS answers differ, investigate DNS.&lt;/p&gt;

&lt;p&gt;If DNS agrees but TCP connectivity differs, look farther down the path.&lt;/p&gt;

&lt;p&gt;If TCP succeeds from both but TLS fails from only one, that is another useful distinction.&lt;/p&gt;

&lt;p&gt;The important part is not simply having more probes.&lt;/p&gt;

&lt;p&gt;It is having &lt;strong&gt;different observations that can disagree&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Disagreement is often where the useful information is.&lt;/p&gt;

&lt;h2&gt;
  
  
  The larger idea
&lt;/h2&gt;

&lt;p&gt;Network troubleshooting tools usually become collections of tests:&lt;/p&gt;

&lt;p&gt;ping something.&lt;/p&gt;

&lt;p&gt;Resolve something.&lt;/p&gt;

&lt;p&gt;Open a socket.&lt;/p&gt;

&lt;p&gt;Inspect a route.&lt;/p&gt;

&lt;p&gt;Check a certificate.&lt;/p&gt;

&lt;p&gt;Those are necessary, but I am increasingly interested in the reasoning that connects the observations.&lt;/p&gt;

&lt;p&gt;A diagnostic tool should help answer:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does this result rule out?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Remote diagnosis adds another way to obtain that evidence.&lt;/p&gt;

&lt;p&gt;Instead of endlessly probing the same broken machine, sometimes the best next probe is the same test from somewhere else.&lt;/p&gt;

&lt;p&gt;That is now one command in Network Doctor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netdoc &lt;span class="nt"&gt;--via&lt;/span&gt; another-machine target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Network Doctor is open source, and I would especially like to hear about cases where comparing two machines gives a misleading result or where the remote diagnosis reaches the wrong conclusion.&lt;/p&gt;

&lt;p&gt;Those are the interesting bugs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/heymaikol/network-doctor" rel="noopener noreferrer"&gt;https://github.com/heymaikol/network-doctor&lt;/a&gt;&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>opensource</category>
      <category>go</category>
      <category>networking</category>
    </item>
  </channel>
</rss>
