WT1520とdtsとGPIO

最近lede-project/sourceにマージされたPR #1542 に関連して、dtsのGPIO関連について初めて理解できた点が多かったので、備忘録的に。
前置きが長いので、不要な人は 本題 まですっ飛ばしてください。

仕様

何はともあれ、まずWT1520の仕様。

  • SoC: Ralink RT5350 (MIPS32, 1C1T, 384MHz)
  • RAM: 32MB
  • Flash: 4MB
  • WAN/LAN: 100Mbps x1 / 100Mbps x1
  • USB: USB 2.0 Type-A x1

ざっくり言ってしまうと、少し古めの所謂ポケットルータ。

問題

OpenWrtから長らく、リセットボタンがdts(Device Tree Source)で定義されておらず使用できなかった。

対処法

Windows使いのOpenWrt(ビルド編) | もくのすけのスペース
で紹介されている通り、dtsに付け足してビルドする。

その後

上記対処法でビルドした結果、LEDEになりramipsのKernelが4.4から4.9に引き上げられる前後までは正常に機能していた。しかし、どこからか(気づいたのがだいぶ遅かったので、どこからNGになったのか正確には不明)この対処法でビルドした場合リセットボタンは機能するものの、シリアルのコンソールが入力を受け付けない状態になってしまった。
個人的にリセットボタンよりもシリアルコンソールが重要なので、泣く泣くリセットボタンを有効化するためのコミットをrevert。

以上が長いけど前置き。

修正してみる

手持ちのルータは基本シリアルを取るようにしているので、リセットボタンが機能しなくても通常は firstboot コマンドで初期化が可能。しかしながら、WT1520に関しては2台所有しているうち片方はシリアルのケーブルをハンダ付けする際に誤って基板上のパターンを剥がしてしまったために、シリアル通信が不可能になってしまった。そのため、どうしてもリセットボタンを使えるようにする必要があった。

修正内容

何度か試行錯誤を重ねた結果、WT1520のFlash 4MB版と8MB版で共通部を定義する WT1520.dtsi を以下のように修正。

修正前

#include "rt5350.dtsi"

/ {
	compatible = "nexx,wt1520", "ralink,rt5350-soc";

	memory@0 {
		device_type = "memory";
		reg = <0x0 0x2000000>;
	};

	chosen {
		bootargs = "console=ttyS1,57600";
	};
};

&uart {
	pinctrl-names = "default";
	pinctrl-0 = <&uartf_pins>;
	status = "okay";
};

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag";
			ralink,function = "gpio";
		};
	};
};

&ethernet {
	mtd-mac-address = <&factory 0x4>;
};

&wmac {
	ralink,mtd-eeprom = <&factory 0>;
};

&ehci {
	status = "okay";
};

&ohci {
	status = "okay";
};

修正後

ハイライト部分が追加/修正/削除した箇所。

#include "rt5350.dtsi"

#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

/ {
	compatible = "nexx,wt1520", "ralink,rt5350-soc";

	memory@0 {
		device_type = "memory";
		reg = <0x0 0x2000000>;
	};

	chosen {
		bootargs = "console=ttyS1,57600";
	};

	gpio-keys-polled {
		compatible = "gpio-keys-polled";
		#address-cells = <1>;
		#size-cells = <0>;
		poll-interval = <20>;

		reset {
			label = "reset";
			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
	};
};

&uart {
	status = "okay";
};

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag", "uartf";
			ralink,function = "gpio";
		};
	};
};

&ethernet {
	mtd-mac-address = <&factory 0x4>;
};

&wmac {
	ralink,mtd-eeprom = <&factory 0>;
};

&ehci {
	status = "okay";
};

&ohci {
	status = "okay";
};

変更点


#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>

ボタンの定義に関して、GPIOの0/1をLOW/HIGHと記述したり、ボタンの割り当てコードを数字ではなく文字で記述できるようにするためのincludeを追加


	gpio-keys-polled {
		compatible = "gpio-keys-polled";
		#address-cells = <1>;
		#size-cells = <0>;
		poll-interval = <20>;

		reset {
			label = "reset";
			gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
			linux,code = <KEY_RESTART>;
		};
	};

ボタンの定義を追加。”gpio-keys-polled” はボタン(key)の種類で、その後の#address-cellsや#size-cells, poll-intervalは正直不明。その下に、個々のボタンの定義が並ぶ。
resetボタンはGPIOチップ0のGPIO10がLOW、つまり0である場合にACTIVE(押されている状態)。codeは他の機種と同様に “KEY_RESTART” を割当て。


&uart {
	status = "okay";
};

pinctrl-names = “default”; と pinctrl-0 = ; の削除。リセットボタンに関して参考にした前述のサイトを読んだ際、”シリアルコンソールとリセットボタンでGPIOピンを共有している” という盛大な勘違いをしてしまい、この箇所を削ると上手く両立できるようになるのでは?と考えた(間違い)。


&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag", "uartf";
			ralink,function = "gpio";
		};
	};
};

39行目の ralink,group に “uartf” を追加。これも上記同様、シリアルとリセットボタンを両立させるために必要なのでは、と考えた(間違い)。


以上が自分で修正してみた点。かなり色々と思い込みが多く、認識を間違えたままやってしまったものの、これでリセットボタンが機能するようになってしまった

PR

できればUpstreamにも反映できないかな、と考えた結果、この状態でPRを出した。正直ブン殴りたい。
予想していなかったわけではないものの指摘が入ったが、どちらかというと予想外な方向だった。

この指摘とそれに関連する議論については、lede-project/source – PR #1542 を参照。恥ずかしい。詳細は記事では割愛します。

 メンテナのmkresin氏の指摘やアドバイスに従って確認作業をしていくと、どうも元々 WT1520.dtsi 自体に問題があったことが判明。どうやら、基板上に出ているシリアルはGPIO10ではなく別のピンの “UART Lite” に接続されているらしい。
 WT1520の搭載するRT5350にはUART LiteとUART Fullが存在し(これも初めて知った)、UART Liteは送受信各1本のみの信号線を有する文字通りLiteなインターフェースで、UART FullはLiteの信号線以外にも各種制御用などの信号線を有するフル機能版ということになる。
 このうち、UART Liteは既に WT1520.dtsi でincludeしている rt5350.dtsi で有効化(status = “disabled” が無い)されており、WT1520.dtsi でも有効扱いとなっている。これだけでUART Liteは使用可能になっているが、何故か WT1520.dtsi ではUART Fullまで有効化していた。
 このため、ttyS0はUART Fullに、ttyS1はUART Lite割り当てられてしまい、そのままでは(デフォルト設定はconsole=ttyS0のため)シリアルコンソールを接続しても通信ができなくなってしまう。そこで、WT1520.dtsi では chosen {}; ノードにより console をttyS1 に設定されていた。

ざっくりまとめると以下の表のとおり。

本来(18cc8d5 以降)

UART status tty bootargs
Lite
(Console)
Enable
(rt5350.dtsi)
ttyS0 (None)
Full Disable (None)

WT1520(18cc8d5 よりも前)

