tech.guitarrapc.cóm

Technical updates

Unifi AP AC-Pro が永遠に消えたVLAN への接続を試みる件

Unifi のアクセスポイントである Uniti AP AC-Pro (UAP) を使っています。

Access Point U6 Prowww.ui.com

今買うなら Unifi nanoHD が本来筋なのですが、いろいろあってメッシュ先のLAN ポイントとして使いたかったのでシカタナイ。

unifi-nanohd.ui.com

今回は、UAPのアップグレード中にVLAN の構成を変更したらエラーが出続けてちょっと困ったことになったので対処をメモ。

目次

再現手順

  • UAP のファームアップデートがきた通知があったので、Unifi Deram Machine(UDM) のコンパネからUAPのファームを更新
  • 更新中に 不要になったVLAN2000の削除
  • UAP が起動後、UAP が消えたVLAN へのアクセスを試みて失敗するエラーが出続けます
Message: AP[MAC ADDRESS] event: {"event_string":"EVT_AP_Notification","payload":"UAP-AC-Pro is unable to reach the DHCP server for VLAN 2000"}

どういうトラブルか

私の場合消したVLANはVLAN2000 だったのですが、インシデントに対してメール通知を仕掛けていたので1分に一度エラー通知メールが飛んでしまいました。

さて、ファームアップデート後に設定が同期していないと思われるので対処をやってみます。 上から順に解決すればそれでok でしょう。

  1. Provision のし直し
  2. Fatory Reset からのデバイス追加
  3. 適当な既存VLANネットワークの構成をし直してVLAN設定の同期

結論からいうと、適当な既存VLANネットワークの構成をし直せば同期しました。

復旧の流れ

Provision をすると、設定が同期されるので解消を期待しましたがエラーは出続けました。 Provision あんまりうまくいくことないのでぐぬぬ。

仕方ないので、UAPのFactory Reset、 UDM上から UAP を Forget、iOS の Unifi App からUAPを追加し直しても復帰後に同じエラーが出続けました。 UAP の Factory Reset 後にUDM上からデバイスをForget 忘れてて追加できなくて??っとなったのでマニュアルは読みましょう。

https://help.ui.com/hc/en-us/articles/205143490-UniFi-How-to-Reset-Devices-to-Factory-Defaultshelp.ui.com

ここまでで、UAP自体というより同期されるべきVLANの構成が正常にUAP向けに生成されているない気配なので、VLAN を修正して強制的に同期させます。 既存の適当なVLAN を修正で大丈夫です。私の場合、残していた他のVLAN ID を修正してSaveしたらUAP が自動的に構成を受け取ってエラーが消えました。

ちなみに、エラーが出てる間は既存の Guest Portal な SSID が不正なアクセスポイントとして検出もされていました。コミュニティフォーラム見るとGuest Portal を有効にしていると起こる気配も。

まとめ

自動構成同期、いいのですがどういう構成を同期しているのか、そういえばあんまり気にしたことありませんでした。 Unifi の場合、Device > UAP > Settings > Download Device Info で動作状況がダウンロードできるので良いのですが、ちょっと困りますね。

余談

そういえばこういう古い記事はいい加減直してほしいものです。VHT20 以外も選べるようになってるのですよ。

internet.watch.impress.co.jp

UAPのVHTは選択可能になっている

scoop の bucket を自動更新する

Scoop Bucket を作るのは避けたいものです。 しかし、Main や Extras に追加するのもアレだし、既存のパッケージ更新はメンテされてないし、など様々な理由で自分のバケットを作ることはあるでしょう。

自分のバケットを持った時に面倒なのが、バケットの更新追従です。 幸いにも Scoop には Excavate という自動更新する仕組みがあります。今回はこれを仕込んでみましょう。

目次

TL;DR

  • Bucket の manifest を記述した json に checkverautoupdate セクションを設定する
  • Excavate と更新スクリプトをバケットに配置する
    • バケットフォルダで、bukcet/ などフォルダを掘っている場合はスクリプトで対応が必要
  • Excavate は docker-compose で動くので、動かしっぱなしにするか適当などこかで定期実行

実際に使用しているリポジトリ

この記事で使っている自動更新のためのスクリプトや仕組みは .github フォルダに一式が入っています。

github.com

動作環境

バケットの自動更新は以下の環境で動作します。

  • Linux コンテナ
  • PowerShell 7
  • 定期実行環境 (ローカルマシン、GitHub Actions、Kubernetes など)

Linux コンテナで動作するので、事実上実行環境に困らないでしょう。Windows でも実行できますが、私はLinuxのみで行っています。

Scoop App Manifest 自動更新の仕組み

3つやることがあります。

  1. 自動更新するバケットjsonを自動更新に対応させる
  2. 自動更新スクリプトをバケットのリポジトリにおく
  3. 自動更新を定期実行する

順番に見ていきましょう。

1. 自動更新するバケットjsonを自動更新に対応させる

Scoop App Manifest は、checkverautoupdate に適切な内容を記述することで自動更新対象のマニフェストとして認識されます。この辺りは公式の Wiki に書いてあります。

App Manifest Autoupdate · ScoopInstaller/Scoop Wiki · GitHub

といってもWikiの内容は複雑でよくわからん.... ということで実際に使っているシンプルなパターンで説明します。

GitHub のリリースページを見る

