VPNにつなぐとWSL2でインターネットに繋がらない問題を解決する

:::note warn
この方法はGlobalProtectをバージョン6.0.8にアップデートしたら使えなくなりました。
:::
:::note info
GlobalProtect 6.xの場合は`targetIfName`に`'PANGP Virtual Ethernet Adapter Secure'`を指定してください。ローカルネットにだけ接続可能になります。
:::

# インターネットに繋がらないので

* `apt-get`が出来ない
* DockerとかPodmanとかもイメージを取りに行けない

```shell
$ sudo apt-get update
Ign:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Ign:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Ign:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Ign:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Ign:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Ign:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
Ign:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Err:2 http://security.ubuntu.com/ubuntu jammy-security InRelease
  Temporary failure resolving 'security.ubuntu.com'
Ign:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Ign:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Ign:1 http://archive.ubuntu.com/ubuntu jammy InRelease
Ign:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Ign:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Err:1 http://archive.ubuntu.com/ubuntu jammy InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Err:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
  Temporary failure resolving 'archive.ubuntu.com'
Reading package lists... Done
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/jammy-backports/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/jammy-security/InRelease  Temporary failure resolving 'security.ubuntu.com'
W: Some index files failed to download. They have been ignored, or old ones used instead.
```

# <del>パクっt</del>参考にしたサイト
* https://aquasoftware.net/blog/?p=1472
  * 「VPN に繋ぐと WSL2 や Hyper-V VM でネットワークに繋がらなくなる問題を解消する」
* https://www.cats-insteadof-pc.net/wpdb/index.php/2021/12/31/runas/
    * 「【PowerShell】管理者権限に昇格してPS1ファイルを実行し直すコードを解説」

# 解決方法

* GlobalProtect限定
* 以下の内容をファイルに保存して実行（コメントなどに日本語を記載する場合BOM付きUTF-8にする必要あり）
* 管理者権限で開き直すので、管理者権限でPowerShellを起動できるアカウントであること
* VPNに接続するたび実行が必要

```powershell: wsl2-nwconfig.ps1
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole("Administrators")) {
    Start-Process -FilePath powershell.exe -ArgumentList "-ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs;
    Exit;
}

$targetIfName = 'PANGP Virtual Ethernet Adapter';
# $targetIfName = 'PANGP Virtual Ethernet Adapter Secure';  # for GlobalProtect 6.x

# define function
function Get-NetworkAddress {
    param([Parameter(Mandatory, ValueFromPipelineByPropertyName)][string]$IPAddress, [Parameter(Mandatory, ValueFromPipelineByPropertyName)][int]$PrefixLength);
    process {
        $bitNwAddr = [ipaddress]::Parse($IPAddress).Address -band [uint64][BitConverter]::ToUInt32([System.Linq.Enumerable]::Reverse([BitConverter]::GetBytes([uint32](0xFFFFFFFFL -shl (32 - $PrefixLength) -band 0xFFFFFFFFL))), 0);
        [pscustomobject]@{
            Addr = $IPAddress;
            Prfx = $PrefixLength;
            NwAddr = [ipaddress]::new($bitNwAddr).IPAddressToString + '/' + $PrefixLength;
        };
    }
}
# extend route metric
$targetAddresses = Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -Match 'Hyper-V Virtual Ethernet Adapter' | Get-NetIPAddress -AddressFamily IPv4 | Get-NetworkAddress;
$targetIfs = Get-NetAdapter -IncludeHidden | Where-Object InterfaceDescription -Match $targetIfName;
$targetIfs | Set-NetIPInterface -InterfaceMetric 2;
$targetIfs | Get-NetRoute -AddressFamily IPv4 | Select-Object -PipelineVariable rt | Where-Object { $targetAddresses | Where-Object { $_.NwAddr -eq (Get-NetworkAddress $rt.DestinationPrefix.Split('/')[0] $_.Prfx).NwAddr } } | Set-NetRoute -RouteMetric 6000;
```