Operations Lab.

Archive for 12月 10th, 2012

PowerShell を使用して IPv6 アドレスを設定する

leave a comment »

※この投稿は、PowerShell Advent Calendar 2012 に参加しています。

Windows は(以前から) IPv6 をサポートしています。最近は IPv6 接続が行える ISP も増えてきていますので、サーバに IPv6 アドレスをアサインする機会も、今後増えてくるかもしれません。

Windows Server 2012 を GUI付きでインストールを行った場合(又は、GUIを後からインストールした場合)は、通常通りインタフェースのプロパティから IPv6 アドレスを構成できます。Server Core インストールの場合は、残念ながら sconfig は IPv6 を十分にサポートしていない為、PowerShell 又は netsh を使用して IPv6 を構成する必要があります。

事前準備

PowerShell を使う場合も netsh を使う場合も同じですが、設定対象となるインタフェースのインデックス番号を把握しておくと、スムーズに設定が行えます。(インタフェースの名前(エイリアス名)でも指定は可能ですが、日本語を入力するのが面倒なので個人的にはインデックス番号がお勧めです。)

インタフェースの一覧は、Get-NetIPInterface で取得できます。

PS C:\Users\Administrator> Get-NetIPInterface

ifIndex InterfaceAlias                  AddressFamily NlMtu(Bytes) InterfaceMetric Dhcp     ConnectionState PolicyStore
------- --------------                  ------------- ------------ --------------- ----     --------------- -----------
12      イーサネット                    IPv6                  1500              10 Enabled  Connected       ActiveStore
14      Teredo Tunneling Pseudo-Inte... IPv6                  1280              50 Disabled Connected       ActiveStore
13      isatap                          IPv6                  1280              50 Disabled Disconnected    ActiveStore
1       Loopback Pseudo-Interface 1     IPv6            4294967295              50 Disabled Connected       ActiveStore
12      イーサネット                    IPv4                  1500              10 Enabled  Connected       ActiveStore
1       Loopback Pseudo-Interface 1     IPv4            4294967295              50 Disabled Connected       ActiveStore

ifIndex がインタフェースのインデックス番号です。イーサネットはインデックス番号 12 であることが分かります。

PS C:\Users\Administrator> Get-NetIPInterface -InterfaceIndex 12

ifIndex InterfaceAlias AddressFamily NlMtu(Bytes) InterfaceMetric Dhcp     ConnectionState PolicyStore
------- -------------- ------------- ------------ --------------- ----     --------------- -----------
12      イーサネット   IPv6                  1500              10 Enabled  Connected       ActiveStore
12      イーサネット   IPv4                  1500              10 Enabled  Connected       ActiveStore

ちなみに、IP アドレスの情報は Get-NetIPAddress で取得する事が出来ます。

PS C:\Users\Administrator> Get-NetIPAddress -InterfaceIndex 12

IPAddress         : fe80::299e:cf78:8834:ada0%12
InterfaceIndex    : 12
InterfaceAlias    : イーサネット
AddressFamily     : IPv6
Type              : Unicast
PrefixLength      : 64
PrefixOrigin      : WellKnown
SuffixOrigin      : Link
AddressState      : Preferred
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource      : False
PolicyStore       : ActiveStore

IPAddress         : 2001:db8::299e:cf78:8834:ada0
InterfaceIndex    : 12
InterfaceAlias    : イーサネット
AddressFamily     : IPv6
Type              : Unicast
PrefixLength      : 64
PrefixOrigin      : RouterAdvertisement
SuffixOrigin      : Link
AddressState      : Preferred
ValidLifetime     : 29.23:56:18
PreferredLifetime : 6.23:56:18
SkipAsSource      : False
PolicyStore       : ActiveStore

IPAddress         : 192.168.24.241
InterfaceIndex    : 12
InterfaceAlias    : イーサネット
AddressFamily     : IPv4
Type              : Unicast
PrefixLength      : 24
PrefixOrigin      : Dhcp
SuffixOrigin      : Dhcp
AddressState      : Preferred
ValidLifetime     : 20:17:25
PreferredLifetime : 20:17:25
SkipAsSource      : False
PolicyStore       : ActiveStore

