Oracle CloudでARMインスタンスが開始されたのでIPv6アクセスできるサーバとして構築してみた


Oracle CloudでARMインスタンスの提供が開始された。

Arm-based cloud computing is the next big thing: Introducing Arm on Oracle Cloud Infrastructure

Ampere A1を使用したものらしい。

今日から使える、といってるけど、さすがに東京リージョンには来てないだろうと思いつつコンソールを開いてみる。

画像

え!?東京でも作成できんじゃん!と作成開始

まず、Always Freeアカウントではどういうスペックが作れるのか?を確認→「Always Free Resources

画像

なんとCPU 4個/RAM 24GBまでいけるらしい。

すでに、これまでのAlways Freeアカウントの上限である、VM.Standard.E2.1.Micro インスタンスで2個作っていても、それとは別カウントでARMのVM.Standard.A1.Flexが作れるようだ。

画像
画像
画像

標準ではOracle Linux 7.9が選択されている。他の選択肢を見てみる。

画像

「イメージビルド」に記載がないものは選べないようだ。このため、Oracle Autonomous Linux は選択できなかった。

Oracle Linux 8 にすることはできるようだ。

インスタンスのshapreは変更可能

その他の項目はいままでのインスタンス作成となんら変わらず。

完成するとこんな感じ

画像

「Always Free」というマークがついてない・・・

不安になったのでいろいろ試行錯誤

画像

既存のVM.Standard.E2.1.Microインスタンスを1個けして作り直してもA1.FlexインスタンスにAlways Freeマークがつくわけではないようだ。

かといって、VM.Standard.E2.1.Microインスタンスが2個ある状態で3個目をつくろうとすると、有料アカウントへのアップグレードが必要と表示されるので、有料になっているわけではない模様。

画像

じゃあ、ARMインスタンスを複数個立てられるのかな?と実行してみると、作成は可能なものの直ちに終了して使えないという状態

既存インスタンスのシェイプの変更を選び

変更することは可能

変更が反映されました。

ほんとにこれで大丈夫なのかなぁ???と悩むところではありますが、ドキュメント通り、「VM.Standard.E2.1.Micro インスタンスを2個」と「ARMのVM.Standard.A1.Flexインスタンスを4CPU/メモリ24GBの範囲内」で作成することができる、ということのようです。

また、ARMインスタンスについては、作成後、CPU/メモリスペックを変更する事が可能でした。

2021/05/27訂正

ドキュメント上は「All tenancies get two public IPv4 addresses for Always Free compute instances」となっていますが、動作検証をしてみたところ、パブリックIPアドレスの上限個数が3となっているようです。

パブリックIPアドレスの割り当てをやめてみたところARMインスタンス(VM.Standard.A1.Flex)を4つ作ることができました。

画像

IPv6設定メモ

4月から使える様になったIPv6ですが「Oracle Cloudですでに作成済みのネットワークに対してIPv6を有効にする方法」に示した手順で有効化したところ、DHCPv6でのIPv6アドレス取得が失敗しました。

手動であれば設定できたので、ARMインスタンスが存在するネットワークへのDHCPv6が正常に動作していない模様です。

設定としては、Oracle Cloudコンソールの[インスタンスの詳細]-[アタッチされたVNIC]-[VNICの詳細]にある[リソース]-[IPv6アドレス]にて、インスタンスにIPv6アドレスを割り当てる。

また、2021/05/26時点でのOracle Linux 7提供イメージでは、IPv6アドレスが有効化されていないため、インスタンス内のOS設定を変更する必要があり、DHCPv6アドレス取得ができなかったので、disable-ipv6.confと01_ipv6を作成した。
Oracle Linux 8だとIPv6有効化されていたがDHCPv6アドレス取得ができなかったので01_ipv6を作成したfirewalldにdhcpv6-clientの設定がされていないのでDHCPv6アドレス取得に失敗していたので設定を変更した。
Ubuntu 20.04ではIPv6有効化されておりDHCPv6アドレス取得はできたものの起動時に自動取得はしなかったので01_ipv6を作成しdhclient -6の方を有効にした。

disable-ipv6.confの手順

/etc/sysctl.d/disable-ipv6.conf を作成し、下記を記載

net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0

01_ipv6の手順

/var/lib/cloud/scripts/per-boot/01_ipv6 を作成し、下記を記載

#/bin/bash
#dhclient -6
ip -6 addr add xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/128 dev enp0s3

DHCPv6が使える様になった場合は、ip行の先頭に#を入れ、dhclientの前の#を外すこと。

また/var/lib/cloud/scripts/per-boot/01_ipv6には下記の様に実行権限を与えること

# chmod a+x /var/lib/cloud/scripts/per-boot/01_ipv6 

firewalldにdhcpv6-clientを追加する手順

serviceとしてdhcpv6-clientを追加する、という手順。Oracle Linux 7だと標準で設定されていたが、2021/05/27時点でのOracle Linux 8 ARM環境だと設定されていなかった。

$ sudo firewall-cmd --permanent --add-service=dhcpv6-client
success
$ sudo firewall-cmd --reload
success
$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
$

簡易的なセキュリティ対策

インスタンスを稼働させておくとsshへのアタックが凄い数来ます。

標準設定では秘密鍵持ってないとログインできないので影響は少ないですが、アクセスができる状態だといつまでもリトライを繰り返してきます。このため、fail2banを使って拒否することで、アタック側のブラックリストに載せて攻撃者数を減らしてみよう、という試みです。

$ sudo yum install fail2ban
$ sudo vi /etc/fail2ban/jail.local
$ sudo cat /etc/fail2ban/jail.local
[DEFAULT]
# 86400秒=24時間以内に5回不審なアクセスがあったら24時間BAN
bantime  = 86400
findtime  = 86400
maxretry = 5
# 259200秒=3日以内に5回不審なアクセスがあったら3日間BAN
#bantime  = 259200
#findtime  = 259200
#maxretry = 5

# 除外IP
ignoreip = 127.0.0.1 127.0.0.0/8 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16

[sshd]
enabled = true
banaction = firewallcmd-ipset

$ sudo systemctl enable fail2ban
$ sudo systemctl start fail2ban
$

おまけ情報

インスタンス内でlscpuを実行した結果

Oracle Linux 7の場合

$ sudo lscpu
Architecture:          aarch64
Byte Order:            Little Endian
CPU(s):                1
On-line CPU(s) list:   0
Thread(s) per core:    1
Core(s) per socket:    1
Socket(s):             1
NUMA node(s):          1
Model:                 1
BogoMIPS:              50.00
NUMA node0 CPU(s):     0
Flags:                 fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
$

Oracle Linux 8 (Oracle-Linux-8.3-aarch64-2021.05.12-0) 初期状態の場合

$ lscpu
Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              1
On-line CPU(s) list: 0
Thread(s) per core:  1
Core(s) per socket:  1
Socket(s):           1
NUMA node(s):        1
Vendor ID:           ARM
Model:               1
Stepping:            r3p1
BogoMIPS:            50.00
NUMA node0 CPU(s):   0
Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
$

Oracle Linux 8 (Oracle-Linux-8.3-aarch64-2021.05.12-0) でdnf updateした後の場合