UART status tty bootargs
Lite
(Console)
Enable
(rt5350.dtsi)
ttyS1 console=ttyS1,57600
Full Enable
(WT1520.dtsi)
ttyS0

上記の通りttyS0が入れ替わってしまい、bootargsを設定してUART LiteであるttyS1を指定し直している。では、UART Fullを有効にして何に使っていたかというと、何もしていない。RT5350のdatasheetを見るとUART Fullのピンの中にリセットボタンが接続されているGPIO10があるが、リセットボタンを機能させるのにUART Fullの有効化は必要ない。
要するに、不要なUART Fullを有効にしてそのためにttyS0が変更され、わざわざUART LiteのttyS1を指定し直すという二度手間ということだった。どうしてこうなってしまったのかは謎。

最終的に “UART Full の有効化は必要ないので消してしまおう” ということになり、具体的な修正方法まで示されたので、それに従ってコミットを修正し、それがLEDE-Project masterブランチへマージされた。(後から気付いたが、lede-17.01ブランチにもbackportされていた。)
WT1520.dtsi の最終的なコードは、lede-project/source を参照。

気づいたこと

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag", "uartf";
			ralink,function = "gpio";
		};
	};
};

は、ピンのグループ(上記だと “jtag” や “uartf”)に対する機能の割り当ての設定ということ。上記ではグループ “jtag” と “uartf” がそれぞれ持っているピンに対して、一括でGPIOとして機能するように割り当てを行っている。この場合、あくまでGPIOとしてのみ動作し、元々のJTAGやUART Fullとして動作することはできなくなる。

もし本来の機能通りに動作させる場合、gpio {}; ノードの中ではなく下記のように設定する。

&uart {
	status = "ok";
}

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag";
			ralink,function = "gpio";
		};
		uartf {
			ralink,group = "uartf";
			ralink,function = "uartf";
		};
	};
};

1 – 3行目でUART(≠ UART Lite)を有効化し、pinctrl内で uartf {}; を設定して “uartf” グループに対して “uartf” 機能の割り当てを行う。
このうち、pinctrl内の uartf {}; は rt5350.dtsi でも定義されており、それを利用して以下の通りに書くことも可能な模様(commit 18cc8d5 よりも前と同じ状態)。

&uart {
	pinctrl-names = "default";
	pinctrl-0 = <&uartf_pins>;
	status = "okay";
};

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag";
			ralink,function = "gpio";
		};
	};
};

&uart {}; ノード内に pinctrl-names と pinctrl-0 を追加。

このピンの割り当て方法については、”rt5350 datasheet” などと検索すると見つかるデータシートに詳しく書かれている。
(1 PIN DESCRIPTION -> 1.3 PIN SHARING SCHEME -> Table 1-5 UARTF Pin Sharing Scheme)
これを見ると、UART Fullの持つ8本のピンのうち、全てをUART Fullとして利用するものから半分で分割するもの、全てGPIOとして利用するものなど複数あり、なるほどと思える。
今回、commit 18cc8d5 の前までは全てのピンがUART Fullとして割り当てられ、commit 18cc8d5 以降は逆に全てGPIOとしての割り当てになった。
ちなみに、GPIOとUART Fullでピンを半々に割り当てる場合、

&pinctrl {
	state_default: pinctrl0 {
		gpio {
			ralink,group = "jtag";
			ralink,function = "gpio";
		};
		uartf_gpio {
			ralink,group = "uartf";
			ralink,function = "gpio uartf";
		};
	};
};

というように、ralink,function に並べて指定する模様。

まとめ

mkresin氏、本当に丁寧に教えて頂いてありがとうございました。

広告

LEDE-ProjectをWN-G300DGRに対応させてみる

発端

  • 2ch(5ch)のOpenWrt/LEDEスレで、 “WN-G300DGRにOpenWrtを入れた人がいる” という情報を見かける
  • 面白そう
  • ざっくり調べてみる
  • 入れた方の記事が見つかる -> IODATA WN-G300DGR OpenWrt 化事前調査 : Royal Windows
  • 構成がかなり似ている機種があるらしく、0からではないのであればなんとかなりそう
  • ざっと見た感じではWN-G300DGR用のプロファイルを用意した上でネットワーク周りと各種LED及びボタン類の調整のみでいけそう
  • 学習に良さそう

注意

  • 前述の通り、0から対応させたのではなく類似機種と先行情報があった
  • 作業内容の理解度は半々程度。

リポジトリ

musashino-build/lede-source

ビルド済みファーム

Jenkinsにプロジェクトを作り、適当なタイミングでビルドしています。
ダウンロードは taiha.net/jenkins からどうぞ。なお、無線関連はFlashの領域確保のためドライバからユーティリティまで全て飛ばしてあります。

写真など

  • 基板全体
    IMG00370
  • 作業時
    シリアルはCN1で、三角からVcc, GND, TX, RX。接続時はケーブル側をNC, GND, RX, TXとして接続。TX, RXはスルーホールを埋めているハンダがすぐ抜けたものの、GNDとVccは手こずり上手くいかなかったため、GNDは別の場所(アンテナ付近)にピンを立てた。

    IMG00377

