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 でも適宜読み替えて設定すれば機能するとは思います。

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編)

【お知らせっぽいもの】大破.netについて

このブログではOpenWrt / LEDE-Projectファームのダウンロード先が大体自宅鯖の 大破.net になっていますが、現在IPv6でしかアクセスできません

2017/01/31 追記:なんとかIPv4でもアクセスできるようにはなりました。ただし、ISP (BIGLOBE) 側回線が非常に低速かつ不安定なため、接続が不安定です。

なんでそんなことになっているかというと、回線速度の遅さに耐えかねてBIGLOBE(を含めた数社)が提供するIPv6 (IPoE)接続提供サービス “v6プラス” を申し込んだところ、30分程度で切り替わってしまったうえ、IPv4によるサーバ公開ができない状態になってしまったためです。

詳細な流れは以下の通り。

  • 去年11月辺りから速度が極端に下がり(日中下り160Mbps程度あったのが20Mbps前後に)、夜間は10Mbps未満に
  • 耐えかねて父にISPの変更を相談するも、ISP(BIGLOBE)のメールアドレスを広く使用していたため難色を示される(SMTP / POP3等でのメール送受信不可になる)
  • ISPを変えずに改善できないか探る
  • “v6プラス” を見つける
  • “v6プラス” ではMAP-EによりIPv4アドレスが複数の加入者線で共用となるためサーバ公開不可となるものの、別途ルータ使用で従来のPPPoEも可という情報を得て申し込み
  • 当日30分程度で切り替わってしまう ←!?
  • 回線速度が一日通して下り150Mbps~180Mbps程度(無線)で安定する(ONU (PR-S300HI)との有線接続では300Mbps以上)
  • 従来のIPv4 PPPoE接続を試すも、トンネルは確立されるがインターネット側への通信が一切通らず ←???

各方面の方々のアドバイスで、ONUからサーバまでの間に無線を介しているためPPPoEが繋がらない、ということが判明しました。現在試行錯誤してIPv4 PPPoEを接続できるようにしています…

大体こんな感じ。
参考にしたサイトではPPPoEセッションを張ることでサーバの公開を継続しているものの、当方ではまったく通信できずお手上げ状態。∩( ・ω・)∩ ばんじゃーい
そんなわけで、当方のサーバは現状IPv4を諦めてIPv6でのアクセスのみとなっています。

IPv6移行期とはいえ、世の中の家庭のネットワークは大体がIPv4な現在。やっぱりIPv4のアクセスも受け付けたいところですが、未だに仕事も見つからず貯金することもできないのでどうすることもできません。

Jenkins with IIS (URL Rewrite)

かなりの今更感ですが、書いておかないとたぶん(というか絶対)忘れるので、備忘録として書いておくことに。

2017/04/19追記: 備忘録として書いたはずが、既に1個完全に忘れてました。Application Request Routing (ARR)も必要です。

IISとJenkinsを連動させる、というか特定のURL以下をJenkinsに飛ばすやり方です。

環境とか

  • WebサーバOS: Windows Server 2012
    クライアントからのアクセスを最初に受けるWebサーバ。Hyper-V内で動作し、長らく “大破.net” をホストしているこいつを使用しました。
  • Webサーバソフト: Microsoft IIS 8.0
    Windows Server 2012に含まれる、Microsoft製でおなじみInternet Information Serviceのバージョン8.0。既にWindows Server 2016が登場し、IISもバージョンが上がっていっているものの、8.0もまだまだ使えます。
  • Jenkins側OS: Xubuntu 16.04
    Debian系のUbuntuファミリーの一つ、Xubuntuを使用。完全なCUIはまだまだ自分のスキル的に厳しい。
    Jenkins自体はWindowsにも導入できますが、今回はOpenWrt / LEDE-Projectのビルドに使用したかったため、Linux系OSを選択。
  • Jenkins Ver: 2.30
    前述の通り、実際に導入してからだいぶ経っているので導入時のバージョンは忘れかけてますが、たぶんこの辺り。2017年1月7日現在最新の2.39でもできるはずです。
  • URL Rewrite Ver: 2.0
    今回重要となる、IISのURL Rewrite(URL書き換え)。Apacheにおける “mod_rewrite” と同等の機能を提供します。たぶん(筆者自身はApacheまともに触れたことが無い)。
    URLのリダイレクト、書き換え、その他色々。
  • Microsoft Application Request Routing 3.0
    上記のURL Rewriteと連携し、受信したリクエストを指定されたホストへ転送します。こっちも何気に重要です。