$ sudo lscpu
Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              1
On-line CPU(s) list: 0
Thread(s) per core:  1
Core(s) per cluster: 1
Socket(s):           1
Cluster(s):          1
NUMA node(s):        1
Vendor ID:           ARM
BIOS Vendor ID:      QEMU
Model:               1
Model name:          Neoverse-N1
BIOS Model name:     virt-4.2
Stepping:            r3p1
BogoMIPS:            50.00
NUMA node0 CPU(s):   0
Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
$

Oracle Linux 8で4CPU/24GBにした場合

$ sudo lscpu
Architecture:        aarch64
Byte Order:          Little Endian
CPU(s):              4
On-line CPU(s) list: 0-3
Thread(s) per core:  1
Core(s) per cluster: 4
Socket(s):           1
Cluster(s):          1
NUMA node(s):        1
Vendor ID:           ARM
BIOS Vendor ID:      QEMU
Model:               1
Model name:          Neoverse-N1
BIOS Model name:     virt-4.2
Stepping:            r3p1
BogoMIPS:            50.00
NUMA node0 CPU(s):   0-3
Flags:               fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm lrcpc dcpop asimddp ssbs
$

Ubuntu 20.04の場合

$ sudo lscpu
Architecture:                    aarch64
CPU op-mode(s):                  32-bit, 64-bit
Byte Order:                      Little Endian
CPU(s):                          1
On-line CPU(s) list:             0
Thread(s) per core:              1
Core(s) per socket:              1
Socket(s):                       1
NUMA node(s):                    1
Vendor ID:                       ARM
Model:                           1
Model name:                      Neoverse-N1
Stepping:                        r3p1
BogoMIPS:                        50.00
NUMA node0 CPU(s):               0
Vulnerability Itlb multihit:     Not affected
Vulnerability L1tf:              Not affected
Vulnerability Mds:               Not affected
Vulnerability Meltdown:          Not affected
Vulnerability Spec store bypass: Mitigation; Speculative Store Bypass disabled v
                                 ia prctl
Vulnerability Spectre v1:        Mitigation; __user pointer sanitization
Vulnerability Spectre v2:        Not affected
Vulnerability Srbds:             Not affected
Vulnerability Tsx async abort:   Not affected
Flags:                           fp asimd evtstrm aes pmull sha1 sha2 crc32 atom
                                 ics fphp asimdhp cpuid asimdrdm lrcpc dcpop asi
                                 mddp ssbs
$

Commvault バックアップのLinuxクライアントをインストールする場合の設定


2024/01/23現在 のLinuxクライアントとして設定する場合の要点

「gzip」と「tar」コマンドが利用できること。使えない場合は、パッケージをインストールする。

RHEL8/RHEL9系の最小インストールの場合、tarコマンドが使えないので注意。

クライアント側のFirewall設定は ポート 8400 をあけておくこと。

ポート8400を使った通信は、CommServeだけではなく、MediaAgentからも行われるので、IPアドレス制限をかける場合は注意すること。

なお、ポート8400をあけていなくても、クライアント上で起動したCommvaultのエージェントからCommServeなどへの通信が行えるが、内部的にリトライエラーを繰り返した代替策となるため処理に時間がかかるので推奨はしない。


2023/10/10現在

Commvault 2022E(11.28)でLinuxクライアントをインストールする場合のメモ

System Requirements for Linux File System」には特に必要なパッケージについての記載は、RHEL/CentOS 7.1環境でnet-toolsをインストールしておくこと、以外の記載はない。

AlmaLinux 8.8の最小インストール環境で net-toolsが含まれていない状態ですが、この状態でCommvault 11.28.56環境でインストールを試みたところ、net-toolsがない状態でもインストールは成功しました。

また、tarコマンド、gzipコマンドについては必須ですが、Linuxの設定状況によってはtarコマンドがインストールされていないことがあるのでが「tarコマンドがない」的なエラーはでないで失敗するので、原因が分かりにくいです。(エラーでた後に該当Linuxサにログインすると /opt/seed/ にファイルが転送されています。/opt/seed/cvpkgadd を実行してみると、tarコマンドがない、というエラーがでるので、ようやくわかります)

エラーコード: [68:184]

説明: Failed to install File System Core Package on client.
Source: todoroki110, Process: DistributeSoftware

firewallについてはポートを開けない状態でもうまく動作する場合がおおかったですが、Media Agent/Virtual Server設定などを行った際には、ポートを開けておかないと動作が安定しませんでした。

加えて、インストールしてそのまま使うだけであればfirewall設定をしないままでも通信に成功し、バックアップの取得も可能でしたが、一度再起動すると接続が確立しない状態となりましたので、ポートは開けておくべきです。

また、VMware Proxy/Access Nodeとした場合、 https アクセスも必要であったようでしたので下記の例ではport 8400と、port 443(https)を追加しています。
MAの場合は追加で port 50000-50020 とかしておいた方がよさそうです。

普通のLinuxクライアントとして使う場合は port 8400だけで大丈夫でしょう。

# firewall-cmd --permanent --zone=public --add-port=8400/tcp
success
# firewall-cmd --permanent --zone=public --add-service=https
success
# firewall-cmd --reload
success
# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources:
  services: cockpit dhcpv6-client https ssh
  ports: 8400/tcp 
  protocols:
  forward: no
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
#

また、Linux仮想マシン内の個別ファイルをリストアする際に利用するFREL仮想マシン(File Recovery Enablers for Linux)は、通常のLinux MediaAgent+Virtual Server構成では使えません。

追加設定として「Converting a Linux MediaAgent to a File Recovery Enabler (FREL)」にある設定を行う必要があります。

また、FRELは/opt/commvault/CVBLK 以下にあるコンパイル済みのkernel module cvblk を使用します。ここに該当のkernelバージョンのモジュールがない場合はFRELに昇格できません。

また、VSAとして使う場合に、Commvault環境を一時的なNFSサーバとしてvSphere環境からデータストアとしてマウントし、バックアップされているvmdkファイルを使う、という3dnfs serviceを使う場合は、追加でNFS v3で必要なポート設定をする必要があります。

こちらについては面倒なので「Additional Port Requirements for 3dnfs Services」を参照のこと…というか、そこまでやるならfirewallをoffにした方が早いですけどね。FREL仮想マシンはfirewall offですし。

2023/10/18追記

Commvault 2023E(11.32)環境にテスト環境を作った
(1)CommServe単独サーバ Windows
(2)MediaAgent+重複排除のバックアップ保存領域 Windows
(3)IndexServer Windows
(4)VSA/FREL Linuxサーバ

(1),(2),(3)のWindowsサーバで共通のfirewall設定「Windows Management Instrumentation (DCOM受信)」「Windows Management Instrumentation (WMI受信)」「ファイルとプリンターの共有」を有効化と、Commvaultがインストール時に自動作成するルールの有効化

Linux仮想マシン内の単独ファイルをリストアするためにブラウズする際は、(2)から(4)のport 8403に対して通信が発生し、(4)側で8403を開けていないと失敗した

(1)CommServeは動作中のcvfwd.log を見ると、8400~8403 を開けておいた方が接続が早そう。

(2)MAは8400,8403 をあけた方が良い。NDMPバックアップを保存する場合は10000と50000-50050 とMAのネットワークルート設定のインカミングに50000-50050を追加


2021/5/24 に書いたもの

CommvaultバックアップのLinuxクライアントをインストールする際にうまく行かずに悩んだ点が発生したのでメモ書き。

Linux File System Agent: System Requirements」には下記のような記述があるが、実際にはRHEL/CentOS 7.1以外でも発生する問題である。