今回のパターンは GitHub Releases のパッケージ更新を見てバケットを構成している場合に利用できます。ただし、プレリリースではない && バージョン1.0.0 や v1.0.0 といったパターンでタグ公開されているの2点が前提です。

実際に利用しているctop を定義したマニフェストを用意しました。

{
    "description": "Top-like interface for container metrics",
    "homepage": "https://github.com/bcicen/ctop",
    "version": "0.7.5",
    "license": "MIT",
    "url": "https://github.com/bcicen/ctop/releases/download/v0.7.5/ctop-0.7.5-windows-amd64#/ctop.exe",
    "hash": "sha256:bffb1499d62c46b70dd25d557b653f812ccdc8b4bfb08473c063a6265faf78b3",
    "bin": "ctop.exe",
    "checkver": "github",
    "autoupdate": {
        "url": "https://github.com/bcicen/ctop/releases/download/v$version/ctop-$version-windows-amd64#/ctop.exe"
    }
}

自動バージョン更新に必要なのは、checkver と autoupdate のセクションです。

  • checkver"github" で問題ありません。これでリリースぺージのTagが \/releases\/tag\/(?:v|V)?([\d.]+) パターンで公開されていれば抽出されます
  • autoupdate のセクションは、$version を使って実際のリリースページのダウンロードurl を表現します。url が https://github.com/bcicen/ctop/releases/download/v0.7.5/ctop-0.7.5-windows-amd64 なので、0.7.5 というバージョンが $version に置き換えられていることがわかります

これでバケットのjsonは準備が整いました。

2. 自動更新スクリプトをバケットのリポジトリにおく

リポジトリ直下にバケットのjsonを配置しているか、bucketフォルダを掘ってそこにまとめているかで微妙に異なります。

bucket フォルダを掘っている場合は、lukesampson/scoop-extras の bin フォルダの中身を、そのまま自分のリポジトリの/binに持ってくるといいでしょう。

lukesampson/scoop-extras の bin フォルダの中身

もしもリポジトリ直下にバケットjson を置いている場合は、以下のように $dir = "$psscriptroot/.." とします。各スクリプトにこの変更がいるので面倒です。

# auto-pr.ps1
param(
    # overwrite upstream param
    [String]$upstream = "<user>/<repo>:master"
)
if(!$env:SCOOP_HOME) { $env:SCOOP_HOME = resolve-path (split-path (split-path (scoop which scoop))) }
$autopr = "$env:SCOOP_HOME/bin/auto-pr.ps1"
# $dir = "$psscriptroot/../bucket" # checks the parent dir
$dir = "$psscriptroot/.." # checks the parent dir
iex -command "$autopr -dir $dir -upstream $upstream $($args |% { "$_ " })"

これでバケットのスクリプト配置も完了です。

NOTE: 調べるとこのスクリプト名がbucket-updater.ps1 だったり auto-pr.ps1 だったりしますが、後述のExcavatorを使う場合どちらでも対応されているので大丈夫です。auto-pr.ps1 が公式でも使ってて新しいかな?

3. 自動更新を定期実行する

自動更新方法はWikiにもいくつかのっています。

App Manifest Autoupdate · ScoopInstaller/Scoop Wiki · GitHub

個人的には、ScoopInstaller/Excavatorを用いて docker-compose で実行するのがおすすめです。Linux で実行できるのと、docker-compose が利用できるので実行環境を選びません。あとこの方法なら Kubernetes で実行も簡単です。

github.com

docker-compose を実行すると ssh キーが生成されるので、公開鍵 id_rsa.pub をGitHub に登録して push できるようにしましょう。sshキーを再利用する場合は、id_rsa も取得しておいて、docker-compose 実行時にマウントさせればok です。

$ docker-compose up --build
$ docker-compose exec bucket cat /root/.ssh/id_rsa.pub
$ docker-compose exec bucket cat /root/.ssh/id_rsa

このコンテナイメージは定期的に呼び出して実行するには注意があります。/sbin/my_init を実行した上でないと scoop コマンドがコンテナ内部で見つからずエラーが出ます。

走らせっぱなしで定期実行する前提なイメージになっているので、自分のように定期的に呼び出し実行する場合は docker-compose で次のようなラッパーコマンドを用意して呼び出すといいでしょう。

#!/bin/bash
/sbin/my_init &
chmod 600 /root/.ssh/id_rsa
pwsh ./root/scoop/lib/install.ps1
bash -x /root/excavate.sh

これで コンテナを使っていい感じに更新されるようになります。

実行環境について

このような定期実行環境は、Kubernetes の cron job、後今日使えるようになった Amazon ECS のdocker-compose対応などが楽でしょう。

www.docker.com

GitHub Actions での使用は、使用条件のここに該当するかによりそうです。

any other activity unrelated to the production, testing, deployment, or publication of the software project associated with the repository where GitHub Actions are used.

バケットのデプロイ作業なので実行は許されそうですが、自前のクラスタで実行で行えるならそれがいいでしょう。 仮にリポジトリで実行していますが、自前Kubernetes クラスタでの実行に変更を予定しています。

以下に GitHub Actions で実行する場合の Workflow を示します。

name: auto update bucket

on:
  schedule:
    - cron: "0 * * * *"
  workflow_dispatch:

jobs:
  update:
    timeout-minutes: 10
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - run: openssl aes-256-cbc --pbkdf2 -d -in .github/.ssh/id_rsa.cipher -k ${{ secrets.CIPHER_KEY }} >> .github/.ssh/id_rsa
      - run: docker-compose up
        working-directory: .github