IPv4 アドレスと IPv6 アドレスが両方表示されます。

ちなみに、IPv6 アドレス 2001:db8::/32 は、ドキュメント記載用の IP アドレスです。実際の運用環境では利用できません。詳細は RFC3849: IPv6 Address Prefix Reserved for Documentation を参照して下さい。

IPv6 アドレスの設定

IPv6 アドレスの設定は、New-NetIPAddress を使用します。

New-NetIPAddress [-IPAddress] <String> -InterfaceIndex <UInt32> [-AddressFamily <AddressFamily> ] [-AsJob] [-CimSession <CimSession[]> ] [-DefaultGateway <String> ] [-PolicyStore <String> ] [-PreferredLifetime <TimeSpan> ] [-PrefixLength <Byte> ] [-SkipAsSource <Boolean> ] [-ThrottleLimit <Int32> ] [-Type <Type> ] [-ValidLifetime <TimeSpan> ] [-Confirm] [-WhatIf] [ <CommonParameters>]

ここでインタフェース番号、IP アドレス、プレフィックス長、デフォルトゲートウェイを指定するのですが、環境によってはコマンドの実行に失敗します。

例えば、IP アドレスとしてグローバルユニキャストアドレスである 2001:db8::55、デフォルトゲートウェイのアドレスにリンクローカルアドレスである fe80::1 を指定すると、以下の様なエラーが表示されます。

PS C:\Users\Administrator> New-NetIPAddress -InterfaceIndex 12 -IPAddress 2001:db8::55 -PrefixLength 64 -DefaultGateway fe80::1
New-NetIPAddress : DefaultGateway fe80::1 is not on the same network segment (subnet) that is defined by the IP address 2001:db8::55 and PrefixLength 64.
発生場所 行:1 文字:1
+ New-NetIPAddress -InterfaceIndex 12 -IPAddress 2001:db8::55 -PrefixLength 64 -De ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (MSFT_NetIPAddress:ROOT/StandardCimv2/MSFT_NetIPAddress) [New-NetIPAddress]、CimException
    + FullyQualifiedErrorId : Windows System Error 87,New-NetIPAddress

どうやら、インタフェースにアサインする IP アドレスとデフォルトゲートウェイのアドレスが、同じネットワークセグメント上に無いと(つまり、同じネットワークプレフィックスを持っていないと)、登録ができないようです。

IPv4 では、インタフェースのアドレスとデフォルトゲートウェイのアドレスは、同一のネットワークプレフィックスを持つ事が一般的です。しかし、IPv6 は一つのインタフェースに複数のアドレスが付与され、用途に応じてアドレスを使い分けることが一般的です。リンクローカルアドレスはリンク上で重複しなければ問題ない為、ゲートウェイとなるルータの全インタフェースに fe80::1 をアサインする事が出来ます。(これにより、どのセグメントでもデフォルトゲートウェイを fe80::1 に固定でき、運用負荷を軽減できます。)

TechNet を参照すると以下の記載があります。

The New-NetIPAddress cmdlet creates IP address and the configuration properties of that IP address. To create a specific IP address object, the required parameters include an IP address (IPv4 or IPv6) and an interface (InterfaceIndex or InterfaceAlias). It is also recommended to define the prefix length, also known as a subnet mask, and default gateway.

デフォルトゲートウェイの指定を推奨するような記載がありますので、New-NetIPAddress から fe80::1 等が設定できるべきだと思いますが、できないものは仕方がないので一旦 IP アドレスのみを登録します。

PS C:\Users\Administrator> New-NetIPAddress -InterfaceIndex 12 -IPAddress 2001:db8::55 -PrefixLength 64