Net-tools Package
On Red Hat Enterprise Linux/CentOS 7.1 computers, make sure to install the net-tools package.

それどころか、RHEL8/CentOS8などでは、tarパッケージが最小インストールではインストールされなくなっているため、インストールに失敗する。(vSphere環境上にインストールする場合、open-vm-toolsの必須パッケージとしてtarがインストールされるため気がつきにくい)

今回、RHEL8.3, AlmaLinux 8.3, Rocky Linux 8.3, openEuler 21.03, CentOS 7, Ubuntu 18.04にインストールした結果、必要だったものは以下であった。

・必須のコマンド
tar, netstat, gzip コマンド
・上記が含まれるパッケージ(RHEL系の場合)
tar net-tools

また、firewalld/iptablesによる通信制限がかけられている場合、下記を実行してポートをあけた方が良い。

ただ、あけなくてもバックアップできる場合もある。

現状を確認「firewall-cmd –list-all」

[root@centos8 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources:
  services: dhcpv6-client ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@centos8 ~]#

Commvault用にポート8400をあける設定

[root@centos8 ~]# firewall-cmd --permanent --zone=public --add-port=8400/tcp
success
[root@centos8 ~]#

設定の反映

[root@centos8 ~]# firewall-cmd --reload
success
[root@centos8 ~]#

反映されたことを確認

[root@centos8 ~]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources:
  services: dhcpv6-client ssh
  ports: 8400/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[root@centos8 ~]#

また、rootユーザでのログインが禁止されている場合は、以下の4つの手段のどれかを使う

その1) 予め各Linuxサーバの/etc/sudoers ファイルにインストール用ユーザを設定してリモートインストールを行う「Adding sudo Users with Root Privileges on a UNIX Client

その2) 各LinuxサーバにLinuxクライアントパッケージを転送してrootユーザでインストールを行う「Installing Commvault Locally on UNIX, Linux, and Macintosh Computers Using the Installation Package

その3) 各LinuxサーバにLinuxクライアントパッケージを転送して一般ユーザ+sudoでインストールを行う「Installation of UNIX Agents by a Non-Root User

その4) 各Linuxサーバでrootログインを許可する

NanoPi R2S+openWRT 21.02.0RCでBIGLOBEのMAP-E接続


2021/09/14追記

OpenWRT 21.02.0リリース版にてだいぶ手順が変わってしまったので、あたらしく「NanoPi R2S+OpenWRT 21.02.0でBIGLOBEのMAP-E接続」として修正しています。

この記事は古い内容となります。


GL.iNET GL-MV1000を使っていたわけですが2020年8月以降IPv6が無効化、そのまま放置され、2021年4月になって再度有効化されたものの、GL.iNETが提供する機能以外の部分はほぼ切り捨てられてしまいました。

GL.iNET firmwareの駄目なところ
・GL.iNET UIで提供されている機能はGL.iNET側で有効化しないとluci側で行った設定が有効にならない(DynamicDNSやIPv6など)
・追加したパッケージはfirmwareバージョンアップ時に削除される(GUI上はパッケージを追加する、とか表示されるけど追加されたことはない)
・GL.iNet ver 3.201だとluci パッケージがインストールされていないため詳細設定が出来ない
・パッケージを追加するにはネットワーク接続が必須だがGL.iNET UIだと詳細設定ができないのでネットワーク接続ができない場合がある

そんな状況が約1年続いたわけなので、さすがに諦めました。

代替としてRockchip RK3328のNanoPi R2S と Rockchip RK3399のNanoPi R4S を候補にあげた。

Amazon日本の倉庫に在庫があるというのと、openWRTのページに「FriendlyARM NanoPi R2S」とデバイスに関する個別ページが作成されており、snapshotの提供がされていたので、NanoPi R2Sを買って設定を行った。

画像
画像

ちなみに置き換え対象となったGL-MV1000とのサイズ比較はこんな感じ

画像
画像

さて、openWRTの設定を行ったタイミングではopenWRT 21.02.0 rc1の提供が開始されていたのでそちらを使用した。(2021/07/12追記 openWRT 21.02.0 rc3は壊れているようでLANポートが稼働しないので使わないこと。やるのであればrc2)

friendlyarm_nanopi-r2s-squashfs-sysupgrade.img.gz を展開したものをmicroSDに書き込んでNanoPi R2Sを起動した。

設定手順1:パッケージの追加

mapパッケージと日本語UIパッケージ(luci-i18n-base-ja)をインストール

CLIでインストールする場合は以下を実行

# opkg update
# opkg install luci-i18n-base-ja
# opkg install map

インストール後は再起動を行うこと。

再起動しないとluciのネットワーク設定で「プロトコル:MAP / LW4over6」が選択肢に現れません。

設定手順2:WAN6インタフェースの作成

WAN6インタフェースがなければ「プロトコル: DHCPv6クライアント」で作成する

最初はそのまま設定して、有効化し、WAN6インタフェースに割り当てられるIPv6アドレスを確認すること。

↑の画像は使い回しなので、この段階では無いはずの「MAP」インタフェースが入ってます

上記のように「IPv6」アドレスが確認できたら、そのアドレスをコピーして、[詳細設定]の「委任されたカスタムIPv6プレフィックス」に貼り付け「/56」とかつけます。

設定手順3:WAN6インタフェースにDHCPv6関連設定

openWRT 21.02の段階でもWAN6インタフェースではDHCPv6関連設定がGUIできない状態であるため、/etc/config/dhcpファイルを直接書き換えます。

必要な設定は「option dhcpv6 ‘relay」「option ra ‘relay’」「option ndp ‘relay’」「option master ‘1’」です。

変更したあとは、以下の様な感じになるかと思います。

config dhcp 'wan6'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
        option interface 'wan6'
        option start '100'
        option limit '150'
        option leasetime '12h'

ファイル変更後は下記を実行して変更を反映します。

# uci commit dhcp
# /etc/init.d/odhcpd restart
# /etc/init.d/network restart

設定手順4:LANインタフェースにDHCPv6関連設定

LANインタフェースの[DHCPサーバー]-[IPv6設定]で以下の設定を行います。

RA-Service:リレーモード
DHCPv6-サービス: リレーモード
NDP-Proxy: リレーモード

(マスターにチェックは入れません)

設定手順5: MAP-E接続設定

インタフェースの新規作成で「プロトコル:AP / LW4over6」を作成して、必要な値を入れていきます。

[一般設定]では下記の様にしました。

プロトコル:MAP/LW4over6
タイプ:MAP-E
以後は環境に合わせた値

[詳細設定]では下記の2つを設定します。

「トンネルリンク: WAN6」
「従来のMAPを使用」にチェックを入れる

設定完了

ひとまずこれで設定完了です。

うまく接続が始まらない場合は、再起動してみてください。

設定:ニチバン対策

2chの「v6プラス関連 Part21」に下記のような書き込みがある。

757名無しさんに接続中… (ブーイモ MM0e-wDGU)2020/09/27(日) 12:54:30.84ID:cYRzN3kgM>>758
openwrtでMAP-Eされてる方で、
https://gist.github.com/anonymous/0fdec75fa20a7f1ce4806391d6b0429b
このgitのコメントにあるように、
json_add_boolean connlimit_ports 1を
json_add_string connlimit_ports “1”
に変えるor最新のfirewallパッケージを入れるで安定して通信出来てる人いますか?