パッケージの更新ログの例です。

main_1  | 
main_1  | ScriptBlock ID: f43b73d1-2181-437c-9d72-8b0797e62035
main_1  | Path: /root/scoop/lib/install.ps1
main_1  | py: 1.0.1.6
main_1  | DejaVuSansMono-Bront: couldn't match '\/releases\/tag\/(?:v|V)?([\d.]+)' in https://github.com/chrismwendt/bront/releases/latest
main_1  | bombardier: 1.2.5 (scoop version is 1.2.4) autoupdate available
main_1  | Autoupdating bombardier
main_1  | Downloading bombardier-windows-386.exe to compute hashes!
main_1  | Downloading https://github.com/codesenberg/bombardier/releases/download/v1.2.5/bombardier-windows-386.exe#/bombardier.exe (9.7 MB)...
main_1  | Computed hash: d2bfd99019ca590610c89ccf829bf4c84ed6652821fe55e7f9bcf342106fe496
main_1  | Downloading bombardier-windows-amd64.exe to compute hashes!
main_1  | Downloading https://github.com/codesenberg/bombardier/releases/download/v1.2.5/bombardier-windows-amd64.exe#/bombardier.exe (10.9 MB)...
main_1  | Computed hash: 52e0c22e3a10c06f7013bbb09d713ab52fae6fba5a86a5ffcfdd6546ed86b7cf
main_1  | Nov 22 12:17:39 3e2cb27a65fb powershell[86]: (7.0.2:9:80) [ScriptBlock_Compile_Detail:ExecuteCommand.Create.Warning] Creating Scriptblock text (1 of 1):
main_1  | {⏎⏎            $architecture = $_.Name⏎⏎            if ($json.architecture.$architecture.$prop -and $json.autoupdate.architecture.$architecture.$prop) {⏎⏎                $json.architecture.$architecture.$prop = substitute (arch_specific $prop $json.autoupdate $architecture) $substitutions⏎⏎            }⏎⏎        }
main_1  | 
main_1  | ScriptBlock ID: a1ca077d-4175-458e-9ad3-e0f9e4c68c86
main_1  | Path: /root/scoop/lib/autoupdate.ps1
main_1  | Writing updated bombardier manifest
main_1  | ctop: 0.7.5
main_1  | warning: LF will be replaced by CRLF in bucket/bombardier.json.
main_1  | The file will have its original line endings in your working directory.
main_1  | Creating update bombardier (1.2.5) ...
main_1  | hub add bucket/bombardier.json
main_1  | warning: LF will be replaced by CRLF in bucket/bombardier.json.
main_1  | The file will have its original line endings in your working directory.
main_1  | hub status --porcelain -uno
main_1  | hub commit -m 'bombardier: Update to version 1.2.5'
main_1  | [master 603a742] bombardier: Update to version 1.2.5
main_1  |  1 file changed, 5 insertions(+), 5 deletions(-)
main_1  | Pushing updates ...
main_1  | hub push origin master
main_1  | Warning: Permanently added the RSA host key for IP address '140.82.112.4' to the list of known hosts.
main_1  | To github.com:guitarrapc/scoop-bucket.git
main_1  |    c5e2c3f..603a742  master -> master
main_1  | hub reset --hard
main_1  | HEAD is now at 603a742 bombardier: Update to version 1.2.5
main_1  | + '[' -f /root/bucket/bin/bucket-updater.ps1 ']'
github_main_1 exited with code 0

まとめ

難しい記述をしなくても自動更新できるのはいいことです。 実行環境だけ面倒ですね。

参考

手の入れ方が好みじゃないので参考程度にしています。 こういう公式のやり方に乗っかる場合は、コンテナに手を入れないのがおすすめです。メンテしきれなくなるので。

Scoopを使ったWindows環境構築のススメ - Hyper!!! - Qiita

Unifi Dream Machine で MAP-E方式の IPv6 に対応する

IPv4 PPPoE からIPoE にしつつ、Unifi Dream Machine (UDM) で IPv4 over IPv6 環境でアクセスするまで組んだのでそのメモです。

Unifi Dream Machine はMAP-E に対応していないので、ちょっと小細工が必要だったのは学びでした。

私が欲しい内容の記事がなかったので自分で書くしかないのです。

tl;dr;

HGW と組み合わせることで、UDMは MAP-E 方式の IPv6 に対応します。

  • MAP-E 方式の IPoE (IPv4 over IPv6) には「ひかり電話」の契約についてくるホームゲートウェイ(HGW) が必要です
  • HGW が MAP-E をしゃべるため、UDM が MAP-E に対応していなくても問題ありません
  • UDMは HGW からDHCPv6 Prefix Delegate (DHCPv6-PD) を行うことができます
  • UDM 配下のクライアントは IPv4 over IPv6 で通信できます

構成は以下の通り。

  • ぷらら光
  • 光配線方式
  • ひかり電話あり、HGW あり
  • Unifi Dream Machine

結果、UDM の出口速度でIPoE VDSL から IPoE光配線 で 約6-10倍に上がったのでいったんこれで。(満足できてない)

今後のメモ

  • HGW のLAN接続とUDMのWifi を比べたときに、アップロードは有線並みに出ている一方でダウンロードが遅い (要改善)
  • WIFI 6 対応した Unifi 製品はアメリカでアーリーアクセスで出ているので日本にも来てほしい (希望)
  • WAN回線を 2Gbps 程度にあげるか、10Gbps サービス試していきたいところ (まずはWifi速度の改善をしてから)