作業開始

  • プロファイルの用意

    単一のデバイスとしてファームを生成させるため、WN-G300DGR用に必要な各種ファイルを用意/変更する。プロファイルというのは半ば勝手な呼び方。
    新規に追加するファイルは以下の通り。

    • WN-G300DGR.dts
      デバイスの構成情報を格納するファイル (Device Tree Source)。Flash内でのパーティション情報、LED、ボタン類、イーサネットスイッチ等。

    変更するファイルは以下の通り。

    • target/linux/ramips/base-files/etc/board.d/01_leds
      システムステータスを表すために使用されるLEDの指定。
    • target/linux/ramips/base-files/etc/board.d/02_network
      ネットワークのデフォルト構成ファイル。LANとWANにそれぞれ割り当てるポートの指定とMACアドレスの指定を行う。
    • target/linux/ramips/base-files/lib/ramips.sh
      ルータに搭載されるボードの名前などの対比を設定。
    • target/linux/ramips/base-files/lib/upgrade/platform.sh
      sysupgrade時に確認されるデバイス名の設定(たぶん)。
    • target/linux/ramips/image/rt305x.mk
      デバイス毎のファームウェアの生成方法を指定。デバイス毎にデフォルトで含めるパッケージもここで指定。
  • 経過

    • とりあえずWL-351から大体コピー / commit: e4b2709
      WN-G300DGRとWL-351はハードの構成がほぼ同じということで、とりあえずdtsファイルを始めとして変更するファイルもほぼコピーして複製。デバイス名等はWN-G300DGRに変更。01_ledsのみ、搭載されているLEDが不明のためこの時点では変更せず。
      なお、02_network内のスイッチの設定については前述の先行情報のサイトにて別の記事で書かれていたものの、確認漏れでこの時点ではWL-351のまま設定。

      ちなみに、この時点ではまだWN-G300DGRは持ってなかったりする。
      (2017/10/31 14:55)

    • スイッチ構成を修正 / commit: 4a7edf4
      この時点でようやくスイッチの情報が前述のサイトにあることに気付き、02_networkを修正。
      これで3番ポートにデフォルトでWANが割り当てられるようになった(修正前は存在しない4番ポートに割当てになっていた)。
      (2017/10/31 22:50)
    • 定義済みLED, ボタン類の削除 / commit: b2c480e
      OpenWrt Wikiにある通り、GPIOを直接操作してLEDとボタン類のGPIOピン番号を確認するために、一旦dtsファイルにて定義済みのLEDとボタン類を全て削除。
      定義された状態では、特にLEDがGPIOを占有してしまっていて確認ができなかった。
      (2017/10/31 22:53)
    • LEDの定義を追加 / commit: d3c1256
      ここに来てようやくWN-G300DGRを中古で購入し、LEDに割り当てられているGPIOピンを確認。
      前述の通りOpenWrt Wikiにある方法で確認したが、GPIO 7を叩いたタイミングで強制的に再起動が掛かった。理由は不明。1 – 6まで確認後、スクリプトの gpio=$BASE を gpio=8 に書き換えてGPIO 8以降を確認。
      なお、搭載されているLEDのうち “ワイヤレス” LEDについては、RT3052FのGPIOではなく無線部のほうにぶら下がっている形だったため、ここでは追加する必要はなかった。ワイヤレスLEDはLEDEから設定を行うことは可能なものの、GPIOではなく無線部により管理されるため、無線のドライバを削除した場合一緒にこのLEDも使用不可となる。
      (2017/11/10 22:53)
    • ボタン定義の追加 / commit: a2f117b
      LEDに続きボタン類のGPIOピンも確認したため追加。スライドスイッチは少々よくわからず、色々弄ったうえで最終的に 8edbb0a で reset, wps, router の3つのみに。スライドスイッチはAPだけGPIOを取っておらず、残りの “Auto”, “Router” にGPIOの割り当てがあることが判明したため、 3bd022f にて修正。
      (2017/11/11 02:24)
    • メーカー名を変更 / commit: 4bd0e01
      なんとなく、IO-DATAよりもIODATAが適切なのかなぁと思ったため。
      (2017/11/11 02:26)
    • LED設定の追加 / commit: eb57599
      ここで01_ledsにデフォルトのLED設定を追加。初回起動時からフロントの青色LEDが電源LEDとして点灯するようになった。 573dc2c では、青色LEDをdiag LEDとしても設定(起動時などに点滅したりする)。
      (2017/11/11 02:54)
    • USB周りのデフォルトパッケージを追加 / commit: 0751245
      USB Type-A端子を搭載しているため、使用できるように試しにusb-core, dwc2ドライバを追加。
      ただし、これだけでは機能せず、次の 37f54f3 でさらにドライバを追加するも依然ダメだったため、2回目の追加分を 4769500 でrevert。
      (2017/11/11 03:27)
    • マージ / commit: 0f75557
      ここまでWN-G300DGRのサポートを追加するためmasterとは別のブランチで作業していたものの、ある程度形になったためここでmusashino-build/lede-sourceのmasterへmerge。
      (2017/11/11 13:43)

起動ログ(LEDE-Project)

  • 121 – 123行目の “switchへの接続に失敗した” というエラーは、恐らくLEDEが最初にルータ上のスイッチを検出しようとするタイミングではRTL8366RBのドライバが読み込まれていないことに起因するものと思われる。
    少し後138行目でスイッチのドライバが読み込まれ、以降は正常に動作する。
  • 115行目ではUSBポートが “1ポート認識された” とログが吐かれるものの、何らかのデバイスを接続しても反応が無い。
U-boot Ver:1.0.6.20 2011/06/01


Board: Ralink APSoC DRAM:  32 MB  2*16 MB
============================================ 
ASIC 3052_MP2 (Port5<->GigaSW)
Product Name: WN-G300DGR
SDRAM CAS = 3(d1835272) 
============================================ 

Please choose the operation: 
   1: Load system code to SDRAM via TFTP. 