これをする事でopenwrtで当たり前となってるmap.sh編集してMARKターゲット作ってstatisticで分散してって事をせずとも、
connlimitでポートセット使い切ったら次のポートセット移ってってfirewallがちゃんと出来上がるようになるけど、
ルール通りロールアウトしてる気配が全く無い。
ロールアウトせずパケ詰まりしてしまう。

795 757 (ブーイモ MMe7-PIvK)2020/09/30(水) 20:53:39.27ID:1mR0IohpM>>802
最終的にこのようなcunstom rulesになりました。
https://pastebin.pl/view/raw/06212cd8
多分ですが、map.shで自動生成されるiptablesだと、
–connlimit-maskの指定がなく32になるので、
それだとdestinationが0.0.0.0/0なのでマッチせずロールアウトされないんだと思います。
0にしてあげたらロールアウトしました。(間違ってたらご指摘下さい。)
TCPもnf_conntrack調整したらconnlimitでも大丈夫な感じでしたが、
statisticでかなり安定してるのでTCPのみstatisticにしました。
map.shはlegacy=1をコメントアウトするか、snapshotsから最新のmapをインストールした場合は、
option legacymap ‘1’をnetworkのmapインターフェイスに追記するだけで動くと思います。
markターゲット追加する改変は不要です。
custom rulesに書いただけだと、リブート時、custom rulesの後にmap.shがiptablesを書いてしまうので、
local startupに
sleep 30
sh /etc/firewall.ser
を書けばmap.shで自動生成されたNATテーブルを削除して改めて書いてくれます。

これで、ニチバンベンチ回してもTCPは詰まらないですし、
MAP-EでUDP hole puch使うアプリケーションが使えるので、PS系ゲーム機でNATタイプ2になりましたし、
SoftEtherでUDP高速化機能が使るようになりました。

アドバイス下さった>>758様や、スクリプト考案の先駆者様等、
有難うございます。

GL-MV1000時代にも試した「OpenWrt map-e (JPNE v6plus) において、割当ポート240個をちゃんと使わせるための設定。」はここでもうまく動作していなかった模様。

代替としてhttps://pastebin.pl/view/raw/06212cd8にある設定に置き換えるとある。

しかし「OpenWrt map-e (JPNE v6plus) において、割当ポート240個をちゃんと使わせるための設定。」のコメント欄を見ると、誤植があるようだった。

また、誤植修正後も接続状況が不安定なので出力されるiptablesの確認したところ、範囲外のポートを指定していることが判明

(2021/05/21追記: この差異はV6プラス/BIGLOBEとOCN バーチャルコネクトとの仕様の違いとのこと)

修正版として https://gist.github.com/osakanataro/a9ba5ded340070b8e6abc28969d7ae4f を作成した。

修正点
「units=63」→「units=15」
「portl=expr $rule \* 1024 + $PSID \* 16」→「portl=expr $rule \* 4096 + $PSID \* 16

IP4,PSID, LANDEV,WAN6DEV,TUNDEVは自分の環境に合わせて変更すること
IP4, PSIDがわからない場合は http://ipv4.web.fc2.com/map-e.html で確認すること

#units=63
units=15

IP4='xxx.xxx.xxx.xxx'
PSID=110
LANDEV='br-lan'
WAN6DEV='eth0'
TUNDEV='map-MAP'

iptables -t nat -F PREROUTING
iptables -t nat -F OUTPUT
iptables -t nat -F POSTROUTING

rule=1
while [ $rule -le $units  ] ; do
  mark=`expr $rule + 16`
  pn=`expr $rule - 1`
  portl=`expr $rule \* 4096 + $PSID \* 16`
  portr=`expr $portl + 15`

  echo iptables -t nat -A PREROUTING -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A PREROUTING -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  echo iptables -t nat -A OUTPUT -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark
  iptables -t nat -A OUTPUT -p tcp -m statistic --mode nth --every $units --packet $pn -j MARK --set-mark $mark

  echo iptables -t nat -A POSTROUTING -p icmp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p icmp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  echo iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p tcp -o $TUNDEV -m mark --mark $mark -j SNAT --to $IP4:$portl-$portr
  echo iptables -t nat -A POSTROUTING -p udp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr
  iptables -t nat -A POSTROUTING -p udp -m connlimit --connlimit-daddr --connlimit-upto 16 --connlimit-mask 0 -o $TUNDEV -j SNAT --to $IP4:$portl-$portr

  rule=`expr $rule + 1`
done

上記を

openwrtの[ネットワーク]-[ファイヤーウォール]-[Custom Rules] (/etc/firewall.user) に記載する。

また、[システム]-[スタートアップ]-[ローカルスタートアップ] (/etc/rc.local)の exit 0よりも前に下記2行を追加する

sleep 30
sh /etc/firewall.user

また、iptablesのstatisticモジュールはiptables-mod-ipoptに入っているが、標準では導入されていないため、下記のようにインストールする。

root@nanopi:~# opkg install iptables-mod-ipopt
Installing iptables-mod-ipopt (1.8.7-1) to root...
Downloading https://downloads.openwrt.org/releases/21.02.0-rc1/targets/rockchip/armv8/packages/iptables-mod-ipopt_1.8.7-1_aarch64_generic.ipk
Installing kmod-ipt-ipopt (5.4.111-1) to root...
Downloading https://downloads.openwrt.org/releases/21.02.0-rc1/targets/rockchip/armv8/packages/kmod-ipt-ipopt_5.4.111-1_aarch64_generic.ipk
Configuring kmod-ipt-ipopt.
Configuring iptables-mod-ipopt.
root@nanopi:~#

これで、とりあえずニチバンもスムースに開けるようになった。


失敗例コレクション

「プロトコル:MAP / LW4over6」が選択肢にない

画像

mapパッケージインストール後、openWRTを再起動するまで、このプロトコル一覧は更新されませんでした。

再起動すると表示されるようになりました。

「MAP rule is invalidError: MAP rule is invalid」になる

「MAP rule is invalidError: MAP rule is invalid」はWAN6インタフェースの詳細設定で「委任されたカスタムIPv6プレフィックス」(ip6prefix)を設定していない場合に出力されました。

invalidと表示された時のWAN6インタフェースの「IPv6-PD」に表示されている値を突っ込んだら、invalidが解消されました。

設定ファイル的には/etc/config/networkのWAN6に関する記述に「list ip6prefix」を追加する感じです。

LAN内にDHCPv6アドレスが配布されない

nanoPi上は特に問題無くIPv6アドレスが割り当てられており動作もしているが、LAN内のクライアントにDHCPv6アドレスが配布されていないという状態になった。

これは、LANインタフェースの[DHCPサーバ]-[IPv6設定]にある「マスター」にチェックを一度でも入れてしまうと発生する事象だった。

一度チェックを入れて保存すると、/etc/config/dhcp に以下の様な設定が行われる。

<略>
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'
        option master '1'
<略>

この後、マスターのチェックを外すと、以下の様になる

<略>
config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'
<略>

ここで問題となったのは以下の値でした。

        option ra_slaac '1'
        list ra_flags 'managed-config'
        list ra_flags 'other-config'
        option ra_maxinterval '600'
        option ra_mininterval '200'
        option ra_lifetime '1800'
        option ra_mtu '0'
        option ra_hoplimit '0'

これらの値が存在しているとDHCPv6アドレスのLAN内への配布がうまくいきませんでした。