前説

いくつか事前情報を共有します。

記事の対象となる人

  • UDM (UDM Pro) を使いMAP-E 方式の IPoE を用いて、クライアントの IPv6 ネイティブアクセスを可能にしたい人
  • 海外ルーターなどMAP-E をサポートしてない自分の好みのルーターを使う人

はたして国内に何人いるのでしょう、そんなにいない気がします。

記事の対象ではない人

  • UDM 配下のクライアントが IPv6 を持たなくていいなら、この記事は不要です。IPoE を契約してUDM をつなぎ IPv4 のみにすればok です、この記事は IPv6 もクライアントに配布してつなぎたい場合に役立つでしょう
  • 国内の IPoE 対応を謳うルータを使うのなら、この記事は不要です。多くの場合、MAP-E (あるいは DS-Lite) 方式のIPoE で契約して、プロバイダが提供する無線ルーターあたりでつなげばいいでしょう。自前のWifi にしても AP モードで適当につなげばok なはずです
  • Nuro もIPv4/v6デュアル方式なので、この記事は不要です。ほぼなにも考えずただつなぐだけでいいはずです。DHCP-PD で Prefix /56 が降ってきます

LANネットワーク環境の前提

私の個人環境は8年前から完全にWifiで統一しています。 ケーブルが嫌いというのもあるのですが、配線や配置の自由さと、ネットワーク環境でやりたい放題やるを考えたときに、Wifiもまとめて制御することを自分に課しています。有線LANは好みではないし、Wifiの技術的進展が目覚ましいのでよい。

Wifi で統一するにあたり、当然メッシュ環境が欲しくなるので以前は Amplifi を使っていました。

tech.guitarrapc.com

しかし、メッシュを広げつつ、計測やIDS/IPSを展開しつつ、今後の変化にも追随することを考えるとUnifi にしたくなります。でも Cloud Keyはいや。ということで、Unifi Dream Machine は欲しかったマシンであり、日本Ubiquiti Store で販売されてすぐに切り替えました。

Dream Machinejp.store.ui.com

私の環境において「あらゆる機器は UDM配下からのアクセスになる」というのが構成上の大前提となります。

もしもUDMに興味がなくて、「さくっとIPoEでいい感じに組みたい」だけなら適当にIPoE 対応の国内ルーターでも使えばいいと思います、好きにするのが一番。Synology とかもMAP-E対応ありますしね。

www.synology.com

WAN ネットワーク環境の前提

私はISPに、ぷららを利用しています。

以前は住んでいたところが VDSL だったため、何をどうあがいても100Mbps が上限でした。

とはいえ、IPv4 PPPoE だと夜間の速度が不安定になることが多くなってきたので、回線速度を安定させるため IPoE にすることにします。

IPoE にするだけで、いったん回線速度は安定しますが、せっかくなので IPv6 への対応も考えたいものです。 しかし、ぷららが提供する MAP-E 方式の IPoE 環境とUDM は相性が悪いので「UDM配下のクライアントで IPv6 ネイティブでアクセスさせるためにどんな構成にするのか」、これがこの記事のポイントです。

ネットワーク環境

IPv4 で PPPoE でつないでいるときは次のような環境です。

インターネット -- | | -- ONU -- ルーター -- UDM -- 各Wifiクライアント

最終的に、MAP-E方式の IPv6 で次のような構成に持っていきます。

インターネット -- | | -- HGW -- UDM -- 各Wifiクライアント

PPPoE から IPoE までの変遷を見ていきます。

事前調査

IPoE と UDMをどう組めばいいのか考えます。

UDM は MAP-E にも DS-Lite にも対応していない。これは調べればすぐにわかります。

ではどうすれば組めそうでしょうか。

採用しなかった方法

まず採用しなかった方法を見てみます。

EdgeRouter の EdgeOS なら DS-Lite 構成組まれている方もいますが、UDM は UnifiOS でそういった構成は組めません。(そういえば MAP-E 組んでいる人はいませんね)

stop-the-world.hatenablog.com

こういう MAP-E に対応していない場合のよくある対処の1つは、IPv4 アクセスは IPv4 PPPoE 回線から、IPv6 アクセスは IPv6 プラスルーター経由でアクセスさせる方法です。PPPoE を残したくないですし、なんのための IPv4 over IPv6 なのかって話で好みではありません。(過渡期としてはやむを得ないですね。ぷららの技術部門の人と話をしたときも、ぷららの人はこの構成で話していました、わかる。)

chitoku.jp

あるいは、ひかり電話なしでRAをLANにいきわたらせてしまうのも手でしょう。IPv6でクライアントがグローバルにさらされるのを避けるために、スマートスイッチでタグベースVLANを使ってIPv6を選択的に設定するのもありだと思います。(めんどくさすぎて好みじゃない)

yabe.jp

どれも単純ではない、自分が運用したくないと感じる構成です、こういうのは避けたい。

必要な条件が何かを考える

IPv4 over IPv6 でUDMを使ってどのように組めるか調査すると、「ひかり電話」の有無で前提が大きく変わるのがわかります。ひかり電話の有無で DHCPv6 が使えるかが決まり、同時にHGW を使えるかも決まります。

