WSL - VPN에 연결하면 DNS가 작동하지 않습니다.

WSL - VPN에 연결하면 DNS가 작동하지 않습니다.

저는 몇 년 동안 WSL Bash/Ubuntu를 사용해왔는데, 어떤 이유에서인지 최근에 이 문제가 발생했습니다.
DNS가 내부 및 외부 이름을 확인할 수 없습니다. 처음 WSL을 다시 설치했을 때 하루 동안 작동한다고 생각했지만 다시 설치한 후에도 더 이상 작동하지 않습니다.

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 Store)
Cisco AnyConnect VPN("연결 시 로컬 LAN에 대한 액세스 허용" 확인)

누구든지 아이디어가 있나요? 어디서 시작하나요?

답변1

해결하다.

VPN을 켜거나 끌 때 WSL(Ubuntu 하위 시스템)은 회사 및 회사가 아닌 도메인을 확인할 수 없습니다.

안정적인.

/etc/wsl.conf 파일을 생성하고 재부팅 시 resolv.conf 파일의 자동 생성을 종료하는 항목을 추가해야 합니다. /etc/wsl.conf에 코드 블록을 추가합니다.

[network] 

generateResolvConf = false

그런 다음 관리자로 powershell을 열고 명령을 실행하여 우분투 하위 시스템을 다시 시작하십시오.

wsl --shutdown

이제 우분투 하위 시스템을 다시 엽니다.

다음 명령을 순서대로 사용하십시오.

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 확인은 호스트 시스템과 정확히 동일해야 합니다.

관련 정보