/etc/config/networkを編集したあと、下記で反映することで動作するようになりました。

# uci commit dhcp
# /etc/init.d/odhcpd restart
# /etc/init.d/network restart

参考: IPv6 working on router but not on clients

MAP-E接続が開始されない

GL-MV1000からnanoPi R2Sに置き換えてすぐは、IPv6接続はできているが、MAP-E接続が開始されない、という状態になった。

ONUの電源を切り、5分ぐらいしてから電源を入れnanoPiも起動するとMAP-E接続が可能となった。

おそらく、接続先でのセッション認識が消えないと別のデバイスでの接続が行うことができないようだ。(エラーにもならないので詳細は不明)


参考資料

/etc/config/network

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config globals 'globals'
        option ula_prefix 'fd23:66f8:d98f::/48'

config interface 'lan'
        option type 'bridge'
        option ifname 'eth1'
        option proto 'static'
        option netmask '255.255.255.0'
        option ipaddr '192.168.1.1'
        option ip6assign '60'

config device 'lan_eth1_dev'
        option name 'eth1'
        option macaddr '1a:e4:a4:xx:xx:xx'

config interface 'wan'
        option ifname 'eth0'
        option proto 'dhcp'
        option auto '0'

config device 'wan_eth0_dev'
        option name 'eth0'
        option macaddr '1a:e4:a4:xx:xx:xx'

config interface 'wan6'
        option ifname 'eth0'
        option proto 'dhcpv6'
        option reqaddress 'try'
        option reqprefix 'auto'
        list ip6prefix 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/56'

config interface 'MAP'
        option proto 'map'
        option maptype 'map-e'
        option peeraddr 'xxxx:xxxx:xxxx:xxxx::64'
        option ipaddr 'xxx.xxx.xxx.xxx'
        option ip4prefixlen '15'
        option ip6prefix '240b:10::'
        option ip6prefixlen '31'
        option ealen '25'
        option psidlen '8'
        option offset '4'
        option tunlink 'wan6'
        option legacymap '1'

/etc/config/dhcp

config dnsmasq
        option domainneeded '1'
        option boguspriv '1'
        option filterwin2k '0'
        option localise_queries '1'
        option rebind_protection '1'
        option rebind_localhost '1'
        option local '/lan/'
        option domain 'lan'
        option expandhosts '1'
        option nonegcache '0'
        option authoritative '1'
        option readethers '1'
        option leasefile '/tmp/dhcp.leases'
        option resolvfile '/tmp/resolv.conf.d/resolv.conf.auto'
        option nonwildcard '1'
        option localservice '1'
        option ednspacket_max '1232'

config dhcp 'lan'
        option interface 'lan'
        option start '100'
        option limit '150'
        option leasetime '12h'
        option dhcpv4 'server'
        option ra 'relay'
        option dhcpv6 'relay'
        option ndp 'relay'

config dhcp 'wan'
        option interface 'wan'
        option ignore '1'

config odhcpd 'odhcpd'
        option maindhcp '0'
        option leasefile '/tmp/hosts/odhcpd'
        option leasetrigger '/usr/sbin/odhcpd-update'
        option loglevel '4'

config dhcp 'wan6'
        option dhcpv6 'relay'
        option ra 'relay'
        option ndp 'relay'
        option master '1'
        option interface 'wan6'
        option start '100'
        option limit '150'
        option leasetime '12h'

Oracle Cloudですでに作成済みのネットワークに対してIPv6を有効にする方法


Oracle CloudはこれまでIPv6が提供されてなかったのですが、4/15に「IPv6 on Oracle Cloud Infrastructure」でIPv6提供が全体に開始されたとのことなので試してみた。

既存のOracle CloudインスタンスをIPv6対応にするための設定を開始。

まずは「仮想クラウドネットワーク(VNC)」一覧を開く

画像

最初はIPv6 CIDRブロックが割り当てられていない。

画像

「IPv6 CIDRブロックの追加」を選択

画像

すると、IPv6アドレスが追加される

画像

次に、VNC配下にあるサブネットに対してIPv6アドレスを割り当て・・・

画像
画像
画像

「NotAuthorizedOrNotFound」というエラーになる。

最初にためしたのは4/28に、PhoenixリージョンとTokyoリージョンで、どちらも同じエラーになっていた。

で・・・5/12になって検索すると、コマンドでなら成功するらしい、という情報を発見した。

Oracle Cloud 甲骨文云启用原生 IPv6 地址详细教程 – 简单、通用、免费、双栈更香
Oracle Cloud 支持 IPv6 了

これをTokyoリージョンで試してうまくいったので、Phoenixリージョンでも実施しようとしてみたところ、こちらでは、そのそも↑で失敗していたはずの操作が成功・・・

どうやら修正されつつあるようです。

というわけで、両方の手順をまとめました。

GUI操作が成功する場合

サブネットの編集でIPv6 CIDRブロックを行ってみて、成功するのであれば問題ありません。

このあと、後半にある仮想マシンインスタンスに対する設定を行います。

サブネットへのIPv6アドレス設定が失敗する場合

GUI操作で失敗する場合は、コマンド操作を行います。

Oracle CloudのWeb UIにログインして、Cloud Shellを開いてコマンドを実行

まず、コンパートメントのIDを確認

username@cloudshell:~ (ap-tokyo-1)$ oci iam compartment list
{
  "data": [
    {
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "description": "IPv6\u7528\u30cd\u30c3\u30c8\u30ef\u30fc\u30af",
      "freeform-tags": {},
      "id": "ocid1.compartment.oc1..<略>",
      "inactive-status": null,
      "is-accessible": null,
      "lifecycle-state": "ACTIVE",
      "name": "IPv6_network",
      "time-created": "2021-04-28T07:09:50.554000+00:00"
    },
    {
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "description": "idcs-e97e3212f2c9483ca8b9d1f0efa22062|22560888|OSAKANA OSAKANA NET 504302",
      "freeform-tags": {},
      "id": "ocid1.compartment.oc1..<略>",
      "inactive-status": null,
      "is-accessible": null,
      "lifecycle-state": "ACTIVE",
      "name": "ManagedCompartmentForPaaS",
      "time-created": "2019-09-19T10:16:44.796000+00:00"
    }
  ]
}
username@cloudshell:~ (ap-tokyo-1)$ 

上記出力の「compartment-id」にある「ocid1.tenancy.oc1~」が必要な値です。

これで、サブネットにつけられているIDを確認します。