構成の単純さとDHCPv6 を考えるとひかり電話はいれるのが妥当だと思います。月500円かけるだけで、いかんともしがたい課題が解決するのです。ひかり電話は使わないので、これだけのために入れるのは納得感はないですが目を瞑ります。

もう1つが HGW です。UDM はMAP-Eをしゃべられないルーターなので、事前にMAP-E をしゃべらせておく必要があります。

  • HGWがない場合、MAP-E 認証をさせるため、HGWとUDMの間に対応ルータを置いた二重ルータが確定します
    • HGWとUDM間にルーターを挟むため、DHCPv6-PD がスムーズにいかなくなります
  • HGW がある場合、HGW でMAP-E認証が終わっているので、UDM を直接刺せます
    • UDMで直接DHCPv6-PDを受け取ることができます

余談: HGWから直でなくても、MAP-E 対応ルーターが RA パススルーに対応していればワンチャンとふと思いましたが、私の借りた MAP-E対応ルーター WN-AX1167GR2 は RAパススルーがなかったです。

必要な条件

次の通りです。

  • ひかり電話を契約する
  • HGW を手に入れる

YAMAHA などでもよく組まれているほう方法ですね。

y2lab.org

NTT の方式でいうところの、光配線方式の接続パターンB が該当します。

4466.jp

では構成の変遷を見ていきましょう。

余談: UDM とMAP-E

UDM が MAP-E 対応すると、ひかり電話なしでもよくなるので対応されると嬉しいですね。対応されるかは期待はあまりできなさそうですが...。

https://community.ui.com/questions/Feature-Request-IPv4-over-IPv6-in-Japan-using-IPOE-MAP-E-or-DS-LITE-etc-/452a1bbf-6880-4cc9-9c75-fae87ff68ca4community.ui.com

1. PPPoE から IPoE への変更

ぷららの場合、ぷららv6エクスプレスで IPoEを提供しています。 プロフィールページから「ぷらら光」に契約を切り替えることでIPoE に変更できます。 なかなか手間がかかる作業で、事前にNTTから承諾番号を得る必要があり、ぷららの契約切り替え自体も概ね2週間見る必要があります。

www.plala.or.jp

この時点では、「HGW での IPoE 接続」はしません、まずは IPoE 接続を安定させます。ということで、IPoEへの切り替えを申し込むにあたり、MAP-E対応ルータとして「ぷららWi-Fiルーター」をレンタルします。

PPPoE から IPoE への切り替え時の申し込みは次の通りです、めんどくさい。

  • 切り替えに2週間程度は猶予時間を見る
  • 事前にNTT から承諾番号を得る
  • 「ぷらら光」への切り替え
  • 「ひかり電話」の契約
  • 「ぷららWi-Fiルーターレンタル」の申し込み

変更予定日前に、HGWとMAP-E 対応ルーターが届きます。変更予定前日夜にでもVDSLルータとUDM の間に入れましょう。AM8:00ぐらいに切り替えが走ったのが計測できました。

IPoEへの切り替えが無事に完了すると、ぷららv6エクスプレスが開通済み、IPoE対象接続先がIPv4+IPv6へと変わります。

接続状態はVDSL方式の接続パターンCになります。すごく面倒くさい。

VDSLルーター -- HGW -- MAP-E対応ルーター -- UDM -- 各Wifiクライアント

この時点では、UDM 配下には IPv6 が配布されず IPv4のみになります。MAP-E対応ルーターを抜いて IPv6 ネイティブ接続にすることはできますが、はっきり言ってどこも接続できないのでムリ。 (GitHub も Twitter もつながらないのは意外でしたが)

なので、IPoE + IPv6 もクライアントで使いたいなら、MAP-E 対応ルーターに直接接続すれば期待通り動きます。(私はUDM を使いたいのでやらない)

通信速度は、VDSL の上限によって 100Mbps できっちり止められます。PPPoE とは違い、IPoEでは速度はある程度安定し、100Mbps 程度ならずっと維持できるのでいいでしょう。

余談ですが、UDMの代わりに Amplifi HD をおいて Bridge 接続 + Router Steeling を仕掛けると、Wifi クライアントに IPv6 が配布されたりします。Amplifi をどうしても使いたい人はこれでもいいですね。

2. VDSL から 光ファイバー回線への切り替え

いろいろあって、住んでいるところがVDSL回線が光ファイバー回線に更新されることになりました。(下り/上り 1Gbps)

ということで、当然 VDSL ルーターは不要になり、光コンセントからHGWに直接回線がつながるようになります。 接続状態は光配線方式の接続パターンCに相当します、一般的な光回線が入っている場所ではこの構成が多いでしょう。

HGW -- MAP-E対応ルーター -- UDM -- 各Wifiクライアント

VDSL がなくなるだけですが、これで回線速度が 300Mbps に上がりました、遅いもののだいぶん改善しました。(LAN も Wifi も同じ速度がでている) 当然ですが、まだ UDM の配下には IPv6 は渡せず IPv4 のみです。

余談: MAP-E 対応ルータの下に UDM を置くと、なぜか速度が 60~70Mbps に落ちたのですが、どうやら LAN の DHCPv6 が残っているとゴミ設定で速度が落ちるバグがある気配があります。LAN の IPv6 対応を無効にして再起動すれば速度劣化なしに300Mbpsでます。(その後は同じ設定をいれても速度劣化がなくなりました)

3. ホームゲートウェイ(HGW)によるIPoE接続 への変更

