Git SSH Connection Exception: github.com Resolution Error Caused by WSL2 DNS Hijacking

Symptoms

When using Git to push code to GitHub via SSH in a Windows environment, a connection reset error suddenly occurred:

1
2
3
4
5
6
$ git push
Connection reset by xxx.xxx.x.x port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Even more strangely, pushes were working fine the day before, but suddenly failed today.

Troubleshooting

Initial Diagnosis

First, test the SSH connection:

1
2
$ ssh -T [email protected]
Connection reset by xxx.xxx.x.x port 22

Check the remote repository configuration:

1
2
3
$ git remote -v
origin [email protected]:username/repo.git (fetch)
origin [email protected]:username/repo.git (push)

The remote address configuration is correct, so the problem lies elsewhere.

DNS Resolution Anomaly

Try pinging GitHub:

1
2
3
4
$ ping github.com

Pinging github.com [xxx.xxx.x.x] with 32 bytes of data:
Reply from xxx.xxx.x.x: bytes=32 time<1ms TTL=64

Issue Exposed: github.com resolved to a local network IP address (127.x.x.x range) instead of GitHub’s real public IP (which should be in the x.x.x.x range).

Excluding Common Causes

Following standard troubleshooting steps, check one by one:

  1. hosts File:

    1
    type C:\Windows\System32\drivers\etc\hosts | findstr github

    Result: No relevant records ✓

  2. Port Occupation:

    1
    netstat -ano | findstr xxx.xxx.x.x

    Result: No process listening ✓

  3. VPN/Proxy Configuration:

    • Check Proxifier rules: Normal
    • Check Git configuration: No anomalies

Pinpointing the Root Cause: WSL2

Noticed that WSL2 (Windows Subsystem for Linux) is running in the background, which is a key clue.

WSL2 Network Architecture:

  • WSL2 uses a virtual network adapter (Hyper-V Virtual Switch).
  • It has an independent virtual IP address range (usually 172.x.x.x or 127.x.x.x).
  • It may intercept and redirect Windows DNS queries.

Verifying the Hypothesis:

1
2
3
4
5
6
7
8
# Shutdown WSL
wsl --shutdown

# Flush DNS cache
ipconfig /flushdns

# Retest
ping github.com

Result: github.com resolves correctly to 140.82.x.x. Problem confirmed!

Solution

Root Cause Analysis

WSL2 automatically generates the /etc/resolv.conf file by default, and its DNS configuration may conflict with the Windows host, causing:

  1. DNS queries within WSL are forwarded to Windows.
  2. Windows DNS queries are intercepted by WSL.
  3. Certain domains (like github.com) are incorrectly resolved to WSL’s virtual network address.

Permanent Fix Steps

Step 1: Disable WSL’s Automatic DNS Generation

Execute in the WSL terminal:

1
2
# Edit WSL configuration file
sudo nano /etc/wsl.conf

Add the following configuration:

1
2
[network]
generateResolvConf = false

Save and exit (Ctrl+XYEnter).

This step tells WSL not to automatically generate DNS configuration, preventing conflicts with Windows.

Step 2: Manually Configure WSL DNS

1
2
3
4
5
# Remove the automatically generated resolv.conf
sudo rm /etc/resolv.conf

# Create new DNS configuration
sudo nano /etc/resolv.conf

Write in reliable public DNS servers:

1
2
nameserver 1.1.1.1
nameserver 8.8.8.8

Lock the file to prevent it from being overwritten:

1
sudo chattr +i /etc/resolv.conf

Step 3: Restart WSL to Apply Configuration

In Windows PowerShell (Admin):

1
wsl --shutdown

Wait a few seconds, then restart WSL:

1
wsl

Step 4: Verify the Fix

Verify DNS in WSL:

1
2
3
4
5
cat /etc/resolv.conf
# Should show: nameserver 1.1.1.1

nslookup github.com
# Should resolve to 140.82.x.x

Verify in Windows:

1
2
3
4
5
6
7
8
9
ipconfig /flushdns
ping github.com
# Should resolve to 140.82.x.x

ssh -T [email protected]
# Should output: Hi username! You've successfully authenticated...

git push
# Push successful

Technical Principles

WSL2 Network Model

WSL2’s network implementation is completely different from WSL1:

Feature WSL1 WSL2
Network Implementation Shared Windows Network Stack Independent Virtual Network (Hyper-V)
IP Address Same as Windows Independent Virtual IP
DNS Resolution Uses Windows DNS directly Automatically generates /etc/resolv.conf

Conditions Triggering DNS Hijacking

  1. WSL2 DNS service (systemd-resolved or similar) is running.
  2. Improper priority configuration of Windows network adapters.
  3. WSL virtual network adapter Metric value is lower than the physical network card.
  4. DNS queries are routed to WSL’s virtual IP.

Why is generateResolvConf = false Effective?

By default, WSL2 automatically generates /etc/resolv.conf based on the Windows network configuration, which can lead to:

  • Circular Reference: WSL’s DNS points to Windows, and Windows DNS queries are intercepted by WSL.
  • Cache Pollution: Incorrect resolution results are cached, continuously affecting subsequent queries.

Disabling automatic generation allows WSL to use fixed public DNS (1.1.1.1), completely cutting off the coupling with Windows DNS.

Summary

Lessons learned from this issue:

  1. WSL2 is a complete virtual machine environment with an independent network stack that may conflict with the Windows host.
  2. DNS hijacking issues are hard to detect because incorrect resolution results look “plausible” (can ping local addresses).
  3. “It worked yesterday, but not today” problems are often caused by system configuration changes (e.g., WSL updates, network adapter order changes).
  4. Correct order for troubleshooting network issues: DNS Resolution → Trace Route → Firewall Rules → Application Layer Configuration.

By disabling WSL’s automatic DNS generation and manually configuring reliable public DNS, you can thoroughly resolve such issues while maintaining network independence between WSL and the Windows host.

References