username@cloudshell:~ (ap-tokyo-1)$ oci network subnet list --compartment-id ocid1.tenancy.oc1..<略>
{
  "data": [
    {
      "availability-domain": null,
      "cidr-block": "10.0.1.0/24",
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "dhcp-options-id": "ocid1.dhcpoptions.oc1.ap-tokyo-1.<略>",
      "display-name": "IPv6 \u30c6\u30b9\u30c8",
      "dns-label": null,
      "freeform-tags": {},
      "id": "ocid1.subnet.oc1.ap-tokyo-1.<略>",
      "ipv6-cidr-block": "xxxx:xxxx:8000:f501::/64",
      "ipv6-virtual-router-ip": "fe80::200:17ff:fec9:f071",
      "lifecycle-state": "AVAILABLE",
      "prohibit-internet-ingress": false,
      "prohibit-public-ip-on-vnic": false,
      "route-table-id": "ocid1.routetable.oc1.ap-tokyo-1.<略>",
      "security-list-ids": [
        "ocid1.securitylist.oc1.ap-tokyo-1.<略>"
      ],
      "subnet-domain-name": null,
      "time-created": "2021-04-28T04:44:55.872000+00:00",
      "vcn-id": "ocid1.vcn.oc1.ap-tokyo-1.<略>",
      "virtual-router-ip": "10.0.1.1",
      "virtual-router-mac": "00:00:17:C9:F0:71"
    },
    {
      "availability-domain": "xkXd:AP-TOKYO-1-AD-1",
      "cidr-block": "10.0.0.0/24",
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "dhcp-options-id": "ocid1.dhcpoptions.oc1.ap-tokyo-1.<略>",
      "display-name": "\u30d1\u30d6\u30ea\u30c3\u30af\u30fb\u30b5\u30d6\u30cd\u30c3\u30c8xkXd:AP-TOKYO-1-AD-1",
      "dns-label": null,
      "freeform-tags": {},
      "id": "ocid1.subnet.oc1.ap-tokyo-1.<略>",
      "ipv6-cidr-block": null,
      "ipv6-virtual-router-ip": null,
      "lifecycle-state": "AVAILABLE",
      "prohibit-internet-ingress": false,
      "prohibit-public-ip-on-vnic": false,
      "route-table-id": "ocid1.routetable.oc1.ap-tokyo-1.<略>",
      "security-list-ids": [
        "ocid1.securitylist.oc1.ap-tokyo-1.<略>"
      ],
      "subnet-domain-name": null,
      "time-created": "2019-09-19T10:20:05.710000+00:00",
      "vcn-id": "ocid1.vcn.oc1.ap-tokyo-1.<略>",
      "virtual-router-ip": "10.0.0.1",
      "virtual-router-mac": "00:00:17:C9:F0:71"
    }
  ]
}
username@cloudshell:~ (ap-tokyo-1)$ 

最初のブロックは新規で作ったIPv6が有効になっているもので「IPv6 テスト」という名前になっています。コマンド出力上では日本語が有効になっていないようです。

後ろのブロックがデフォルトで作成された「パブリック・サブネットxkXd:AP-TOKYO-1-AD-1」です。これに対してIPv6アドレスを付与する設定を行います。

どんなIPv6アドレスがつけられるかは、サブネット/VNC設定画面の「IPv6 CIDRブロック」を参照します。

「xxxx:xxxx:8000:f500::/56」となっています。

Oracle Cloudでは各サブネットに対して「xxxx:xxxx:8000:f5??::/64」を割り当てることになっているため下記の様に実行します。

username@cloudshell:~ (ap-tokyo-1)$ oci network subnet update --subnet-id ocid1.subnet.oc1.ap-tokyo-1.<略> --ipv6-cidr-block xxxx:xxxx:8000:f502::/64
{
  "data": {
    "availability-domain": "xkXd:AP-TOKYO-1-AD-1",
    "cidr-block": "10.0.0.0/24",
    "compartment-id": "ocid1.tenancy.oc1..<略>",
    "defined-tags": {},
    "dhcp-options-id": "ocid1.dhcpoptions.oc1.ap-tokyo-1.<略>",
    "display-name": "\u30d1\u30d6\u30ea\u30c3\u30af\u30fb\u30b5\u30d6\u30cd\u30c3\u30c8xkXd:AP-TOKYO-1-AD-1",
    "dns-label": null,
    "freeform-tags": {},
    "id": "ocid1.subnet.oc1.ap-tokyo-1.<略>",
    "ipv6-cidr-block": "xxxx:xxxx:8000:f502::/64",
    "ipv6-virtual-router-ip": "fe80::200:17ff:fec9:f071",
    "lifecycle-state": "UPDATING",
    "prohibit-internet-ingress": false,
    "prohibit-public-ip-on-vnic": false,
    "route-table-id": "ocid1.routetable.oc1.ap-tokyo-1.<略>",
    "security-list-ids": [
      "ocid1.securitylist.oc1.ap-tokyo-1.<略>"
    ],
    "subnet-domain-name": null,
    "time-created": "2019-09-19T10:20:05.710000+00:00",
    "vcn-id": "ocid1.vcn.oc1.ap-tokyo-1.<略>",
    "virtual-router-ip": "10.0.0.1",
    "virtual-router-mac": "00:00:17:C9:F0:71"
  },
  "etag": "e457a894"
}
username@cloudshell:~ (ap-tokyo-1)$ 

設定が反映されたかを確認します。

username@cloudshell:~ (ap-tokyo-1)$ oci network subnet list --compartment-id ocid1.tenancy.oc1..<略>
{
  "data": [
    {
      "availability-domain": null,
      "cidr-block": "10.0.1.0/24",
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "dhcp-options-id": "ocid1.dhcpoptions.oc1.ap-tokyo-1.<略>",
      "display-name": "IPv6 \u30c6\u30b9\u30c8",
      "dns-label": null,
      "freeform-tags": {},
      "id": "ocid1.subnet.oc1.ap-tokyo-1.<略>",
      "ipv6-cidr-block": "xxxx:xxxx:8000:f501::/64",
      "ipv6-virtual-router-ip": "fe80::200:17ff:fec9:f071",
      "lifecycle-state": "AVAILABLE",
      "prohibit-internet-ingress": false,
      "prohibit-public-ip-on-vnic": false,
      "route-table-id": "ocid1.routetable.oc1.ap-tokyo-1.<略>",
      "security-list-ids": [
        "ocid1.securitylist.oc1.ap-tokyo-1.<略>"
      ],
      "subnet-domain-name": null,
      "time-created": "2021-04-28T04:44:55.872000+00:00",
      "vcn-id": "ocid1.vcn.oc1.ap-tokyo-1.<略>",
      "virtual-router-ip": "10.0.1.1",
      "virtual-router-mac": "00:00:17:C9:F0:71"
    },
    {
      "availability-domain": "xkXd:AP-TOKYO-1-AD-1",
      "cidr-block": "10.0.0.0/24",
      "compartment-id": "ocid1.tenancy.oc1..<略>",
      "defined-tags": {},
      "dhcp-options-id": "ocid1.dhcpoptions.oc1.ap-tokyo-1.<略>",
      "display-name": "\u30d1\u30d6\u30ea\u30c3\u30af\u30fb\u30b5\u30d6\u30cd\u30c3\u30c8xkXd:AP-TOKYO-1-AD-1",
      "dns-label": null,
      "freeform-tags": {},
      "id": "ocid1.subnet.oc1.ap-tokyo-1.<略>",
      "ipv6-cidr-block": "xxxx:xxxx:8000:f502::/64",
      "ipv6-virtual-router-ip": "fe80::200:17ff:fec9:f071",
      "lifecycle-state": "AVAILABLE",
      "prohibit-internet-ingress": false,
      "prohibit-public-ip-on-vnic": false,
      "route-table-id": "ocid1.routetable.oc1.ap-tokyo-1.<略>",
      "security-list-ids": [
        "ocid1.securitylist.oc1.ap-tokyo-1.<略>"
      ],
      "subnet-domain-name": null,
      "time-created": "2019-09-19T10:20:05.710000+00:00",
      "vcn-id": "ocid1.vcn.oc1.ap-tokyo-1.<略>",
      "virtual-router-ip": "10.0.0.1",
      "virtual-router-mac": "00:00:17:C9:F0:71"
    }
  ]
}
username@cloudshell:~ (ap-tokyo-1)$ 