これで、UDM で IPv6 を配布する準備が整います。IPoE の MAP-E 接続をHGW にゆだねましょう。

HGW にするには、HGW製品が型番が300番台以降でないとだめなのと、いくつか使えなくなるサービスがあるので注意です

faq.plala.or.jp

faq.plala.or.jp

まずは、ぷららのプロフィールから 「ホームゲートウェイ(HGW)によるIPoE接続」への切り替えを申し込みましょう。

www.plala.or.jp

次の日の夜ぐらいにいきなりスパッと切り替わります。HGW で PPPoE 接続を入れていない場合は回線が切れます、MAP-E対応ルーターは不要なので外します。

これで、光配線方式の接続パターンB に無事移行できました。

HGW -- UDM -- 各Wifiクライアント

余談: ちなみに、デフォルトのLANサブネットが HGW (192.168.1.1/24) と UDM (192.168.1.1/24) でかぶります。UDM のLANを 192.168.2.1/24 あたりにずらしておきましょう。(MAP-E 対応ルータが 192.168.0.1/24 なので放置していた)

HGWに特に設定は不要なので、HGW と UDM を再起動すればすべてが期待通りに動き出します。(PPPoE は不要ですし外しておきましょう)

4. UDM で IPv6 を受けてクライアントに配布する

ようやく本題です。

ひかり電話を契約していれば、RA ではなくDHCPv6-PD (Prefix Delegate) 方式が利用できます。 早速UDM で IPv6 を HGW から受ける設定 (WAN) と、クライアントへのIPv6 配布の2点を行います。

WAN の設定

ひかり電話がある場合、IPv6は DHCPv6-PD 方式で60bitのPrefix再委任が行われます。(ひかり電話なしだと、RAが直でおりてきて 64bit しかこない)

ということで、IPv6の構成を行います。加えて、DNS の解決ができなくなるケースを防ぐため、DNSにGoogle DNS あたりを指定します。

  • IPv6 Connection Types: DHCPv6
  • Prefix Delegation Size: 60
  • DNS: 8.8.8.88.8.4.4

LAN の設定

LAN に IPv6 を配布する設定を行います。 IPv6 RA、IPv6 Priority、DHCP Range はデフォルトのままでok です。DHCPv6/RDNSS DNS は、Google DNS を指定します。

  • IPv6 Inteface type: Prefix Delegation
  • IPv6 RA: 有効
  • IPv6 Priority: High
  • DHCP Range: Start ::2、 Stop ::7d1
  • DHCPv6/RDNSS DNS Control: Manual
  • DNS Server1: 2001:4860:4860::8888
  • DNS Server2: 2001:4860:4860::8844

IPv6 の確認

ipv6 test を行います。 HGW - UDM 接続 + DHCPv6-PD の構成を組むことで、UDM のWifi クライアントもIPv6テストが通るようになります。長かった。

速度の確認

HGW と UDM を直接つなげたことでルーターが1つ減ります。ということで、速度も改善します。

UDM との LAN 接続で 610Mbps まで向上します。

UDM の 5GHz 160 VHT と 1.7 Gbpsのネットワークアダプタで接続すると、下りがLAN より劣化しているのが気になります。(そもそも 160 VHT は非推奨です) アップロードは想定通り向上しています。

まとめ

IPv6 IPoE で接続して、好きなルーターで良い感じに構成するなら、ひかり電話は契約しておくといいです。 DHCPv6-PD に持ち込めばどうとでもなれるので、ひかり電話なしで頑張るのは避けましょう。

なによりも、VDSLな住居は絶対に避けて光配線の住居を選びましょう。自分で入れるのいろいろ面倒ですしね。

Windows開発環境をscoopで継続的に構築する

以前 Windows の開発環境を scoop で構築しているということを書きました。

tech.guitarrapc.com

その際に、scoopを継続的に使っていくためのツール ScoopPlaybook を書いたことに触れました。 今回はその ScoopPlaybook の紹介です。

目次

TL;DR

  • ScoopPlaybook という PowerShellモジュールを作った(2年近く使っている)
  • scoop で何をインストールするかをYAML定義して使える
  • Scoop-Playbook コマンドでYAML通りに実行される
  • 使い心地は、Ansible Playbook のYAML定義とコマンドにインスパイアされている

scoop 使っていて、YAMLでインストールするツールを定義したい方は使ってみてください。

目指す姿

私は普段からOS環境を壊すことをアリと考えています。 ただし壊すからには再構築にコストをなるべくかけたくないため、対象のマシン上で再構築がコマンド1つでできるようにしています。 macOS は Homebrew や defaultsをAnsible Playbookで構築し、Ubuntu は Ansible Playbook で構築しています。

Ansible Playbook を使うことで、ほどよく緩くいい感じの目指す姿が可能になります。

  • 利用する開発ツールをYAMLに定義して
  • 何度実行しても同じ結果に収束させる

例えば Homebrew でインストールする場合は次のように定義できます。

# roles/homebrew/tasks/main.yaml
- name: 'homebrew packages installation'
  homebrew:
    name: '{{ item.name }}'
    state: "{{ item.state|default('present') }}"
  with_items: "{{ homebrew_packages }}"

# roles/homebrew/vars/main.yaml
homebrew_packages:
  - name: autoconf
  - name: awscli
  - name: aws-iam-authenticator
  - name: azure-cli
  # and so on....

一度定義してしまえばツールを定義に追加したり、アンインストール ( state: "absent" ) を指定するだけとメンテナンスが非常に簡単です。

