WSL - VPNに接続すると、DNSは機能しません。

WSL - VPNに接続すると、DNSは機能しません。

私は何年もWSL Bash / Ubuntuを使用してきましたが、何らかの理由で最近この問題が発生しました。
DNSは内部名と外部名を解決できません。初めてWSLを再インストールしたときは、1日間は機能すると思いましたが、再インストール後も機能しなくなりました。

Windows StoreでUbuntu 18.04を新規インストールします。

user@hostname:~$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, remove this line.
nameserver <DNS server from wi-fi NIC 1>
nameserver <DNS server from wi-fi NIC 2>
nameserver <DNS server from ethernet 2 (VPN) NIC 1>
search anyconnect.local

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known

user@hostname:~$ ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=16.1 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 16.197/16.197/16.197/0.000 ms

user@hostname:~$ dig +short google.com
user@hostname:~$ dig +short @8.8.8.8 google.com
user@hostname:~$ 

修正後/etv/resolv.conf

user@hostname:~$ dig +short google.com

user@hostname:~$ cat /etc/resolv.conf
search <internal-domain>.local
search anyconnect.local
nameserver <DNS server from wi-fi NIC 1>
nameserver <DNS server from wi-fi NIC 2>
nameserver <DNS server from ethernet 2 (VPN) NIC 1>
nameserver <DNS server from ethernet 2 (VPN) NIC 2>
nameserver 8.8.8.8
nameserver 8.8.4.4

user@hostname:~$ ls -la /etc/resolv.conf
-rw-r--r-- 1 root root 167 May 28 09:18 /etc/resolv.conf

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known

user@hostname:~$ ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=54 time=17.0 ms

--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.045/17.045/17.045/0.000 ms

# disconnected VPN

user@hostname:~$ dig +short google.com
172.217.21.142

user@hostname:~$ ping google.com -c 1
PING google.com (172.217.21.142) 56(84) bytes of data.
64 bytes from arn11s02-in-f14.1e100.net (172.217.21.142): icmp_seq=1 ttl=53 time=17.4 ms

--- google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 17.445/17.445/17.445/0.000 ms

user@hostname:~$ dig +short google.com
172.217.21.142

# connected VPN

user@hostname:~$ dig +short google.com

user@hostname:~$ ping google.com -c 1
ping: google.com: Name or service not known
user@hostname:~$ 

ご覧のとおり、VPN の接続を解除すると、名前解決は完全に機能します。しかし、会社のリソースへの接続が必要なため、一日中VPNに接続していました。

WSL では内部 DNS に依存しません。理想的には内部DNSも機能するはずですが、機能するには外部DNSが必要です。

DNSはローカルで期待どおりに機能します。 VPNネットワークカードではDNSサーバーにpingを送信できますが、Wi-Fiネットワークカードではpingできません。 WSLを再インストールし、Googleのネームサーバーも試してみました/etc/resolv.conf。 DNSが必要なため、WSLはまだ更新されていませんapt

Windows 10バージョン1909
Ubuntu 18.04(Windowsストア)
Cisco AnyConnect VPN(「接続時にローカルLANへのアクセスを許可する」を確認)

誰にもアイデアがありますか?どこから始めますか?

答え1

解決する。

VPNをオンまたはオフにすると、Ubuntuサブシステム(WSL)は会社と会社以外のドメインを確認できません。

安定した。

/etc/wsl.conf ファイルを生成し、再起動時に resolv.conf ファイルの自動生成を終了するエントリを追加する必要があります。 /etc/wsl.conf にコードブロックを追加します。

[network] 

generateResolvConf = false

次に、管理者としてpowershellを開き、コマンドを実行してUbuntuサブシステムを再起動します。

wsl --shutdown

次に、Ubuntuサブシステムを再度開きます。

次のコマンドを順番に使用します。

cd /etc
ls

ディレクトリには「resolv.conf」ファイルを表示する必要があります(シンボリックリンク)。リンクが赤で表示され、どこにも接続されていないことを示します。 resolv.conf リンクを削除し、新しい /etc/resolv.conf ファイルを作成します。

新しい resolv.conf ファイルから次のコードブロックを作成します。

search    your.domain.com
nameserver    x.x.x.x
nameserver    x.x.x.x
nameserver    y.y.y.y

ここで、X は Cisco Anyconnect VPN アダプタに設定された DNS アドレスです。ネットワーク設定でCisco VPNアダプタを見つけて、Cisco VPNアダプタを右クリックして[プロパティ]をクリックします。次に、IPv4を強調表示し、[プロパティ]をクリックします。次に、プライマリDNSと代替DNSを記録し、resolv.confファイルにコピーします。

Y は汎用 IPv4 DNS アドレスです。