Jenkinsをインストール

まず、何も考えずJenkinsをインストールします。手順については詳しく書かれているサイトが沢山あるので、ここでは割愛。
今回はUbuntuファミリーのXubuntuにインストールするので、私は以下を参考にしました。
[Jenkins][Ubuntu] UbuntuにJenkinsをインストール – Qiita

インストールが完了すると、もうローカルの8080ポートでJenkinsが動作しているはず。

Jenkinsを構成

IISへのアクセスをJenkinsに飛ばす下準備です。
まず、Jenkins稼働マシン上で

/etc/default/jenkins

を編集して、ポートやプレフィクスを任意のものに変更しておきます。Windowsでは、Jenkinsのインストール先フォルダにある “jenkins.xml” がその設定ファイルに該当する模様。
今回、設定は以下の通りにしました。

ポート: 8080    #競合するものが無かったのでそのまま
prefix: /jenkins     #なんとなく

ちなみに、URLについてはJenkinsのシステム設定にそれっぽい設定がありますが、これはあくまでビルド通知などに載せるために使用されるだけのURLであって、Jenkinsのシステム自体に関わるものでは無いんだそう。
設定ファイルを編集して保存したら、Jenkinsのサービスを再起動します。

$ service jenkins restart

すると、設定した通りのURLでJenkinsが動作するはずです。今回の場合、

http://localhost:8080/jenkins

になります。

続いて、セキュリティ絡みの設定。Jenkinsでは、不正なアクセスを防ぐため、乱数っぽいものを付加している模様。IISからURL Rewriteを使用してJenkinsに飛ばす場合、これに引っ掛かってしまい、多くのページでCrumbなんちゃらとエラーを吐かれて何もできなくなります。
これを回避するため、Jenkinsの管理ページにある “グローバルセキュリティの設定” で、下のほうの “CSRF対策” 内の “プロキシーとの互換性を有効化” にチェックを入れ、適用、もしくは保存して有効にします。

↓下の画像で赤線の部分

jenkins-crumbs

これでJenkins側の下準備は大体完了。

IISの設定

次はIIS側を設定します。Application Request Routing と URL Rewrite は、予めWebPIを利用してインストールしておきます。
とりあえず、Webサイトを適当に1個作ります。
IIS Manager でサーバーのホーム画面を表示して “Application Request Routing Cache” に入り、さらに右側のペインから “Server Proxy Settings” を選択して入ります。
画面一番上に “Enable Proxy” のチェックボックスがあるので、チェックを入れて右側のペインで適用します。
次に、作成したWebサイトのホーム画面へ移り、 “URL Rewrite” または “URL 書き換え” があるので、そこに入ります。
iis8-taiha-net_url-rewrite

そして右側の “操作” ペインから、”規則の追加…” を開き “空の規則” を選択してOKを押下、規則の編集に入ります。
今回は、

http://taiha.net/jenkins

というURLの “/jenkins” 以下を、Jenkinsが動作しているサーバ(IPアドレス: 192.168.88.254, ポート: 8080 )に飛ばします。

規則の名前は “url-rewrite_to_jenkins” とか適当に付けました。
その他の設定は以下の通り。

  • URLの一致
    • 要求されたURL: パターンに一致する
    • 使用: 正規表現
    • パターン: ^jenkins(.*)$
    • 大文字と小文字を区別しない: 未チェック
  • アクション
    • アクションの種類: 書き換え
    • URLの書き換え: http://192.168.88.254:8080/jenkins{R:1}
    • クエリ文字列の追加: チェック
    • 書き換えられたURLを記録する: 未チェック
    • 後続の規則の処理を停止する: チェック

iis8-taiha-net_url-rewrite_rule

とりあえずはこんな感じ。これで、

http://taiha.net/jenkins

以下がJenkins鯖に飛ばされ、アクセスできるようになりました。

ちなみに、大破.net(taiha.net含む)ではLet’s Encryptの証明書をIISが稼働しているWindows Server上で取得してHTTPSを有効にしていますが、この場合インターネット側とIIS間はHTTPS、IISとJenkins間はHTTPで接続されます。
この状態で上記の様なURL RewriteによってJenkinsに飛ばされるURLにアクセスした場合、大破.netのHTTPS接続が維持されます。

↓例。JenkinsもIIS側の証明書によってHTTPS扱いに。

jenkins-https