IPAddress         : 2001:db8::55
InterfaceIndex    : 12
InterfaceAlias    : イーサネット
AddressFamily     : IPv6
Type              : Unicast
PrefixLength      : 64
PrefixOrigin      : Manual
SuffixOrigin      : Manual
AddressState      : Tentative
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
SkipAsSource      : False
PolicyStore       : ActiveStore

IP アドレスのみであれば、問題なく登録できます。

PS C:\Users\Administrator> Get-NetIPAddress -InterfaceIndex 12 -AddressFamily IPv6 | Format-Table IPAddress

IPAddress
---------
fe80::299e:cf78:8834:ada0%12
2001:db8::299e:cf78:8834:ada0
2001:db8::55

デフォルトゲートウェイの設定

IPv6 アドレスは設定できましたが、このままではデフォルトゲートウェイが登録されていないのでセグメントを超えた通信ができません。

デフォルトゲートウェイの設定には、New-NetRoute を使用します。

New-NetRoute [-DestinationPrefix] <String> -InterfaceIndex <UInt32> [-AddressFamily <AddressFamily> ] [-AsJob] [-CimSession <CimSession[]> ] [-NextHop <String> ] [-PolicyStore <String> ] [-PreferredLifetime <TimeSpan> ] [-Publish <Publish> ] [-RouteMetric <UInt16> ] [-ThrottleLimit <Int32> ] [-ValidLifetime <TimeSpan> ] [-Confirm] [-WhatIf] [ <CommonParameters>]

ここで、インタフェース番号、デスティネーションアドレス(IPv6 デフォルトルートの場合は ::/0)、ゲートウェイのアドレスを指定すれば良いのですが、こちらも環境によっては失敗します。

PS C:\Users\Administrator> New-NetRoute -InterfaceIndex 12 -DestinationPrefix ::/0 -NextHop fe80::1
New-NetRoute : Instance MSFT_NetRoute already exists
発生場所 行:1 文字:1
+ New-NetRoute -InterfaceIndex 12 -DestinationPrefix ::/0 -NextHop fe80::1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (MSFT_NetRoute:ROOT/StandardCimv2/MSFT_NetRoute) [New-NetRoute]、CimException
    + FullyQualifiedErrorId : Windows System Error 87,New-NetRoute

既にルーティングが存在しているとのエラーが出ます。これは、RA で IPv6 アドレスを自動構成する際にデフォルトゲートウェイも構成される為です。

一般的に、IPv6 が有効なネットワークでは RA を使用してアドレスを自動構成しますが、その様なネットワークで一部のサーバのみ手動で IPv6 アドレスをアサインしようとすると、手動設定前に RA 経由でアドレスを自動構成している(デフォルトルートも構成している)為、同じルートを二重に登録しようとしてエラーになります。実際に登録したい情報が既に(自動構成で)登録されている状態ですのでこの瞬間は通信できますが、route コマンド等で確認すると「固定ルート」としては登録されていない事が分かります。(自動構成で取得したアドレスなので当たり前ですが。) IP アドレスが固定でルーティングが自動構成となっているのはトラブルの元ですので、ルーティングも手動構成に変更します。

変更は簡単で、既に自動構成されているルーティング情報を一旦削除し、同じ情報を再度登録するだけです。削除は Remove-NetRoute を使用します。

PS C:\Users\Administrator> Remove-NetRoute -DestinationPrefix ::/0

確認
この操作を実行しますか?

Performing operation "Remove" on Target "NetRoute -DestinationPrefix ::/0 -InterfaceIndex 12 -NextHop fe80::1 -Store
Active"
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):

PS C:\Users\Administrator> New-NetRoute -InterfaceIndex 12 -DestinationPrefix ::/0 -NextHop fe80::1

ifIndex DestinationPrefix                              NextHop                                  RouteMetric PolicyStore
------- -----------------                              -------                                  ----------- -----------
12      ::/0                                           fe80::1                                          256 ActiveStore
12      ::/0                                           fe80::1                                          256 Persiste...