Bad Magic Number,9DA993F9 
Boot from KERNEL 1  !!
[    0.000000] Linux version 4.9.58 (musashino205@Taiha.Net) (gcc version 5.5.0 (LEDE GCC 5.5.0 r0+5730-0c72c27) ) #0 Tue Nov 21 09:34:38 2017
[    0.000000] SoC Type: Ralink RT3052 id:1 rev:3
[    0.000000] bootconsole [early0] enabled
[    0.000000] CPU0 revision is: 0001964c (MIPS 24KEc)
[    0.000000] MIPS: machine is IODATA WN-G300DGR
[    0.000000] Determined physical RAM map:
[    0.000000]  memory: 02000000 @ 00000000 (usable)
[    0.000000] Initrd not found or empty - disabling initrd
[    0.000000] Primary instruction cache 32kB, VIPT, 4-way, linesize 32 bytes.
[    0.000000] Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 32 bytes
[    0.000000] Zone ranges:
[    0.000000]   Normal   [mem 0x0000000000000000-0x0000000001ffffff]
[    0.000000] Movable zone start for each node
[    0.000000] Early memory node ranges
[    0.000000]   node   0: [mem 0x0000000000000000-0x0000000001ffffff]
[    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x0000000001ffffff]
[    0.000000] Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 8128
[    0.000000] Kernel command line: console=ttyS0,57600 rootfstype=squashfs,jffs2
[    0.000000] PID hash table entries: 128 (order: -3, 512 bytes)
[    0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Writing ErrCtl register=00052213
[    0.000000] Readback ErrCtl register=00052213
[    0.000000] Memory: 28092K/32768K available (3033K kernel code, 147K rwdata, 708K rodata, 200K init, 204K bss, 4676K reserved, 0K cma-reserved)
[    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.000000] NR_IRQS:256
[    0.000000] CPU Clock: 384MHz
[    0.000000] clocksource_probe: no matching clocksources found
[    0.000000] clocksource: MIPS: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 9954481493 ns
[    0.000015] sched_clock: 32 bits at 192MHz, resolution 5ns, wraps every 11184811005ns
[    0.015679] Calibrating delay loop... 255.59 BogoMIPS (lpj=1277952)
[    0.100966] pid_max: default: 32768 minimum: 301
[    0.110380] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.123477] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.144928] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.164495] futex hash table entries: 256 (order: -1, 3072 bytes)
[    0.176719] pinctrl core: initialized pinctrl subsystem
[    0.187980] NET: Registered protocol family 16
[    0.230672] rt2880_gpio 10000600.gpio: registering 24 gpios
[    0.241771] rt2880_gpio 10000600.gpio: registering 24 irq handlers
[    0.259473] clocksource: Switched to clocksource MIPS
[    0.271207] NET: Registered protocol family 2
[    0.281139] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    0.295008] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    0.307629] TCP: Hash tables configured (established 1024 bind 1024)
[    0.320429] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    0.332019] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    0.344832] NET: Registered protocol family 1
[    0.357327] rt-timer 10000100.timer: maximum frequency is 3906Hz
[    0.370538] Crashlog allocated RAM at address 0x1f00000
[    0.382957] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[    0.407787] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    0.419363] jffs2: version 2.2 (NAND) (SUMMARY) (LZMA) (RTIME) (CMODE_PRIORITY) (c) 2001-2006 Red Hat, Inc.
[    0.455324] io scheduler noop registered
[    0.463076] io scheduler deadline registered (default)
[    0.474013] Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled
[    0.488177] console [ttyS0] disabled
[    0.495297] 10000c00.uartlite: ttyS0 at MMIO 0x10000c00 (irq = 20, base_baud = 8000000) is a Palmchip BK-3103
[    0.515029] console [ttyS0] enabled
[    0.515029] console [ttyS0] enabled
[    0.528971] bootconsole [early0] disabled
[    0.528971] bootconsole [early0] disabled
[    0.546572] 1f000000.cfi: Found 1 x16 devices at 0x0 in 16-bit bank. Manufacturer ID 0x0000c2 Chip ID 0x0022a7
[    0.566847] Amd/Fujitsu Extended Query Table at 0x0040
[    0.577247]   Amd/Fujitsu Extended Query version 1.1.
[    0.587453] 1f000000.cfi: Swapping erase regions for top-boot CFI table.
[    0.600979] number of CFI chips: 1
[    0.612182] 4 ofpart partitions found on MTD device 1f000000.cfi
[    0.624363] Creating 4 MTD partitions on "1f000000.cfi":
[    0.635105] 0x000000000000-0x000000030000 : "u-boot"
[    0.647542] 0x000000030000-0x000000040000 : "u-boot-env"
[    0.661236] 0x000000040000-0x000000050000 : "factory"
[    0.674318] 0x000000050000-0x000000400000 : "firmware"
[    0.688924] 2 uimage-fw partitions found on MTD device firmware
[    0.700960] 0x000000050000-0x00000018d377 : "kernel"
[    0.713710] 0x00000018d377-0x000000400000 : "rootfs"
[    0.726592] mtd: device 5 (rootfs) set to be root filesystem
[    0.738117] 1 squashfs-split partitions found on MTD device rootfs
[    0.750623] 0x000000330000-0x000000400000 : "rootfs_data"
[    0.765254] libphy: Fixed MDIO Bus: probed
[    0.776833] rt3050-esw 10110000.esw: RGMII mode, not exporting switch device.
[    0.795291] mtk_soc_eth 10100000.ethernet eth0: mediatek frame engine at 0xb0100000, irq 5
[    0.812813] rt2880_wdt 10000120.watchdog: Initialized
[    0.824669] NET: Registered protocol family 10
[    0.838458] NET: Registered protocol family 17
[    0.847628] 8021q: 802.1Q VLAN Support v1.8
[    0.862828] VFS: Mounted root (squashfs filesystem) readonly on device 31:5.
[    0.878558] Freeing unused kernel memory: 200K
[    0.887575] This architecture does not have kernel memory protection.
[    1.633398] init: Console is alive
[    1.640737] init: - watchdog -
[    2.036293] kmodloader: loading kernel modules from /etc/modules-boot.d/*
[    2.197073] usbcore: registered new interface driver usbfs
[    2.208389] usbcore: registered new interface driver hub
[    2.219373] usbcore: registered new device driver usb
[    2.240590] dwc2 101c0000.otg: Configuration mismatch. dr_mode forced to host
[    2.291709] dwc2 101c0000.otg: DWC OTG Controller
[    2.301343] dwc2 101c0000.otg: new USB bus registered, assigned bus number 1
[    2.315635] dwc2 101c0000.otg: irq 26, io mem 0x00000000
[    2.328007] hub 1-0:1.0: USB hub found
[    2.336224] hub 1-0:1.0: 1 port detected
[    2.350726] kmodloader: done loading kernel modules from /etc/modules-boot.d/*
[    2.365381] random: fast init done
[    2.382949] init: - preinit -
[    2.751290] dwc2 101c0000.otg: Overcurrent change detected
[    2.917051] dwc2 101c0000.otg: Overcurrent change detected
Failed to connect to the switch. Use the "list" command to see which switches are available.
Failed to connect to the switch. Use the "list" command to see which switches are available.
Failed to connect to the switch. Use the "list" comm[    3.726453] 8021q: adding VLAN 0 to HW filter on device eth0
and to see which switches are available.
Press the [f] key and hit [enter] to enter failsafe mode
Press the [1], [2], [3] or [4] key and hit [enter] to select the debug level
[    7.251418] jffs2: notice: (313) jffs2_build_xattr_subsystem: complete building xattr subsystem, 0 of xdatum (0 unchecked, 0 orphan) and 0 of xref (0 dead, 0 orphan) found.
[    7.284407] mount_root: switching to jffs2 overlay
[    7.329039] urandom-seed: Seeding with /etc/urandom.seed
[    7.519324] procd: - early -
[    7.525425] procd: - watchdog -
[    8.322087] procd: - watchdog -
[    8.328994] procd: - ubus -
[    8.442323] procd: - init -
Please press Enter to activate this console.
[    8.943197] kmodloader: loading kernel modules from /etc/modules.d/*
[    8.963789] ip6_tables: (C) 2000-2006 Netfilter Core Team
[    8.992741] Realtek RTL8366RB ethernet switch driver version 0.2.4
[    9.005391] rtl8366rb rtl8366rb: using GPIO pins 1 (SDA) and 2 (SCK)
[    9.018436] rtl8366rb rtl8366rb: RTL5937 ver. 3 chip found
[    9.256780] libphy: rtl8366rb: probed
[    9.272512] ip_tables: (C) 2000-2006 Netfilter Core Team
[    9.295480] nf_conntrack version 0.5.0 (1024 buckets, 4096 max)
[    9.383927] xt_time: kernel timezone is -0000
[    9.407083] PPP generic driver version 2.4.2
[    9.420101] NET: Registered protocol family 24
[    9.435053] kmodloader: done loading kernel modules from /etc/modules.d/*
[   17.873556] 8021q: adding VLAN 0 to HW filter on device eth0
[   17.932526] br-lan: port 1(eth0.1) entered blocking state
[   17.943518] br-lan: port 1(eth0.1) entered disabled state
[   17.955128] device eth0.1 entered promiscuous mode
[   17.964874] device eth0 entered promiscuous mode
[   18.102423] br-lan: port 1(eth0.1) entered blocking state
[   18.113384] br-lan: port 1(eth0.1) entered forwarding state
[  127.039574] random: crng init done



BusyBox v1.27.2 () built-in shell (ash)

     _________
    /        /\      _    ___ ___  ___
   /  LE    /  \    | |  | __|   \| __|
  /    DE  /    \   | |__| _|| |) | _|
 /________/  LE  \  |____|___|___/|___|                      lede-project.org
 \        \   DE /
  \    LE  \    /  -----------------------------------------------------------
   \  DE    \  /    Reboot (SNAPSHOT, r0+5730-0c72c27)
    \________\/    -----------------------------------------------------------

=== WARNING! =====================================
There is no root password defined on this device!
Use the "passwd" command to set up a new password
in order to prevent unauthorized SSH logins.
--------------------------------------------------
root@LEDE:/# 

課題

  • USB周り
    色々弄ってみたものの、結局現在も使用不可。必要と思われるドライバは導入してあり、起動時にもportを認識したというようなログは流れるも、何かデバイスを接続しても認識せず。
    ぶっちゃけ手詰まり。

総評

デバイスのサポートの追加は今回が初めてだったものの、WHR-G300NやWZR-900DHPのおかげでdtsやその他のファイルに何度か触れていたため、あれが必要、これが必要ということに思い至れて行き詰まることが少なく、自分でも驚くほどのペースで進められた。
今回でGPIOについてもなんとなく操作の仕方は覚えられたものの、まだまだ細かい使い方が知りたいので、何かできれば、と思う。(Raspberry Piの類がいいのかなぁと)
一つ、前述の通りUSBポートを使用できるようにすることが課題になっているものの、正直これ以上何を弄ればいいのか見当が付かない。にゃーん。

mackerel-agentをOpenWrt/LEDE-Projectのパッケージ化してみる

今月9日と10日に明星大学で開催された、「OpenSourceConference (OSC) 2017 Tokyo/Fall」に参加してきました。

今年は東海道らぐのしまださんから “もしよければLTどうですか?” とお誘いいただいていたので、8日に急いでスライドを作って9日の東海道らぐLT枠で発表させていただきました。
ただ、LTに慣れていないために量が多すぎるスライドを作ってしまい、結果持ち時間の5分を大幅に過ぎてしまいました。反省。
1日目はルータを持っていこうと考えていたものの忘れてしまい、2日目持ってきて東海道らぐブースに展示させていただきました。

さて、そのLTの中で最後のほうに少し触れましたが、OpenWrt/LEDE-Projectにおけるmackerel-agentについてです。
スライド自体でもざっくりしたものだったうえに、時間が無かったためにかなり簡単に流してしまいました。

流れ

MackerelをOpenWrt/LEDEでゴリゴリやるまでのざっくりな流れです。

  • TwitterでOpenWrt/LEDE-ProjectにてMackerelを動かす記事を見かける
  • Mackerelについて調べる
  • 自分でもやってみよう、どうせならOpenWrt/LEDEの .ipkパッケージ化してみよう
  • パッケージ化はできたけど、ルータによって動作したりしなかったり
  • 正常終了時にpoweroffが通知されない

大体こんな感じ。OSCまでにはおおよそ解決したかったものの、上手くいかず若干問題を抱えたまま2日目東海道らぐブースにて展示しました。

Mackerel とは

“株式会社はてな” が提供する、サーバー監視ソリューション。”マカレル”。
Goで書かれたmackerel-agentをサーバ等で動作させ、収集したデータをエージェントが定期的にMackerel.io側に送信する。詳細については公式サイトで。

OpenWrt/LEDE-Projectの .ipk パッケージ

OpenWrt/LEDE-Projectがパッケージ管理として採用する “opkg” のパッケージ形式。今回Twitterで見つけてかなり参考にさせていただいた mackerel-agentをLinux/MIPS32環境で動かしてみた – Qiitaでは単体で直接ビルドしルータ上へもってきているものの、ファームへの組み込みや配布等を考慮するとパッケージ化するほうが良さそう、ということに。
必然的に、OpenWrtやLEDE-ProjectのBuildrootを利用したビルドになる。

ビルド用カスタムフィード

OpenWrt/LEDE-Project パッケージとしてビルドするにあたり、Buildrootに読み込ませるためのカスタムフィード(公式提供外のフィード)を、試行錯誤した末になんとか作成。
mackerel – taiha/taiha-pkgs
OpenWrt/LEDE-Project Buildrootのfeeds.conf.defaultをfeeds.confとしてコピーし、

src-git taiha https://github.com/taiha/taiha-pkgs.git

を追記したうえで “./scripts/feeds update -a” “./scripts/feeds install -a” を走らせると、menuconfig のAdministrationに “mackerel-agent” が現れます。

Endianでコケた(?

エンディアン周りはいまいち正確に理解できていないものの、どうにもGoはMIPS用バイナリのビルドにおいては正しいエンディアンを選択してビルドする必要がある模様(GOARCH=mips or mipsle)。ビルドしたmackerel-agentバイナリがBIG EndianなAtheros AR7242を搭載するRouterBoard 750GLでは動作するものの、LITTLE EndianなMediaTek MT7621では同一のバイナリが動作しないということが起きた。この辺については、雑記ブログのほうに多少まとめてあります。

なお、現状 taiha/taiha-pkgs のmackerel-agentはMIPSルータのみ対応。ARMはMakefileでGOARCHを指定するように記述しているものの、未だテストできていないのでビルドの可否と動作は不明。
2017/10/04 追記: LEDE-ProjectのBuildrootからARCHを取得し、targetのArchitectureに合わせてGOARCH, GOARM/GOMIPSを指定するよう変更しました。これにより、MIPS(LITTLE/BIG Endianness)とARM、x86/x86_64に対応しました。
(注: 検証済み環境 -> WZR-900DHP (ARM, bcm53xx), VR500 (MIPSLE, ramips), RB750GL (MIPSBE, ar71xx))

mackerel-agent終了時の問題

mackerel-agentには、プロセスが正常終了された場合Mackerel.io側にStatusの変更を通知して監視を停止、あるいは監視は続行するが障害の通知は行わないというような設定が可能。
弄り始めた当初この機能が効いてた記憶があるものの、何故か途中から機能せずプロセスを停止する度に障害メールが飛んでくる事態に。
色々弄ってみても解決しないため、mackerel-agentに “start” “stop” コマンドを追加し、プロセスの起動/停止とは関係なくMackerel.ioへの通知を個別で行えるようにし、強引に解決。

ただし、initスクリプトでMackerel.ioへの通知の成功/失敗を取っていないため、現状では場合によりStatus変更通知に失敗してもMackerel.io側がpoweroffのままエージェントが起動する、あるいはworkingのままでもエージェントが停止するということが起こり得ます。

2017/10/04 追記: mackerel-agent.confでの設定ミスが原因だった模様。現在は上記の変更は破棄し、feedでの使用リポジトリは公式リポジトリへ戻しました。現状、ビルド時のLDFLAGSのみfeed付属のpatchで追加しています。

スクリーンショットなど


↑ RouterBoard 750GL で動作させたときの様子。搭載SoCのAtheros AR7242やRAM容量などもしっかり表示された。各種グラフもOK。

課題 / やりたいこと

  • initスクリプトの強化(成功 / 失敗による処理など)
  • mackerel-agent のバイナリ圧縮(現状4.5MBほどあるのでUPX使用して)
  • ARM機種での動作確認 / 対応(手持ちのWZR-900DHP)Done(2017/10/04 追記)
  • (気分とか進捗によって増えるやも)

WHR-G300NとLEDE-Project

少し前に雑記ブログのほうでOpenWrt / LEDE-ProjectにおけるWHR-G300Nに関しての記事(BUFFALO WHR-G300NとOpenWrt/LEDE-Project)を書きましたが、この中で触れたパーティションの問題について、LEDE-Projectではつい最近修正が入りました(OpenWrtは修正されるのか不明)。

ramips: add missing partitions – lede-project/source

The partitions were lost during migration to device tree.

コミットメッセージを読むに、OpenWrt 10.xx backfire 辺りまで各デバイス毎の構成情報がCで記述されていたものを OpenWrt 12.xx Atitude Adjustment 辺りから Device Tree Source (dts) に書き換えるにあたって、パーティション定義が抜け落ちてしまった模様。
BUFFALO WHR-G300N のほかに Upvel UR-336UN も同様に抜け落ちていたものの、そちらも今回のコミットでパーティション定義が追加されました。

lede-project/source からのフォークである musashino-build/lede-source では古いコードから引っ張った情報でWHR-G300N のdtsにパーティション定義の追加を行い、正常動作するようにしていましたが、今回の公式のコミットにより独自に追加したものを使う理由は無くなったので、WHR-G300N.dts を公式のものに差し替えました。

この状態で独自にビルドし、実機上で問題なく起動・動作することも確認できました。

Mastodon with IIS (IIS編)

さて、ひとつ前の記事の続きです。今回は Mastodon の上位にくる IIS 側の設定をしていきます。
既に IIS を使用して Web サイトを複数公開していましたが、2年前くらいに立てたとき色々知識が無い状態で弄ったために肥大化しており、ちょうどいいタイミングだったので一から再構築しました。

注意事項など

大体は前回の記事と同じなので、この記事で追加で注意することなど。

  • Mastodon は Streaming API に WebSocket を使用します。IIS は 8.0 以降(Windows Server 2012 以降)から対応しており、それ以前の IIS では(たぶん)利用できないため、構築できても Streaming 等の機能はエラーで使用できません。
  • 今回使用する OS は、Windows Server 2012 R2 です。恐らく Windows 8.1 / 10 等のクライアント版 Windows でも適宜読み替えて設定すれば機能するとは思います。
  • “Mastodon with IIS” なんて言っているものの、正確にはMastodonへリバースプロキシを行っているnginxのさらに上位にIISを突っ込み、nginxへリバースプロキシさせているだけ。
  • Windows Server 2012 R2以下に搭載されるIISでは、HTTP/2には対応できません。WS2016以降のIISでは可能な模様。

IIS のインストール

今回は OS をインストールした直後のまっさらな状態からスタートなので、まず IIS のインストールから。

IIS 本体

  • サーバー マネージャーを開く
    設定を変えたりしていなければ、OS 起動後ログインすると自動で起動してくる。
  • “役割と機能の追加” を開く
  • サーバーの選択(IIS をインストールするサーバーを選択)
  • サーバーの役割で “Web サーバー (IIS)” にチェックを入れる
  • “機能” は変更無し
  • IIS の詳細な機能の選択
    “Web サーバーの役割 (IIS)” の “役割サービス” で IIS 内の必要機能を追加で選択する。最低限必要なもののほかに、個人的に必要かなーと思ったモノも含めた。
    • Web サーバー / HTTP 共通機能

      HTTP エラー, ディレクトリの参照, 既定のドキュメント, 静的なコンテンツ, HTTP リダイレクト

    • Web サーバー / セキュリティ

      要求フィルター, IP およびドメインの制限, URL 承認

    • Web サーバー / パフォーマンス

      静的なコンテンツの圧縮

    • Web サーバー / 状態と診断

      HTTP ログ, カスタム ログ, トレース, 要求の監視

    • Web サーバー / アプリケーション開発

      WebSocket プロトコル(重要

    • 管理ツール / IIS 管理コンソール

  • インストール開始
  • ウィザードの終了

Application Request Routing と URL Rewrite のインストール

クライアントから受けたリクエストを Mastodon に転送するために必要となる、Application Request Routing (ARR) と URL Rewrite をインストールする。
サーバーマネージャーから一旦 “IE セキュリティ強化の構成” を Administrator グループで無効にして、Microsoft の公式サイトから WebPI (Web Platform Installer) をダウンロードして起動する。

Application Request Routing 3.0 (ARR)

WebPI 右上の検索欄に “arr” と入力して Enter 、いくつか候補が出てくるので、バージョンが最新の “Application Request Routing 3.0” を “追加” する。

URL Rewrite 2.0

同様に検索欄に “url rewrite” と入力して Enter 、一つだけ “URL Rewrite 2.0″ が候補として現れるので、”追加” する。

上記2つを追加したら、”インストール” を実行する。
以上で IIS とその関連のインストールは完了。

IIS の設定

Application Request Routing の有効化

インストールしただけでは無効のままなので、有効化する。

  • Internet Information Service (IIS) Manager(または インターネット インフォメーション サービス (IIS) マネージャー)を起動する
  • サーバー ホーム画面の “Applicatoin Request Routing Cache” に入る
  • 右側のペインから “Serverr Proxy Settings” に入る
  • “Enable proxy” にチェックを入れる
  • その他の設定は変更せず右側のペインから “適用” する

Mastodon 用 Web サイトの作成

Mastodon へリクエストを転送するための Web サイトを作成する。
先に、

C:\inetpub\wwwroot\

以下に “mastodon(名前は任意)” という名前のフォルダーを作成しておく。

IIS マネージャーの画面左側のペインで、”Web サイト” を右クリックし “Web サイトの追加” から作成画面を開く。
“サイト名” には “mastodon” など任意のわかりやすい名前を入力し、”物理パス” には先程作成済みの “mastodon” フォルダーを指定する。
“バインド” には、以下の通り設定した。

  • 種類: http
  • IP アドレス: 未使用の IP アドレスすべて
  • ポート: 80
  • ホスト名: mstdn.taiha.net

ホスト名には、自身がMastodonで使用するドメイン名を入力する。

Mastodon 用 Web サイトの設定

Web サイトを作成したので、Let’s Encrypt での暗号化とHTTPSへのリダイレクト、 Mastodon への転送のための設定を行う。

Let’s Encrypt の対応

先程作成した Web サイトのホーム画面から “MIME の設定” を開き、右側ペインの “追加…” から以下の通りの設定で MIME を追加する。

  • ファイル名の拡張子: .(半角ドット)
  • MIME の種類: text/plain

Let’s Encrypt で証明書を取得する際、アクセスされるファイルを読み取れるようにする。

HTTPSへのリダイレクト

Mastodon はユーザーのメールアドレスとパスワードを扱うため、HTTPS化は必須。
Web サイトのホーム画面から “URL 書き換え” を開き、右側ペイン “規則の追加” → “受信規則” 内の “空の規則” を選択し OK。
下記の通り設定した。

  • 名前: redirect_https(任意)
  • 要求された URL: パターンに一致する
  • 使用: 正規表現
  • パターン: ^(.*)$
  • (条件)論理グループ化: すべて一致
    • 入力: {HTTPS}
    • 種類: パターンに一致する
    • パターン: off

    • 入力: {URL}
    • 種類: パターンに一致しない
    • パターン:
      \.well-known/acme-challenge/(.*)$
      
  • アクションの種類: リダイレクト
  • リダイレクト URL: https://{SERVER_NAME}/{R:1}
  • クエリ文字列の追加: チェック
  • リダイレクトの種類: 永続的 (301)(任意)

設定後、右側ペインで “適用” して “URL 書き換え” ページに戻る。

Mastodon への転送設定

“URL 書き換え” ページで、右側ペイン “規則の追加” → “受信規則” 内の “空の規則” を選択し OK。
下記の通り入力した。

  • 名前: rewrite_mastodon(任意)
  • 要求された URL: パターンに一致する
  • 使用: 正規表現
  • パターン: ^(.*)$
  • (条件)論理グループ化: すべて一致
    • 入力: {URL}
    • 種類: パターンに一致しない
    • パターン:
      \.well-known/acme-challenge/(.*)$
  • アクションの種類: 書き換え
  • URL の書き換え: http://mstdn.taiha.net/{R:0}
  • クエリ文字列の追加: チェック
  • 書き換えられたURLを記録する: 未チェック
  • 後続の規則の処理を停止する: チェック

上記の通り、Let’s Encrypt でのドメイン認証時はこのサーバー内のフォルダにアクセスさせるため、

.well-known/acme-challenge/

以下のURL を Mastodon サーバへ転送しないよう設定した。
また、以前別の記事で Jenkins へ IIS 経由で同様に転送したときは問題なかったものの、今回 Mastodon への転送では、転送先 URL で下記のようにローカル IP アドレスを指定すると問題の出るページがあった。

そのため、今回は Mastodon に利用するドメイン名を指定した。この場合、そのままでは IPv4 ではドメインに登録されているグローバルアドレスに、IPv6 ではこの Web サーバ自体にアクセスが戻ってきてしまうため、

C:\Windows\System32\drivers\etc\hosts

にドメインに対して Mastodon サーバーの IP アドレスを指定する必要がある。以下の通りに指定した。
IPv6 対応環境の場合、同様に Mastodon サーバーのグローバル IPv6 アドレスとドメイン名の組を登録したほうが良いかもしれない。

# MastodonサーバーIP ドメイン名
192.168.11.250  mstdn.taiha.net

以上で、Mastodon サーバーへリクエストを転送する設定が完了。
当方の環境では、最終的なWeb サイトの設定ファイル (web.config) は以下の通り。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <clear />
                <rule name="redirect_https" enabled="true" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{HTTPS}" pattern="off" ignoreCase="false" />
                        <add input="{URL}" pattern="\.well-known/acme-challenge/(.*)$" negate="true" />
                    </conditions>
                    <action type="Redirect" url="https://{SERVER_NAME}/{R:1}" />
                </rule>
                <rule name="mastodon_ubuntu-server" stopProcessing="true">
                    <match url="^(.*)$" ignoreCase="false" negate="false" />
                    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
                        <add input="{URL}" pattern="\.well-known/acme-challenge/(.*)$" ignoreCase="false" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="http://mstdn.taiha.net/{R:0}" />
                </rule>
            </rules>
        </rewrite>
        <staticContent>
            <mimeMap fileExtension="." mimeType="text/plain" />
        </staticContent>
    </system.webServer>
</configuration>

ついでに、IIS に最初からある “Default Web Site” は使用しないので、右クリックのメニューなどから停止させておく。

Let’s Encrypt 証明書取得

Mastodon のサイトの通信を暗号化するため、Let’s Encrypt の証明書を取得する。

Windows 用Let’s Encrypt ツールの導入

github.com/Lone-Coder/letsencrypt-win-simple から、最新のツールをダウンロードして C:\ 以下に展開する。

ツール内の Web_Config.xml 書き換え

この Web_Config.xml で設定される部分は既に IIS で設定済みなのと、そのまま利用した場合エラーが出たので、このファイルが何もしないように書き換えてしまう。
以下の通りに書き換えた。

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
  <system.webServer>
  </system.webServer>
  <system.web>
  </system.web>
</configuration>

Let’s Encrypt で証明書を取得

今回、既に別のサイトも存在するので、それらもまとめてカバーするために単一のサイト用の証明書ではなく、”SAN 証明書” を取得した。
上記で Windows 用 Let’s Encrypt ツールを展開したフォルダに移動し、コマンドプロンプトを管理者権限で起動して下記の通り実行していく。ハイライト箇所が入力した場所。
なんだかものっそい長くなっているのはドメインが多すぎるためで、証明書を取得するドメインが1個だけなら多少短くなる。

C:\letsencrypt-win-simple>letsencrypt.exe --san
The global logger has been configured
Let's Encrypt (Simple Windows ACME Client)
Renewal Period: 60
Certificate Store: WebHosting
ACME Server: https://acme-v01.api.letsencrypt.org/
Config Folder: C:\Users\Administrator\AppData\Roaming\letsencrypt-win-simple\htt
psacme-v01.api.letsencrypt.org
Certificate Folder: C:\Users\Administrator\AppData\Roaming\letsencrypt-win-simpl
e\httpsacme-v01.api.letsencrypt.org
Loading Signer from C:\Users\Administrator\AppData\Roaming\letsencrypt-win-simpl
e\httpsacme-v01.api.letsencrypt.org\Signer
Getting AcmeServerDirectory
Loading Registration from C:\Users\Administrator\AppData\Roaming\letsencrypt-win
-simple\httpsacme-v01.api.letsencrypt.org\Registration
Scanning IIS Sites
 6: SAN - IIS eject.taiha.net (D:\wwwroot\eject.taiha.net)
 3: SAN - IIS mstdn.taiha.net (D:\wwwroot\mstdn.taiha.net)
 5: SAN - IIS sokuten.taiha.net (C:\inetpub\wwwroot)
 2: SAN - IIS taiha.net (D:\wwwroot\taiha.net)
 4: SAN - IIS teo.taiha.net (D:\wwwroot\teo.taiha.net)

 W: Generate a certificate via WebDav and install it manually.
 S: Generate a single San certificate for multiple sites.
 F: Generate a certificate via FTP/ FTPS and install it manually.
 M: Generate a certificate manually.
 A: Get certificates for all hosts
 Q: Quit
Choose from one of the menu options above: S
Running IISSiteServer Plugin
Enter all Site IDs seperated by a comma
 S: for all sites on the server 2,3,4,5,6
Authorizing Identifier taiha.net Using Challenge Type http-01
Writing challenge answer to D:\wwwroot\taiha.net\.well-known/acme-challenge/(ドメイン確認用ファイル)
Writing web.config to add extensionless mime type to D:\wwwroot\taiha.net\.well-
known\acme-challenge\web.config
Answer should now be browsable at http://taiha.net/.well-known/acme-challenge/(ドメイン確認用ファイル)
Submitting answer
Authorization Result: valid
Deleting answer
Additional files exist in D:\wwwroot\taiha.net\.well-known/acme-challenge/ not d
eleting.
Authorizing Identifier mstdn.taiha.net Using Challenge Type http-01
Writing challenge answer to D:\wwwroot\mstdn.taiha.net\.well-known/acme-challeng
e/(ドメイン確認用ファイル)
Writing web.config to add extensionless mime type to D:\wwwroot\mstdn.taiha.net\
.well-known\acme-challenge\web.config
Answer should now be browsable at http://mstdn.taiha.net/.well-known/acme-challe
nge/(ドメイン確認用ファイル)
Submitting answer
Authorization Result: valid
Deleting answer
Additional files exist in D:\wwwroot\mstdn.taiha.net\.well-known/acme-challenge/
 not deleting.
Authorizing Identifier teo.taiha.net Using Challenge Type http-01
Writing challenge answer to D:\wwwroot\teo.taiha.net\.well-known/acme-challenge/
(ドメイン確認用ファイル)
Writing web.config to add extensionless mime type to D:\wwwroot\teo.taiha.net\.w
ell-known\acme-challenge\web.config
Answer should now be browsable at http://teo.taiha.net/.well-known/acme-challeng
e/(ドメイン確認用ファイル)
Submitting answer
Authorization Result: valid
Deleting answer
Additional files exist in D:\wwwroot\teo.taiha.net\.well-known/acme-challenge/ n
ot deleting.
Authorizing Identifier sokuten.taiha.net Using Challenge Type http-01
Writing challenge answer to C:\inetpub\wwwroot\.well-known/acme-challenge/(ドメイン確認用ファイル)
Writing web.config to add extensionless mime type to C:\inetpub\wwwroot\.well-kn
own\acme-challenge\web.config
Answer should now be browsable at http://sokuten.taiha.net/.well-known/acme-chal
lenge/(ドメイン確認用ファイル)
Submitting answer
Authorization Result: valid
Deleting answer
Deleting web.config
Deleting C:\inetpub\wwwroot\.well-known/acme-challenge/
Deleting C:\inetpub\wwwroot\.well-known
Authorizing Identifier eject.taiha.net Using Challenge Type http-01
Writing challenge answer to D:\wwwroot\eject.taiha.net\.well-known/acme-challeng
e/(ドメイン確認用ファイル)
Writing web.config to add extensionless mime type to D:\wwwroot\eject.taiha.net\
.well-known\acme-challenge\web.config
Answer should now be browsable at http://eject.taiha.net/.well-known/acme-challe
nge/(ドメイン確認用ファイル)
Submitting answer
Authorization Result: valid
Deleting answer
Additional files exist in D:\wwwroot\eject.taiha.net\.well-known/acme-challenge/
 not deleting.
Requesting Certificate
Request Status: Created
Saving Certificate to C:\Users\Administrator\AppData\Roaming\letsencrypt-win-sim
ple\httpsacme-v01.api.letsencrypt.org\2,3,4,5,6-crt.der
Saving Issuer Certificate to C:\Users\Administrator\AppData\Roaming\letsencrypt-
win-simple\httpsacme-v01.api.letsencrypt.org\ca-0A0141420000015385736A0B85ECA708
-crt.pem
Saving Certificate to C:\Users\Administrator\AppData\Roaming\letsencrypt-win-sim
ple\httpsacme-v01.api.letsencrypt.org\2,3,4,5,6-all.pfx
Installing Non-Central SSL Certificate in the certificate store
Opened Certificate Store WebHosting
 Set private key exportable
Set private key exportable
Adding Certificate to Store
Closing Certificate Store
Installing Non-Central SSL Certificate in server software
Updating Existing https Binding
IIS will serve the new certificate after the Application Pool Idle Timeout time
has been reached.
Committing binding changes to IIS
Opened Certificate Store WebHosting
Removing Certificate from Store X509Certificate2 {(置き換えられた古い証明書の情報)}
Closing Certificate Store
Updating Existing https Binding
IIS will serve the new certificate after the Application Pool Idle Timeout time
has been reached.
Committing binding changes to IIS
Opened Certificate Store WebHosting
Closing Certificate Store
Updating Existing https Binding
IIS will serve the new certificate after the Application Pool Idle Timeout time
has been reached.
Committing binding changes to IIS
Opened Certificate Store WebHosting
Closing Certificate Store
Updating Existing https Binding
IIS will serve the new certificate after the Application Pool Idle Timeout time
has been reached.
Committing binding changes to IIS
Opened Certificate Store WebHosting
Closing Certificate Store
Updating Existing https Binding
IIS will serve the new certificate after the Application Pool Idle Timeout time
has been reached.
Committing binding changes to IIS
Opened Certificate Store WebHosting
Closing Certificate Store
Adding renewal for IISSiteServer 2,3,4,5,6 ()
Creating Task letsencrypt-win-simple httpsacme-v01.api.letsencrypt.org with Wind
ows Task scheduler at 9am every day.

Do you want to specify the user the task will run as? (y/n)
Renewal Scheduled IISSiteServer 2,3,4,5,6 () Renew After 2017/06/24
Press enter to continue.


C:\letsencrypt-win-simple>

このツールは自動的に IIS に設定されている Web サイトを検出し、リストアップしてくれる。ただし、IDN(日本語ドメインなど)には非対応で、その URL は検出できない。Let’s Encrypt 自体は IDN に対応している。
今回は IIS に設定されている Web サイトの証明書を取得するため 29行目で “S” を、リストアップされている Web サイトすべてが対象なので 32行目でリストの先頭についている番号 “2,3,4,5,6” を指定した。”1″ は IIS に最初から存在していた “Default Web Site” に割り当てられている。
番号を指定して Enter を押すと、自動で確認用ファイルの作成と Let’s Encrypt サーバーからのアクセス確認(ドメインが存在するかどうか)が行われ、さらに IIS の各サイトへ HTTPS の設定と証明書の割り当てまで行ってくれる。

最後142行目で尋ねられているのは、取得した証明書の更新スケジュールをシステムのスケジュールに登録するが、これを別のユーザーとして実行するかどうかの指定。特に変える必要も無いため、”n” を入力して進んだ。するとスケジュールに登録した趣旨の表示の後 “Press enter to continue” と表示され、Enter キーを押すとツールが終了する。
できれば、タスクスケジューラを開き、”タスク スケジューラ ライブラリ” -> “letsencrypt-win-simple …” というタスクが存在するか確認する。これが実行されないと、証明書が更新されず期限が 90日で切れ、Web サイトがエラーでアクセスできなくなる。

以上で IIS の設定と証明書の取得は全て終了。

アクセス確認

正常に IIS へのアクセスが Mastodon へ転送されるか確認する。IPv6 が利用可能な環境ではドメインに IPv6 アドレスを設定していれば直接アクセスできるが、v4 のみの場合はクライアント PC の hosts 内に、ドメインに対して Web サーバ側の IP アドレスを指定する。

また、可能であれば携帯電話やスマートフォン等から docomo や au、softbank 等のモバイル回線を使用して、外部からも正常にアクセスできるかを確認する。
↓ LAN 内の PC から

↓ docomo spmode 回線を利用して L-05E から


以上で全て完了です。
今回のやり方で立てたインスタンス “どんぶり大破” と、その後最新の開発バージョンを追う予定で立てたインスタンス “ておくれ” は、今のところ継続的に運用する予定です。

それでは。