site.yml を置いたルートパスでいつも同じコマンドを実行するだけで、YAML定義通りに環境が構築されます、便利。

$ ansible-playbook -i hosts site.yml

sudo が必要な操作 (become) なら、実行時に入れるだけです。

ansible-playbook -i hosts site.yml --ask-become-pass

WSL との相性もよく、気軽に環境を壊してサクッと作り直すことがコストでなくなります。

自分の環境にどんなツールをいれているかを説明することがふとしたときにあるのですが、定義によって、いつでも確認したり継続的に変更をかけたり、場合によっては他人に共有できるのは個人的に好みです。

WindowsでAnsiblePlaybook のようなアプリケーションインストール基盤を作る

環境の再構築はWindowsでもたびたび行います。(OSいれなおしでなくてもリセットはやりますよね)

scoopを使っていくことに決めたときに、コマンドの羅列地獄になるのは嫌だと思いました。 しかしAnsible をWindows localhost に実行はサポートされていないので、Ansible Playbook のような定義とインストールを提供することにしました。(WSLからAnsible実行するというのはナシ派) その晩にザクっと書いたのが ScoopPlaybook という PowerShell Module です。

github.com

あんまり使い方とか書いていないので、どういう利用をするのか紹介します。

scoop の通常のインストール

例えば、scoop でgow、jq、time、unzipをインストールする場合、コマンドラインで次のように実行するでしょう。

scoop install gow jq time unzip

あるいは、次のようにコマンドを分けているかもしれません。

scoop install gow
scoop install jq
scoop install time
scoop install unzip

アンインストールもコマンドラインで制御できます。

scoop uninstall gow

入っているツールは scoop list で見えますが、ほかの環境や再構築、追加インストールをするときはいちいち考えるの嫌になります。

ScoopPlaybook で定義からインストールする

ScoopPlaybook はAnsible Playbook でやっていたのと同じ目指す姿を提供します。

  • 利用する開発ツールをYAMLに定義して
  • 何度実行しても同じ結果に収束させる

利用方法は Ansible Playbookに合わせています。

  • ルートパス/site.ymlに 利用する role のYAML定義し、
  • ルートパス/roles/バケット/tasks/main.yml にツールをYAML定義したら、
  • ルートパスで、Scoop-Playbook コマンドを実行すると、Scoopバケットやツールが定義通りにインストール/アンインストールされる

YAMLで定義して、コマンド1つで定義を実行。ただそれだけです。 実際にどうやるのかイメージしにくいので利用例を見てみましょう。

利用例

先ほどのmainバケットのツールをScoopPlaybookでYAML定義してインストールしてみましょう。 ScoopPlaybook モジュールとYAM解析モジュールをインストールします。PowerShell 5.1 以降で動作します。

PS> Install-Module ScoopPlaybook -Scope CurrentUser
PS> Install-Module "PowerShell-Yaml" -Scope CurrentUser

適当にルートパスを切ります。

md ./begin
cd ./begin

まずは、インストールしたいアプリの定義YAMLを ルートパス/roles/main/tasks/main.yml に定義します。

PS> mkdir roles/main/tasks
PS> New-Item roles/main/tasks/main.yml
PS> vim roles/main/tasks/main.yml
- name: "Install main tools"
  scoop_install:
    state: present
    bucket: main
    name:
      - gow
      - jq
      - time
      - unzip

インストールするロールを指定したYAML定義 site.yml をルートパスにおきます。

PS> New-Item site.yml
PS> vim site.yml

今回のロールは main なのでこれを1つ指定します。

name: Windows Setup
roles:
  - main

早速定義をドライランしてみましょう、次のコマンドを site.yml のパスで実行します。

PS> Scoop-Playbook -Mode check

scoop のバケットを更新して (scoop update) 、ツールがインストールされるか実行計画を確認できます。

PRE [scoop : status] ***************************************************************
  [o] skip: [run with 'check' mode]
  [o] skip: [prerequisiting availability]
  [o] skip: [updating buckets]
  [o] check: [scoop-update: Updating Scoop...]
  [o] check: [scoop-update: Updating 'main' bucket...]
  [o] check: [scoop-update: Scoop was updated successfully!]
  [o] skip: [status checking]
  [o] skip: [scoop-status: Scoop is up to date.]
  [o] check: [scoop-status: Updates are available for:]
.... 省略
PLAY [Windows Setup] ***************************************************************

TASK [main : Install main tools] ***************************************************
  [!] check: [scoop_install: gow] => Installed: No
  [!] check: [scoop_install: jq] => Installed: No
  [!] check: [scoop_install: time] => Installed: No
  [!] check: [scoop_install: unzip] => Installed: No

問題なければインストールします。Mode パラメーターを省略するか、-Mode run を明示的に付けると実行します。

PS> Scoop-Playbook
PRE [scoop : status] ***************************************************************
.... 省略
PLAY [Windows Setup] ***************************************************************

TASK [main : Install main tools] ***************************************************
  [!] changed: [scoop_install: gow] => Installed: No
  Installing 'gow' (0.8.0) [64bit]
Loading Gow-0.8.0.exe from cache
Checking hash of Gow-0.8.0.exe ... ok.
Extracting dl.7z ... done.
Running pre-install script...
Linking ~\scoop\apps\gow\current => ~\scoop\apps\gow\0.8.0
.... 省略
'gow' (0.8.0) was installed successfully!
  [!] changed: [scoop_install: jq] => Installed: No
  Installing 'jq' (1.6) [64bit]