PS C:\Users\Administrator> Get-NetRoute -DestinationPrefix ::/0 | Format-List

DestinationPrefix : ::/0
InterfaceIndex    : 12
InterfaceAlias    : イーサネット
AddressFamily     : IPv6
NextHop           : fe80::1
Publish           : No
RouteMetric       : 256
ValidLifetime     : Infinite ([TimeSpan]::MaxValue)
PreferredLifetime : Infinite ([TimeSpan]::MaxValue)
PolicyStore       : ActiveStore

もう一度 route コマンド等でルーティングを確認すると、固定ルートとして設定されている事が確認できます。PowerShell で確認する場合は、Get-NetRoute を使います。

DNSサーバの設定

最後に、IPv6 用の DNS サーバ (DNS キャッシュサーバ)を設定します。まず、Get-DnsClientServerAddress で現在の設定を確認します。

PS C:\Users\Administrator> Get-DnsClientServerAddress -InterfaceIndex 12

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
イーサネット                        12 IPv4    {}
イーサネット                        12 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}

IPv4、IPv6 ともに手動で構成した場合、DNS サーバが設定されていない状態となります。

設定には、Set-DnsClientServerAddress を使用します。

Set-DnsClientServerAddress -InterfaceIndex <UInt32[]> [-AsJob] [-CimSession <CimSession[]> ] [-PassThru] [-ResetServerAddresses] [-ServerAddresses <String[]> ] [-ThrottleLimit <Int32> ] [-Validate] [-Confirm] [-WhatIf] [ <CommonParameters>]

基本的に、インタフェース番号と DNS サーバのアドレスを指定するだけです。

PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses 192.168.24.1
PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses fe80::1
PS C:\Users\Administrator> Get-DnsClientServerAddress -InterfaceIndex 12

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
イーサネット                        12 IPv4    {192.168.24.1}
イーサネット                        12 IPv6    {fe80::1}

IPv4 と IPv6 はエントリが分かれている為、個別に設定を行う事が出来ます。また、後から設定し直した場合は、設定したアドレスファミリ (IPv4/IPv6) のみが影響を受けます。

PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses 8.8.8.8
PS C:\Users\Administrator> Get-DnsClientServerAddress -InterfaceIndex 12

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
イーサネット                        12 IPv4    {8.8.8.8}
イーサネット                        12 IPv6    {fe80::1}

複数のサーバを指定する場合は、カンマ区切りで複数のアドレスを指定します。

PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses "192.168.24.1,192.168.24.2"
PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses "2001:db8::1,2001:db8::2"
PS C:\Users\Administrator> Get-DnsClientServerAddress -InterfaceIndex 12

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
イーサネット                        12 IPv4    {192.168.24.1, 192.168.24.2}
イーサネット                        12 IPv6    {2001:db8::1, 2001:db8::2}

エントリは分かれていますが、一つのコマンドで IPv4 と IPv6 を同時に構成する事もできます。

PS C:\Users\Administrator> Set-DnsClientServerAddress -InterfaceIndex 12 -ServerAddresses "192.168.24.1,192.168.24.2,2001:db8::1,2001:db8::2"
PS C:\Users\Administrator> Get-DnsClientServerAddress -InterfaceIndex 12

InterfaceAlias               Interface Address ServerAddresses
                             Index     Family
--------------               --------- ------- ---------------
イーサネット                        12 IPv4    {192.168.24.1, 192.168.24.2}
イーサネット                        12 IPv6    {2001:db8::1, 2001:db8::2}

おわりに

PowerShell 3.0 でインタフェースや IP アドレスを構成するコマンドレットが充実し、IPv4/IPv6 アドレスをお手軽に構成・管理できるようになりました。IPv6 も IPv4 と(ほぼ)同じように構成ができますので、OS をインストールしたらまずは IPv6 を無効化する!のではなく、まずは色々とさわってみると面白いかもしれません。

Written by kazu

2012/12/10 at 23:19

カテゴリー: PowerShell

Tagged with , ,