両方のサブネットにIPv6アドレスが入ったことがわかります。

仮想マシンインスタンスに対する設定(管理側)

Oracle Cloudの管理GUI側で、仮想マシンインスタンスに対してIPv6アドレスを割り振る必要があります。

[インスタンスの詳細]-[アタッチされたVNIC]-[VNICの詳細]にて下のほうにある「リソース」の「IPv6アドレス」を選択します。

最初は下記の様に割り当てられていません

「IPv6アドレスの割当て」をクリック

とくになにも数値入力する必要は無く、「割当て」をクリック

これで、IPv6アドレスが割り当てられました。

仮想マシン内のIPv6アドレス設定

Oracle Cloud上のインスタンスはcloud-initなどの影響化にあるため、一般的な設定手法でネットワーク設定を行っても再起動すると初期化されてしまいます。

今回の場合、IPv6未サポート時代に作られたインスタンスはIPv6が無効化されているため、有効にしなければならないのだが、正しいやりかたが不明。

公式ドキュメントの「IPv6 Addresses」には、コマンドで実行する場合のやり方が書かれていた。

しかし、これは仮想インスタンスの元となるイメージの作成時期によって動作が異なっている場合があった。

古いものではIPv6アドレス設定が無効化されており、ここ半年ぐらいのものはIPv6アドレスが有効化されていた。

有効化されている場合はドキュメント記載の「sudo dhclient -6」でIPv6アドレスが割り当てられた。

無効化されている場合は、下記の様に「sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0」実行してIPv6有効化を行った後に、「sudo dhclient -6」でDHCPv6によりIPv6アドレスが割り当てられ、通信が正常に行えることを確認できた。

[root@oraclelinux7 ~]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.22/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 86336sec preferred_lft 86336sec
[root@oraclelinux7 ~]#

[root@oraclelinux7 ~]# sysctl  -a|grep disable_ip
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens3.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.ens3.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
[root@oraclelinux7 ~]#

[root@oraclelinux7 ~]# sysctl  -w net.ipv6.conf.all.disable_ipv6=0
net.ipv6.conf.all.disable_ipv6 = 0
[root@oraclelinux7 ~]#

[root@oraclelinux7 ~]# sysctl  -a|grep disable_ip
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.ens3.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0
net.ipv6.conf.ens3.disable_ipv6 = 0
net.ipv6.conf.lo.disable_ipv6 = 0
[root@oraclelinux7 ~]#

[root@oraclelinux7 ~]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.22/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 86257sec preferred_lft 86257sec
    inet6 fe80::17ff:fe00:a543/64 scope link
       valid_lft forever preferred_lft forever
[root@oraclelinux7 ~]#

[root@oraclelinux7 ~]# dhclient -6
[root@oraclelinux7 ~]# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: ens3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc pfifo_fast state UP group default qlen 1000
    link/ether xx:xx:xx:xx:xx:xx brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.22/24 brd 10.0.0.255 scope global dynamic ens3
       valid_lft 86240sec preferred_lft 86240sec
    inet6 xxxx:xxxx:8000:f502:7f3d:7046:6c88:13a1/128 scope global dynamic
       valid_lft 7495sec preferred_lft 7195sec
    inet6 fe80::17ff:fe00:a543/64 scope link
       valid_lft forever preferred_lft forever
[root@oraclelinux7 ~]#

問題は、これを起動時に自動的に行う設定である。

とりあえず公式ドキュメントは発見できなかった。

IPv6有効化設定の方法

まずIPv6無効化の「net.ipv6.conf.all.disable_ipv6=1」はどこで設定されているのかを調べたところ、/usr/lib/sysctl.d/disable-ipv6.conf で設定されていた。

このファイルはOSパッケージにより管理されているため書き換えてはいけない。ユーザが値を変更したい場合は /etc/sysctl.d/ ディレクトリに同じファイル名でファイルを置いて変更する必要がある。

今回の場合は /etc/sysctl.d/disable-ipv6.conf というファイルを作成して、以下の内容で配置した。

net.ipv6.conf.all.disable_ipv6 = 0
net.ipv6.conf.default.disable_ipv6 = 0

これにより、起動時にIPv6が有効化された状態とすることは可能になった。

DHCPv6によるIPアドレス取得の方法

/etc/sysconfig/network-scripts/ifcfg-ens3 に 「IPV6INIT=yes」とか追加してもIPv6アドレスを割り当ててくれない。それどころか、入れたIPV6INIT記述は削除されている。

動作を調べるとcloud-initにより、起動時に毎回 /etc/sysconfig/network-scripts/ifcfg-ens3 が生成されているので、このファイルを書きかえても意味がないことが分かった。

毎起動時に起動させる手法を探したところ、cloud-initの中でper-boot という設定があることがわかった。

「/var/lib/cloud/scripts/per-boot/01_ipv6」というファイルを作り、下記を書き、実行権限を与えたところ、とりあえず希望通りの動作にはなった。

#/bin/bash
dhclient -6

とりあえず、これでOracle Cloud上に作ったインスタンスをIPv6環境に対応させることができた。

ルーティングの設定

上記だけではOracle Cloud内でのIPv6通信しかできない。

仮想クラウドネットワーク(VNC)の設定内にある「ルート・ルール」に「宛先」を「::/0」、ターゲットタイプ「インターネット・ゲートウェイ」でルールを1個追加する。

また、「セキュリティ・リスト」の「イングレス・ルール」に、ソース「::/0」、プロトコルTCP、宛先ポート範囲で「22,80,443」を追加してssh,http,httpsアクセスが可能な設定を行う。

また、出ていくパケットについての「エグレス・ルール」の方に、宛先「::/0」で全てのプロトコルを設定。

これで、外部からのIPv6アクセスも可能になったはずである。

ESXiのみ環境でPowerCLIを使ってテンプレートもどきの動作をする手法


vCenterサーバがない、ESXiサーバのみ環境ではテンプレート機能が使用できない。

とはいえ、テンプレート化した仮想マシンの中身を見ると、ふつうと同じく仮想ハードディスクのvmdkファイルが存在しているので、vmdkファイルをコピーして、新規仮想マシンを作成するPowerCLIスクリプトをかけば、似たようなことができるな、と実験。

準備するもの

・PowerCLIをインストールした環境
Windows 10で実行したが、Linux環境にPowerShell+PowerCLIをセットアップしてもいけるはず。

・Windowsの場合、sysprepを実行してシャットダウンしたvmdkファイル
sysprepを実行して、次回起動時に初期セットアップが開始されるようにしたvmdkファイル。
VMware-toolsはインストール済みであることが望ましい。

・Linuxの場合、下記の情報などを削除
RHEL7の仮想化の導入および管理ガイド第4章 仮想マシンのクローン作成によれば
/etc/udev/rules.d/70-persistent-net.rules を削除
/etc/ssh/ssh_host_* を削除
/etc/sysconfig/network-scripts/ifcfg-eth* などから IPADDRESS,NETMASK,HWADDRなどの値削除

スクリプト本体

Import-Module VMware.VimAutomation.Core

#Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false

$vcenterserver="ESXiサーバ"
$vcenteruser="ユーザ名"
$vcenterpassword="パスワード"

$targetdatastore="仮想マシンをおくデータストア名"

