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 から


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

それでは。

Mastodon with IIS (Mastodon編)

というわけでやりました、Mastodon インスタンス構築。”サーバを自分で建てられる” と聞いてやらないわけがない性格なので仕方ないね。
今回はMastodon 本体の構築。と言っても、ほとんど公式ドキュメント (Production guide)に準拠します。

下記手順については、記事執筆時点の公式ドキュメントに従ったものです。公式ドキュメントは頻繁に更新されるため、最新の手順に従ってください。

注意事項など

  • サーバの構築などは学習目的で行っています。間違いや改善すべき点等含んでいる前提でご覧ください。
  • クレジットカードが無い(作るのも現状不可)などの理由で、クラウドの利用はそもそも選択肢にありません。
  • 今回は非Docker環境で構築します。そもそもDocker についての知識が乏しいことなどが理由です。
  • 構築先の環境等の詳細については、構築済みインスタンス “どんぶり大破” の about/more ページに記載しています。

必要パッケージのインストール

Production guide の “General dependencies” “Redis” “Postgres” に従ってインストールしていきます。

General dependencies

Nginx は apt-get install の中にありませんが、OSに入ってないのでここで入れてしまいました。

sudo apt install imagemagick ffmpeg libpq-dev libxml2-dev libxslt1-dev nodejs file git curl nginx
curl -sL https://deb.nodesource.com/setup_4.x | sudo bash -

sudo apt install nodejs

sudo npm install -g yarn

Redis

そのまんまインストール

sudo apt install redis-server redis-tools

Postgres

インストール

sudo apt install postgresql postgresql-contrib

Mastodon 用ユーザーの作成

ユーザーを Postgresql によって作成済みのユーザー “postgres” に切り替えて Postgresql のコンソールへログインし、データベース管理の新規ユーザー “mastodon” を作成する。

sudo su - postgres
psql

# ↓新規ユーザー "mastodon" をデータベース作成権限を与えて作成
CREATE USER mastodon CREATEDB;

# ↓Postgresql のコンソールを終了
\q

その他

上記の “\q” の下に “Under Ubuntu 16.04, …” と書かれているが、Ubuntu 16.04 未満の場合必要な操作なので、Ubuntu Server 16.04 を用いている今回は関係無し。

新規 Linux ユーザーの作成

Mastodon は専用のユーザーアカウントで実行する関係で、新規のユーザー “mastodon” を作成する。参考

sudo adduser mastodon
# パスワード入力後、色々聞かれるが何も入力せず4回ほどEnter。最後 "これで良いか" という問いは "y" と入力しEnter でユーザーの作成を完了する。
gpasswd -a mastodon sudo

ユーザーの作成と sudo 権限の付与が完了後、sudo su – mastodon で作成したアカウントに切り替える。
これ以降の作業は、このアカウントで行う。

Rbenv

Ruby のインストール / 管理を行う rbenv の準備
“Production guide” にある通り、rbenv の公式ドキュメントにある方法でインストールを行う。GCC などが必要になるので、”まあいいや” とか言いつつ apt install build-essential をしてしまった。
rbenv のインストールが完了後、

rbenv install 2.4.1
rbenv global 2.4.1

で Ruby ver.2.4.1 のインストールとグローバルバージョンの設定を行った。
Ruby のインストールの際、必要なパッケージが不足していてビルドがコケたりもした。コンソール上のエラーメッセージ内に不足しているパッケージが表示される(libreadline-devなど)ので、それに従い追加でインストールする。

Mastodon 本体の引き込みと追加インストール

Git を利用してMastodon 本体をサーバー上に引き込み、必要パッケージの追加インストールを行う。

引き込み

git clone で、そのまま引き込む。場所は特に変える理由もなかったので、公式ドキュメントに従った。

cd ~     # /home/mastodon
git clone https://github.com/tootsuite/mastodon.git live     # /home/mastodon/live/ 以下に clone
cd live

# master(開発版)はバグが入り込みやすく不安定なため、安定版のバージョンのコードを引き込む
git checkout $(git tag | tail -n 1)

追加パッケージのインストール

ここで “gem コマンドがインストールされていない” などのエラーが出る場合、Ruby のインストールに失敗している可能性があるので rbenv からやり直し。

gem install bundler
bundle install --deployment --without development test
yarn install --pure-lockfile

Mastodon の設定

Mastodon の全体的な設定を行う。

設定ファイルの作成

既存の .env.production.sample ファイルを .env.production としてコピー。

cp .env.production.sample .env.production

設定

デフォルトの設定からの変更のみ列挙、未変更の箇所は未記載。DBのパスワードは、公式ドキュメントにある通り空欄のままにする。

REDIS_HOST=localhost
DB_HOST=/var/run/postgresql
DB_USER=mastodon
DB_NAME=mastodon_production

# Mastodonで利用するドメイン名
LOCAL_DOMAIN=mstdn.taiha.net