次に、Powershell でサブシステムを再起動します。注:これが機能しない場合は、resolv.confファイルがサブシステムによって再度削除されたことを意味します。これが機能するためには、システムはwsl.confファイルを読み取る必要があります。読まない場合は、サブシステムを再インストールするか、20.04にアップグレードしてみてください。

答え2

IPv6 DNSサーバーとの観察された競合に基づいて提案された解決策については、ここを参照してください。

https://github.com/microsoft/WSL/issues/1350#issuecomment-742454940

重要な事実と解決策を参照してください。

/etc/resolv.conf他のネットワークアダプタが使用されている場合、VPN接続のDNSサーバーは追加されません。IPv6 DNSサーバー、これは一種の競合を引き起こすようです(追加のIPv4 DNSサーバーが削除されます)。

IPv6 DNS サーバーを使用してアダプタを確認します。

Get-DnsClientServerAddress -AddressFamily IPv6 | Where-Object ServerAddresses -NE "{}" | Select-Object -ExpandProperty InterfaceAlias

関連アダプターバインディングのインポート

Get-NetAdapterBinding -ComponentID ms_tcpip6 | Where-Object Name -In (Get-DnsClientServerAddress -AddressFamily IPv6 | Where-Object ServerAddresses -NE "{}" | Select-Object -ExpandProperty InterfaceAlias)

Powershellを使用して、各アダプタバインディングに対して(またはすべてのアダプタに対して直接)IPv6を無効にします。管理者権限があります:

Disable-NetAdapterBinding -Name "Wi-Fi" -ComponentID ms_tcpip6 -PassThru
Disable-NetAdapterBinding -Name "Network Bridge" -ComponentID ms_tcpip6 -PassThru
...
Disable-NetAdapterBinding -Name "*" -ComponentID ms_tcpip6 -PassThru

または単にイーサネット/WiFiアダプタでIPv6を無効にするWindowsユーザーインターフェースを使用する:

ビデオ

これで、VPN接続が有効になっている場合はネームサーバーが正しく追加され、VPNが無効になると削除されます。

VPNに接続した後:

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 192.168.1.1
nameserver xx.xx.xx.x1 # obfuscated company dns
nameserver xx.xx.xx.x2 # obfuscated company dns
search home

VPN接続が失われた場合:

$ cat /etc/resolv.conf
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 192.168.1.1
search home

答え3

私は過去数日間この問題を経験し、それが私を狂わせました。周りの解決策は私の好みに比べて昔ながらです。私はwsl-resolv-handler.ps1正しいネームサーバーの順序を自動的に設定し、InterfaceMetricに基づいて正しい検索行を生成する非常に簡単です(このメッセージの後半のスクリプトブロックを参照)。

デフォルトでは、次のようにVPNインターフェイスに対して低(= =より高い優先順位)InterfaceMetricを設定できます(管理者としてpowershellを起動します)。

 # Get a list of interfaces, Note the InterfaceIndex and InterfaceMetric for your VPN adapter
> Get-NetIpInterface
# For example, if your VPN adapter has InterfaceIndex 12, we're setting
# the InterfaceMetric to 10, making sure 10 is lower than whatever your
# WiFi or Ethernet adapter has
> Set-NetIPInterface -InterfaceIndex 12 -InterfaceMetric 10 

インターフェイスメトリックを設定したら、以下のスクリプトブロックでスクリプトを使用できます。スクリプトの上部には、使用方法に関する完全なガイドラインと、正しいために必要ないくつかの設定(WslDistroNameとResolvConfFile)が含まれています。

# Before attempting to run this script, review and/or follow the 
# following steps.
#
# 0. Make sure you can execute powershell scripts. Start Powershell as an
#    administrator and execute:
#
#      Set-ExecutionPolicy RemoteSigned

# 1. Make sure you disable wsl's broken resolv.conf handler.
#    Create /etc/wsl.conf with the following 2 lines (without the pound signs):
#
#      [network]
#      generateResolvConf = false
#
#    After that, make sure you issue a wsl.exe --shutdown.
#
# 2. Configure your WSL distro name in $WslDistroName below and make sure we're
#    pointing at your resolv.conf file in $ResolvConfFile. Also make sure we can write 
#    to the resolv.conf file. I had to set permissions pretty broadly at 666.
#
# 3. Schedule this script with Task Scheduler:
#
#      * Click Action –> Create Task…
#      * Give your task a name in the General tab
#      * Click on the Triggers tab and then click New…
#      * In the "Begin the task" menu, choose “On an event.” Then, choose:
#
#          Log: Microsoft-Windows-NetworkProfile/Operational
#          Source: NetworkProfile
#          Event ID: 10000
#
#      * Event ID 10000 is logged when you connect to a network. Add another
#        one when a disconnect would occur (Event ID 10001):
#
#          Log: Microsoft-Windows-NetworkProfile/Operational
#          Source: NetworkProfile
#          Event ID: 10001
#
#      * Go to the Conditions tab. Make sure it runs regardless of AC adapter
#        connected/disconnected, peruse the other options there.
#
#      * Go to the Actions tab. Add a run script action and then:
#
#          Program/script: powershell.exe
#          Arguments: -noprofile -file "c:\where\you\stored\wsl-resolv-handler.ps1"
#