.... 省略
'jq' (1.6) was installed successfully!
  [!] changed: [scoop_install: time] => Installed: No
  Installing 'time' (0.2018.07.25) [64bit]
.... 省略
  [!] changed: [scoop_install: time] => Installed: No
  Installing 'time' (0.2018.07.25) [64bit]
.... 省略
'time' (0.2018.07.25) was installed successfully!
Notes
-----
Please use 'timecmd' instead of 'time' in cmd.exe.
  [!] changed: [scoop_install: unzip] => Installed: No
  Installing 'unzip' (6.00) [64bit]
.... 省略
'unzip' (6.00) was installed successfully!

再度実行しても同じ結果に収束します。 もし更新があれば更新してくれます。

PS> Scoop-Playbook
Scoop-Playbook
PRE [scoop : status] ***************************************************************
.... 省略
PLAY [Windows Setup] ***************************************************************

TASK [main : Install main tools] ***************************************************
  [o] skip: [scoop_install: gow] =>   gow  0.8.0
  [o] skip: [scoop_install: jq] =>   jq  1.6
  [o] skip: [scoop_install: time] =>   time  0.2018.07.25
  [o] skip: [scoop_install: unzip] =>   unzip  6.00

何かの理由でscoop コマンドで直接インストールすることもあるでしょう、そんな時は定義に一行足せばいいだけです。 もし scoop コマンドで誤ってアンインストールしても、Scoop-Playbook を実行すれば元通りです。

Scoop で管理したいツールを定義通りに実行する。それができます。

普段の利用例

私は ScoopPlaybook を使ってYAML定義をして GitHub においています。 参考に私が普段使っているリポジトリを置いておきます。ルートパスはこのリポジトリの ./envs/windows/ パスです。

local-provisioner/envs/windows at main · guitarrapc/local-provisioner · GitHub

そのため、環境構築するときは次のコマンドを実行しています。

git clone https://github.com/guitarrapc/local-provisioner.git
cd local-provisioner/envs/windows
. ./prerequisites.ps1
sudo Scoop-Playbook

ツールの追加や削除をしたいときは、定義のYAML を修正して git commit/push するだけです。 バッチファイルやスクリプトではないので、どのように動作するかは考えず、ツールをYAMLに並べるだけなのはメンテの面で作ってよかったと思っています。 実際これなしで scoop とかいやです。

できること

ScoopPlaybookは次の操作が可能です。これしかできないです。

  • scoop_bucket_install: バケットの追加、削除
  • scoop_install: ツールのインストール、アンインストール

バケットの追加、削除

scoop は任意のGitHubリポジトリなどをバケットにできます。scoop bucket add xxxx ScoopPlaybook も scoop_bucket_install でバケットの追加、削除をサポートしています。

例えば extras バケットを追加する場合、次のように書けます。

- name: "Install extras bucket"
  scoop_bucket_install:
    state: present
    bucket: extras

extras バケットは特別扱いされていますが、自分の GitHub URL を指定したい場合は次のようになります。

- name: "Install guitarrapc bucket"
  scoop_bucket_install:
    state: present
    bucket: guitarrapc
    source: https://github.com/guitarrapc/scoop-bucket.git

もしも追加したバケットを消したいならstate に absent を指定します。 (source は省略できます)

- name: "Uninstall guitarrapc bucket"
  scoop_bucket_install:
    state: absent
    bucket: guitarrapc

それぞれのキーは、scoop bucket コマンドに合わせてあります。

  • state: present か absent を指定
  • bucket: 対象のバケット名を指定
  • source: GitHub などのバケットURLを指定

ツールのインストール、アンインストール

scoop はバケットからツールのインストール、アンインストールができます。scoop install xxxx ScoopPlaybook も scoop_install でツールのインストール、アンインストールをサポートしています。

- name: "Install main tools"
  scoop_install:
    state: present
    bucket: main
    name:
      - gow

先ほど追加した gow をアンインストールするなら次のように書けます。

- name: "Uninstall main tools"
  scoop_install:
    state: absent
    bucket: main
    name:
      - gow

それぞれのキーは、scoop install コマンドに合わせてあります。

  • state: present か absent を指定
  • bucket: 対象のバケット名を指定
  • name: ツールを配列で指定

すでにインストールされているツールに更新がある場合は、Scoop-Playbook 実行時に更新してくれます。便利。

管理者権限で実行したい

scoop はユーザー権限が基本でーとか言いますが、ツールによってはFiddler のように管理者権限がないとインストールできないものもあります。 そんなときは sudo コマンドです。

sudo コマンドをインストールしておいて(scoop install sudo 相当)

- name: "Install main tools"
  scoop_install:
    state: present
    bucket: main
    name:
      - sudo

Scoop-Playbook を sudo つきで実行すればok です。

sudo Scoop-Playbook

まとめ

一人で使ってて満足していたんですが、WinGet が出てきて未来はどうなるかと楽しみにしています。 ただ、WinGet はこのままいくとこういう YAML 定義に関しては手を出さず、誰かが何か作るのでしょう。

アンインストールやUAC考慮がない、今のWinGet 触る気はありませんが、WinGetを触る将来が来たらこういうツール書くかもしれません。 ただ、その時はたぶん PowerShell では書かない気がするかもしれない。