# ~/live/ 以下で rake secret コマンドを1回ずつ実行して、生成された乱数を入れる。なので計3回実行することになる。
PAPERCLIP_SECRET=(乱数)
SECRET_KEY_BASE=(乱数)
OTP_SECRET=(乱数)

# Mastodon サイトアクセス時に、既定で表示に使われる言語
DEFAULT_LOCALE=ja

# アカウントの確認用に送信するE-Mail設定。
# 今回は Mailgunを試したものの無料アカウントの制限が厳しかったため、新規に取得した Gmail のアカウントを利用することにした。
SMTP_SERVER=smtp.gmail.com
SMTP_PORT=587
SMTP_LOGIN=(Gmail アカウントのメールアドレス 例: hogehoge@gmail.com)
SMTP_PASSWORD=(Gmail アカウントのパスワード)

その他

ユーザーのアイコンやヘッダー、アップロードされる画像や動画の保存先も変更したかったので “PAPERCLIP_ROOT_PATH” も設定してみたものの、メディアが保存はされるのにそこから読み出せないというトラブルが発生したため、デフォルトの保存先である “~/live/public/system” に対して、マウントしたドライブからシンボリックリンクを設置した。ドライブの当該フォルダの所有者は “mastodon” ユーザーに変更済み。

cd ~/live/public
mv ./system ./system.bak     # 一旦名前を変える
ln -s /mnt/mstdn_media/system system

Mastodon のセットアップ

データベースとCSSやJavaScriptの準備。

データベースの作成

データベース及びテーブルの作成。

RAILS_ENV=production bundle exec rails db:setup

CSS と JavaScript の precompile

RAILS_ENV=production bundle exec rails assets:precompile

Systemd サービスの作成

Mastodon の各プロセスを、systemd のサービスとして登録する。

  • /etc/systemd/system/mastodon-web.service
  • /etc/systemd/system/mastodon-sidekiq.service
  • /etc/systemd/system/mastodon-streaming.service

上記の3つを、Production guide からそれぞれそのままコピーして設置。
そのうえで、OS起動時の自動開始有効化と手動での開始を行う。

# 3つのサービスの自動開始有効化
sudo systemctl enable /etc/systemd/system/mastodon-*.service

# 手動開始
sudo systemctl start mastodon-web.service mastodon-sidekiq.service mastodon-streaming.service

Nginx の設定

今までに設定した Mastodon にアクセスできるように、Nginx のプロキシ等の設定を行う。
今回 Mastodon インスタンスのサーバー上で一緒に Nginx が動作するが、その上位でさらに別のサーバー上にある IIS を経由してクライアントからのアクセスを行えるようにするため、Producion guide にあるNginx の設定例から以下の部分を変更した。
Let’s Encrypt を利用した暗号化 (HTTPS) は上位の IIS で行うため、関連する設定は全て無効化。
server_name には、Mastodonで使用するドメイン名を設定する。

#server {
#  listen 80;
#  listen [::]:80;
#  server_name example.com;
#  # Useful for Let's Encrypt
#  location /.well-known/acme-challenge/ { allow all; }
#  location / { return 301 https://$host$request_uri; }
#}

server {
#  listen 443 ssl;
#  listen [::]:443 ssl;
  listen 80;
  listen [::]:80;
  server_name mstdn.taiha.net;

#  ssl_protocols TLSv1.2;
#  ssl_ciphers EECDH+AESGCM:EECDH+AES;
#  ssl_ecdh_curve prime256v1;
#  ssl_prefer_server_ciphers on;
#  ssl_session_cache shared:SSL:10m;

#  ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
#  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
#  ssl_dhparam         /etc/ssl/certs/dhparam.pem;

  keepalive_timeout    70;
  sendfile             on;
  client_max_body_size 0;

  root /home/mastodon/live/public;

  gzip on;
  gzip_disable "msie6";
  gzip_vary on;
  gzip_proxied any;
  gzip_comp_level 6;
  gzip_buffers 16 8k;
  gzip_http_version 1.1;
  gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

  add_header Strict-Transport-Security "max-age=31536000";

  location / {
    try_files $uri @proxy;
  }

  location /assets {
    add_header Cache-Control "public, max-age=31536000, immutable";
  }

  location @proxy {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";
    proxy_pass_header Server;

    proxy_pass http://127.0.0.1:3000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  location /api/v1/streaming {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header Proxy "";

    proxy_pass http://localhost:4000;
    proxy_buffering off;
    proxy_redirect off;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection $connection_upgrade;

    tcp_nodelay on;
  }

  error_page 500 501 502 503 504 /500.html;
}

設定を記述し終わったら、/etc/nginx/sites-available/mastodon として保存し、/etc/nginx/sites-enabled/default を削除の上 /etc/nginx/sites-enabled/mastodon としてシンボリックリンクを作成する。