また、IISは外部へのポート開放は必要なものの、Jenkins側は完全にIISを経由してのアクセスとなるため、こちらは外部へのポート開放の必要は無さそう(未検証)。

ちなみに、この記事の方法でJenkinsに飛ばした場合、Jenkinsでワークスペース内のファイル横に表示される “参照” リンクは、IISのアプリケーションエラーが表示されてしまい機能しません。教えてえろい詳しい人。

というわけで、何かと忘れる自分のための備忘録でした。

IEでOpenWrtのtrxファイルのMIMEが誤判定される

前回の記事で、WZR-900DHP用OpenWrtファームを独自に修正してビルドし、大破.netにアップロードしたことを報告しました。が、MIMEを登録していなかったせいでダウンロードできない状態になっていました。ごめんなさい。(IISの仕組み上、404が出ていた)

しかし今回は、WebサーバのIISにただMIMEを追加しただけではダメ(ファイルがIE上で直接オープンされてしまう)な場合があることが発覚しました。
結論を先に言ってしまうと、”Visual Studio Test Results Fileを扱えるVisual StudioをインストールしたPCで、IEを使用してOpenWrtファームの .trxファイルをダウンロードした場合” です。

この「Visual Studio Test Results File」は、拡張子がWZR-900DHP等のOpenWrtファームと同じ ”.trx” で、これが原因でIEがMIMEの誤判定を起こしてしまうようです。

管理人のWindows 10のPCで何となくWZR-900DHP用ファームのダウンロードをしてみたところ、よくzipファイルなどをダウンロードするときのようなそのまま開くか、それとも保存するか聞いてくるダイアログやバーが出ず、バイナリファイルがそのままブラウザ上で表示されてしまったことで問題が発覚しました。

WebサーバのWindows Server 2012上のIISでは既にMIMEを ” application/octet-stream ” で追加済みで、同じMIMEの拡張子が ” .bin ” のOpenWrtファームは全く問題なくダウンロードできます。少し検索してみても、MIMEが ” application/octet-stream ” であれば、基本ダウンロードが行われる様子。

そこで調べてみたところ、IEではMIMEを認識する際、単純にファイルの拡張子だけで判定するのではなく、いくつかのステップを踏んで判定されるとのこと。

参考:IEのMIME Sniffing – てきとうなメモ

上記のブログを見てみると、判定のステップでまず当てはまるのが
“2.Content-Typeが既知もしくは曖昧なMIME Typeならば,ファイルの中身を調べて自動判定した結果が最終的なMIME-Typeになる”
というもの。
管理人のPCでは、前述の通りのVisual Studioがインストールされているため、” .trx” は “Visual Studio Test Results FIle” としてレジストリに登録されていて、Content Typeは “application/xml” でXML扱いです。もちろんXMLのMIMEタイプは “text/xml” で既知のMIME Typeであり、これは問題なくIE上でオープンできます。

これを元に、再びIEでOpenWrtの .trxファイルを確認のためダウンロードしようとしてみたところ、やはり “Visual Studio Test Results FIle” として判定されてしまっていました。
openwrt_trx-iis_missing

そこで、上記のブログで別の記事

IE8のMIME処理 – てきとうなメモ

に掲載されているIE8からの変更点
“•X-Content-Type-Optionsヘッダにnosniffを指定すると自動検出しなくなる”
を試してみます。

Internet Information Service Managerを開き、ユーザーにダウンロードさせたいファイルの存在するディレクトリ(サイト全体に適用したい場合は、サイトのホームでも可)のホーム画面で “HTTP 応答ヘッダー” を開きます。
右ペインの “追加…” から “カスタム HTTP 応答ヘッダーの追加” を開き、以下のように記述します。

  • 名前(N):X-Content-Type-Options
  • 値(V):nosniff

その後しばらくすると、OpenWrtの .trxファイルをIEでダウンロードしようとした際に勝手にブラウザ上で開かれず、保存するかどうか聞いてくるようになります。

ちなみに、上記ブログに掲載されている
“•X-Download-Optionsヘッダにnoopenを指定すると勝手にそのファイルを開かず、保存するかどうか問い合せてくる”
をnosniffと同様にIISに追加すると、保存するか聞いてくるバーに “ファイルを開く(O)” ボタンが表示されなくなります。OpenWrtの .trxファイルはバイナリファイルなので、このHTTP応答ヘッダも追加しておくのがいいかも。

それと、この問題はOpenWrt公式サイトのダウンロードページでも発生していました。

以上、大コケしたので備忘録代わりに。