$WslDistroName = "Debian"
$ResolvConfFile = [string]::Format("\\wsl$\{0}\etc\resolv.conf", $WslDistroName)

function Convert-To-UnixLineEndings($path) {
  $oldBytes = [io.file]::ReadAllBytes($path)
  if (!$oldBytes.Length) {
      return;
  }
  [byte[]]$newBytes = @()
  [byte[]]::Resize([ref]$newBytes, $oldBytes.Length)
  $newLength = 0
  for ($i = 0; $i -lt $oldBytes.Length - 1; $i++) {
      if (($oldBytes[$i] -eq [byte][char]"`r") -and ($oldBytes[$i + 1] -eq [byte][char]"`n")) {
          continue;
      }
      $newBytes[$newLength++] = $oldBytes[$i]
  }
  $newBytes[$newLength++] = $oldBytes[$oldBytes.Length - 1]
  [byte[]]::Resize([ref]$newBytes, $newLength)
  [io.file]::WriteAllBytes($path, $newBytes)
}

Function Pause ($message)
{
    # Check if running Powershell ISE
    if ($psISE)
    {
        Add-Type -AssemblyName System.Windows.Forms
        [System.Windows.Forms.MessageBox]::Show("$message")
    }
    else
    {
        Write-Host "$message" -ForegroundColor Yellow
        $x = $host.ui.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    }
}

$NetworkInterfaces  = Get-NetIPInterface -AddressFamily IPv4 | Where-Object ConnectionState -EQ 'Connected' | Where-Object NlMtu -LT 9001
$DNSServerAddresses = Get-DnsClientServerAddress -AddressFamily IPv4
$DNSClients = Get-DnsClient

$Entries = $NetworkInterfaces | ForEach-Object {
  [PSCustomObject]@{
    'InterfaceAlias'      = $_.InterfaceAlias
    'InterfaceIndex'      = $_.InterfaceIndex
    'InterfaceMetric'     = $_.InterfaceMetric
    'DNSServerAddresses'  = ($DNSServerAddresses | Where-Object InterfaceIndex -EQ $_.InterfaceIndex | Where-Object AddressFamily -EQ 2).ServerAddresses
    'DNSSuffixes'  =  @(($DNSClients | Where-Object InterfaceIndex -EQ $_.InterfaceIndex).ConnectionSpecificSuffix) + @(($DNSClients).ConnectionSpecificSuffixSearchList | Out-Null)
  }
} | Sort-Object InterfaceMetric -Unique

$CommentLine = [string]::Format("# Generated by wsl-resolv-handler.ps1.")
Write-Output $CommentLine | Set-Content -Path $ResolvConfFile
$SearchLine = [string]::Format("search {0}", ($Entries.DNSSuffixes -join " "))
  Write-Output $SearchLine | Add-Content -Path $ResolvConfFile
$Entries | ForEach-Object {
  $_.DNSServerAddresses | ForEach-Object {
    $NameServerLine = [string]::Format("nameserver {0}", $_)
    Write-Output $NameServerLine | Add-Content -Path $ResolvConfFile
  }
}

Convert-To-UnixLineEndings $ResolvConfFile

Pause "Press any key to continue..."

上記のスクリプトを別の名前で保存し、wsl-resolv-handler.ps1説明の指示に従ってください。頑張ってください+楽しい時間を過ごしてください(注:この方法はすべての種類のVPNまたはネットワークトポロジの変更と連携する必要があり、Windowsのタスクマネージャで正しく設定され、タスクを正しく設定する限り、パッシブな愚かな作業なしで動作する必要があります。作成できる限り、これを実行するために高い権限は必要ありません/etc/resolv.conf

注:これに対する最も関連性の高いgithubの問題に対する回答もここに投稿しました(wslの破損したresolv.confジェネレータには多くのgithubの問題があります)。https://github.com/Microsoft/WSL/issues/2884#issuecomment-928299305

答え4

これは私に効果があったので、他人のイライラを和らげてほしい。

/etc/wsl.confの生成

[network] 

generateResolvConf = false

/etc/resolv.conf 削除またはバックアップ

sudo rm -f /etc/resolv.conf

コマンドプロンプトでwslを再起動します。

wsl --shutdown

新しいbashセッションを開始します。 DNS解決はホストシステムとまったく同じでなければなりません。

関連情報