cd /etc/nginx/sites-enabled
sudo ln -s /etc/nginx/sites-available/mastodon mastodon

その後、Nginx サービスを再起動する。

sudo service nginx restart

以上で Mastodon 側の設定は終了。あとは IIS 側の設定に続きますが、疲れたので後で書きます…

2017/04/26追記: 書きました ==> Mastodon with IIS (IIS編)

LuCIの日本語訳について

今更ではあるものの、とりあえずメモというかざっくりまとめ。

LuCIとは

  • ルータ用Linuxディストリビューションである、OpenWrtやその派生のLEDE-Project用WebUI
  • “Lua Configuration Interface” の略の通り、Luaによって記述されている
  • 基本的にLuCIだけでは機能せず、本体アプリケーションと一緒に機能する
    例: luci-app-adblock -> luci-app-adblock (LuCI App) + adblock(本体)
  • LuCIの機能は、ユーザーが新しく追加することができる
  • 様々な言語で利用できる(2017/03/01現在、26言語)
  • 未翻訳の部分は、ユーザーが訳して追加することもできる
    • 少し前から参加

LuCIプロジェクトへの参加

  • 基本GitHub上での参加
    • 機能の追加や修正、翻訳の追加や修正どちらもここ
    • かつては翻訳ポータルを利用していたらしいが、現在はGitHubのみ
  • ガイドラインで全てのコミットに実名と有効なメールアドレスでサインを入れることが定められている
    • “git commit –signoff”、もしくは手書き
    • 例: Signed-off-by: YAMADA Tarou <hogehoge@gmail.com>
    • メールアドレスはGmail等でOK
    • 名前の書き方についてはweblioの解説ページなどを参照
      • 私は基本 “姓 名” の順で姓を全て大文字
    • 実名ではない名前でのコミットをPRした場合、プロジェクトメンバーから “次から実名でコミットするように” と指摘が入る
      • 何度も繰り返すとたぶんPRを蹴られる(やったことは無い)

LuCIの翻訳

  • 現状LuCIプロジェクトに各言語の担当者はいない
  • luci-base、luci-appで一つずつ分離されているpoファイルに対訳を書き込む
  • 既存の訳文と表記をできるだけ揃える
    • 現在作業中
  • poファイルが存在しないluci-appの場合、当該Appのpot(テンプレートファイル)から新規にpoファイルを作成する
    • 作成するpoファイルは、”luci-app-xxx” の “xxx” と同じファイル名にする(違っていると翻訳が適用されない)
  • pot(テンプレートファイル)が存在しないluci-appの場合、buildディレクトリ以下にある “i18n-scan.pl” を使用してテンプレートを他のluci-appと同様の階層に生成する
    $ ./build/i18n-scan.pl applications/luci-app-adblock > applications/luci-app-adblock/po/templates/adblock.pot
    • LuCI翻訳補助ツール等のドキュメント
    • poが存在しない場合と併せ、可能であれば翻訳後にビルドして翻訳が適用されるか確認する
      • “feeds.conf.default” をコピーして “feeds.conf” とし、”luci” の行を
        src-git luci https://github.com/(GitHubユーザー名)/(自フォーク).git;(ブランチ名)

        に置き換える
        例:

        #src-git luci https://git.lede-project.org/project/luci.git
        src-git luci https://github.com/musashino205/luci.git;wg-add-ja
        
  • 翻訳する機能を可能な限り理解してから訳す
    • トンデモ訳や誤操作の原因になる誤訳を防止するため
    • 翻訳するluci-appの本体Appのドキュメントが理解するのに最適
  • 翻訳する文字列がどこに表示されるものか、極力実際のUIで確認する
    • 項目名なのか、項目に対する説明文なのかを区別するため
    • 説明は少々長くても可か否か
    • 稀に翻訳した箇所が適用されないことがある
      • Luaソースの問題など
  • “%s” や “%q” などは訳さず、順番も元の並びから変更しない
    • ユーザーの入力や設定情報、デバイスの情報をもとに文字列や値が入る
    • Luaソースに記述された順番で文字列や値が入るため、翻訳での順番を変えると誤った表示になる

LuCIの日本語訳について

  • 既に大半が翻訳済み
    • 2011 – 2013年頃に存在した部分は、ほぼ全てが当時参加した方が翻訳された模様
  • それ以降追加された箇所は私が少しずつ訳して投げてます
  • 新たにGitHubでの参加は、LuCIプロジェクト側の方々も(たぶん)ウェルカム(なはず)
  • 日本語訳で誤訳や改善、疑問等あれば、直接参加(openwrt/luciへのPullRequestまたはissue)か私のフォークのissuesページ
    • 私のフォークへのissueは日本語でOK
    • 翻訳について多くの方に聞きたいことが度々出てくるため、その相談にも乗っていただければ
      • カタカナ2単語間の区切り(中点かスペースか)、専門用語の一般名など