# 仮想マシンの名前 / ランダムで作成して、あとから変更する手法
$vmnamebase="NewVM_"
$vmnametmp=Get-Random
$vmname=$vmnamebase+$vmnametmp

# 仮想マシンスペックと接続ネットワーク指定
$vcpu=2
$vmem=6
$network="VM Network"

# 指定できるGuestOSのIDを調べるには下記を実行すること
#   PowerCLIがサポートしている一覧 
#   [VMware.Vim.VirtualMachineGuestOsIdentifier].GetEnumValues()
# 代表的なもの
# windows8Server64Guest = Windows2012
# windows9Server64Guest = Windows2016
#$vmguestosid="windows9Server64Guest"

# 元ネタのWindowsが入ったvmdkファイルの指定
# 構築時にBIOS環境かEFI環境のどちらで作ったのか注意
$vmdkfilepath="[データストア名] windows2019/windows2019.vmdk"
$vmguestosid="windows9Server64Guest"
#$vmdkfilepath="[データストア名] win2016/win2016.vmdk"
#$vmguestosid="windows9Server64Guest"
#$vmdkfilepath="[データストア名] win2012/win2012.vmdk"
#$vmguestosid="windows8Server64Guest"
# 上記の元ネタが置いてあるデータストア名を下記でも指定する
$sourcedatastore ="データストア名"

# vCenterまたはESXiサーバに接続
Connect-VIServer -Server $vcenterserver -User $vcenteruser -Password $vcenterpassword -WarningAction 0
# パスワードを書きたくない場合は
# New-VICredentialStoreItem -Host $vcenterserver -User $vcenteruser -Password $vcenterpassword
# を実行すると、資格情報保存域に登録され、以降は下記だけで接続できるようになる
# Connect-VIServer -Server $vcenterserver

$virtualportgroup=Get-VirtualPortGroup -Name $network
$datastore=Get-Datastore -Name $targetdatastore
$vm=New-VM -Name $vmname -NumCpu $vcpu -MemoryGB $vmem -Portgroup $virtualportgroup -Datastore $datastore -DiskStorageFormat Thin -GuestID $vmguestosid -HardwareVersion vmx-14


$olddiskinfo=Get-Vm $vmname|Get-Harddisk # 一時的に作られたディスクの情報を保存
$sourcevmdk=Get-HardDisk -Datastore $sourcedatastore -DatastorePath $vmdkfilepath
# ディスクの削除
Remove-HardDisk -HardDisk $olddiskinfo -Confirm:$false


# コピー先データストアのパスを生成
$targetvmdktmp=$olddiskinfo.Filename
$ed=$targetvmdktmp.LastIndexOf("/")
$targetvmdk=$targetvmdktmp.Substring(0,$ed+1) # コピー先のパス

# OSが入ったvmdkのコピー
$adddiskinfo=Copy-HardDisk -Harddisk $sourcevmdk -DestinationPath $targetvmdk -DestinationStorageFormat Thin

#$vm = get-Vm $vmname
New-HardDisk -VM $vm -DiskPath $adddiskinfo.Filename

Get-ScsiController -VM $vm | Set-ScsiController -Type VirtualLsiLogicSAS

# 仮想マシン設定変更用オブジェクト定義
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

# USBコントローラの追加
# これがないとWindows環境でマウスが動かない
# https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Where-is-the-quot-Get-USBController-quot-cmdlet-Same-with-Remove/td-p/2155582
# 上記だとUSB 2.0コントローラ追加
$newSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
$newSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
$newSpec.deviceChange[0].operation = "add"
#$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBController # USB2.0コントローラ
$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBXHCIController # USB3.0コントローラ

# EFIかBIOSか
# https://docs.vmware.com/jp/VMware-Cloud-on-AWS/services/com.vmware.vsphere.vmc-aws-manage-vms.doc/GUID-898217D4-689D-4EB5-866C-888353FE241C.html
#https://github.com/vmware/PowerCLI-Example-Scripts/blob/master/Scripts/SecureBoot.ps1
# BIOSを設定する場合は、SecureBootをdisableにする必要がある
#$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
# 仮想マシン起動オプション変更用オブジェクト定義
$bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
#$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::efi
#$bootOptions.EfiSecureBootEnabled = $true
$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::bios
$bootOptions.EfiSecureBootEnabled = $false
$newSpec.BootOptions=$bootOptions


# 仮想マシンへの設定反映
#(get-view $vm).ReconfigVM_Task($newSpec)
$vm.ExtensionData.ReconfigVM($newSpec)


# 接続切断
Disconnect-VIServer -Server $vcenterserver -Confirm:$false

解説

仮想マシンにハードディスクを追加する

仮想マシンに新しく空っぽのハードディスクを追加する場合は、「New-HardDisk -VM 仮想マシン ~」で指定するが、Copy-HardDiskでコピーしてきたハードディスクを登録する場合が分かりづらかった。

結果としては、新規と同じく「New-HardDisk -VM 仮想マシン ~」でよかった。

今回の場合は、CopyHardDiskを実行した結果を変数にいれて、それをNew-HardDIskで登録、という形にした。

$adddiskinfo=Copy-HardDisk -Harddisk $sourcevmdk -DestinationPath $targetvmdk -DestinationStorageFormat Thin

$vm = get-Vm $vmname
New-HardDisk -VM $vm -DiskPath $adddiskinfo.Filename

仮想マシンハードウェアにUSB 3.0コントローラを追加する

Host Clientから作成した場合は、USB 3.0コントローラが作成されていたが、New-VMコマンドでは作成されなかった。このため、Windowsが起動した後にUSBマウスが存在できず、マウス操作ができなかった。(キーボードはPS/2キーボード扱いとして使えたようだった)

このUSB 3.0コントローラを追加するための操作がわからず、いろいろ調べたところ「Where is the “Get-USBController” cmdlet? (Same with Remove- and New-)」の記述を見て、USB 2.0コントローラの追加手法が分かった。

その後、VirtualUSBController を起点に調べることで、 xHCIはVirtualUSBXHCIControllerという名前であることがわかり、解決した

$vm=Get-VM -Name 仮想マシン名
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$newSpec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
$newSpec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
$newSpec.deviceChange[0].operation = "add"
#$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBController # USB2.0コントローラ
$newSpec.deviceChange[0].device = New-Object VMware.Vim.VirtualUSBXHCIController # USB3.0コントローラ

# 仮想マシンへの設定反映
#(get-view $vm).ReconfigVM_Task($newSpec)
$vm.ExtensionData.ReconfigVM($newSpec)

設定を反映する部分は、ネタ元では「Get-View」を使っていたが、後述のSecureBootについての結果ではGet-VM経由で実施しているスクリプトがあったので、それを使用している。

BIOS/EFI切り替え

仮想マシンをBIOS起動にするか、EFI起動にするかを設定する手法。

2021現在のPowerCLIでNew-VMした時のデフォルトはEFI起動でセキュアブート有効になっている。

これをBIOS起動に設定する場合は、セキュアブートを無効にしてからBIOSに切り替える必要があるので下記にようになる。

$vm=Get-VM -Name 仮想マシン名
$newSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

$bootOptions = New-Object VMware.Vim.VirtualMachineBootOptions
$bootOptions.EfiSecureBootEnabled = $false
$newSpec.BootOptions=$bootOptions

$newSpec.Firmware = [VMware.Vim.GuestOsDescriptorFirmwareType]::bios

$vm.ExtensionData.ReconfigVM($newSpec)