Bash on Ubuntu on WindowsでMojolicious::LiteとかNet::Twitter::Liteを動かす。

Windows 10 Anniversary Update(Windows 10 バージョン 1607)を適用したので、Bash on Ubuntu on Windowsを使ってみました。念には念を入れて、アップグレードツールを使わずにWindows Updateから適用できる段階でアップデートしたのですが、失敗してOSごと起動しなくなったりしました。相変わらずですね。
私の環境の場合、MacTypeとセキュリティソフトとタッチパッドのドライバが原因だったので、セーフモードで無理やり起動させて原因のアプリを停止させた後、ツールからアップデートしたらうまくいきました。
自分のマシンだとWindows Helloは予想通りサポートされなかったので、使いたかった機能がbashだけになりました。
OSビルドは14393.51です。

Tech TIPS:Windows 10のLinux/Ubuntu互換環境でbashを使う – @IT
ここを見ながらbashを使えるようにしてみました。ちなみに、私の環境だと、bashを使うときにコマンドプロンプトのオプションから「従来のコンソールを使う」のチェックボックスを外さないと動きませんでした。
Bash on ubuntu on Windowsが起動できません。 – マイクロソフト コミュニティ

sudoすると、「名前解決が出来ません」と言われてしまうので、/etc/hostsに「127.0.0.1 ホスト名」を追加しておきました。
ちなみにPerlはv5.18.2でした。メイン環境のさくらVPS/CentOS 7環境がv5.16.3なので、ubuntuのほうがバージョン上ですね。
ubuntuのバージョンは以下のとおり。

➜  ~ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

ちなみにoh-my-zsh使ってみたのですが、(やっぱり)文字化けしちゃいました、

ホームディレクトリの実体は以下にありました。

C:\Users\ユーザ名\AppData\Local\lxss\home\ubuntuのユーザ名

cpanでモジュールを導入しようとした

最初はcpanでMojoliciousを入れようとしたのですが、「Warning: the following files are missing in your kit」みたいな感じで全然makeできないので、cpanは使えませんでした。cpanmならいけるかもしれないけどめんどくさいので試してません。

apt-getで導入する

ubuntuだとapt-getでperlのモジュールを導入できるので、sudo apt-getで導入してしまいました。

➜  ~ sudo apt-get install libmojolicious-perl
➜  ~ sudo apt-get install libnet-twitter-lite-perl

無事導入できました。

Mojolicious:Liteを動かしてみる

以下のスクリプトをhypnotoadで実行して、http://localhost:8181にアクセスしてみました。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Mojolicious::Lite;
app->config(
  hypnotoad => {
    listen => ['http://*:8181'],
    },
);

get '/' => sub {
  my $self = shift;
  return $self->render(json =>{test => "hello world"});
} => 'index';
app->start;

bashから動かすMojoLite

bashから動かすMojoLite


わーい動いた。

Net::Twitter::Liteを動かしてみる

以下のスクリプトを動かしてみました。

#!/usr/bin/perl

use strict;
use warnings;
use utf8;

use Net::Twitter::Lite::WithAPIv1_1;
use Encode;

my $nt = Net::Twitter::Lite::WithAPIv1_1->new(
consumer_key => $consumer_key,
consumer_secret => $consumer_key_secret,
access_token => $access_token,
access_token_secret => $access_token_secret,
ssl => 1
);

my $tl = $nt->user_timeline();

for my $status(@$tl){
    print encode_utf8($status->{text} ."\n");
}

コンソールから実行してみる

コンソールから実行してみる


わーい動いた。

試したけどできなかったこと

mongodb3は導入できませんでした。以下のStackOverflowの記事と同じ症状です。
Windows 10 Linux Subsystem. How to install MongoDB – Stack Overflow

感想

VirtualBoxでやれ。
ちなみにrm -rfしたらどうなるのかなーと思ったら、やっぱり試してる人がいて「あっ…」てなりました。
`rm -rf /` on Bash on Ubuntu on Windows – Qiita

グローバルIPの8080ポートにアクセスするとルータの設定画面が見える。

私の使っているルータは、192.168.0.1(=ルータのアドレス)の80ポートにアクセスすると、ルータの設定画面が見えるタイプです。
IPマスカレードで、80と443ポートはRaspberry Piにアクセスされるようにしています。が、操作を間違って自分のグローバルIPの8080ポートにアクセスしてみたら、なぜかルータの設定画面が出てきて死ぬほどビビりました。8080ポートなんて設定のどこにも出てないんですがこれは。ためしにルータの8080ポートにアクセスしましたがrefuseされるし謎です。

調べてみたら以下のケースがぴったり当てはまりました。
グローバルIPでルータの設定画面が開いてしまう – .自宅サーバを公開している… – Yahoo!知恵袋
グローバルIPアドレスについて – その他(インターネット接続) 締切済 | 教えて!goo

WAN側のIPアドレス(グローバル)にLAN内からアクセスすると
ルータがちゃんとIPマスカレードを行わないで自分自身のそのポートを
返してしまう場合があります。

使っているルータの仕様のページに詳しいことが書いてなかったのでなんともですが、少なくとも発生している事象に関してはこの挙動に当てはまります。

LAN内からWAN側のIPアドレスの8080ポートにアクセスすると、ルータ自身の8080ポートにアクセスすることになるんですね。試しにLAN外の環境からIPアドレス:8080にアクセスすると、想定通りrefuseされました。

ルータの設定アプリはルータ自身の8080ポート(外からアクセス不可)で動いていて、80ポート(外からアクセス可)にアクセスすると設定アプリが見えるということですね。リバースプロキシ処理は自前でやってるんでしょうか。
ためしに22とかそれっぽそうなポートにアクセスしてみましたが、全部動いてないみたいでした。残念です。(何が)

将来8080ポート開けたときはLAN外から動作確認しないといけないですね。困った困った。

自分のサイトをHTTP/2対応にしようとしたらものすごいはまった。

Life with open mind: コミケ90で「Get Started with HTTP/2」を出します(3日目 西4 f-44b)
これを読みまして、「よし、自分のサイトもこのビッグウェーブに乗せよう」と思い、(Raspberry Piで運用してる以外のSSLに対応してる)サイトをHTTP/2対応にしました。

サーバ弄る前にクライアントのWindows 10マシンにRS1適用したらOSごと起動しなくなって死ねって思いました。

薄いご本にはOCSP Staplingの設定や、ssl_ciphersの設定について解説してあったのですが、結構前に「SSL LabsでA+取らなきゃ(使命感)」みたいな時期があって、そこら辺は全部済ませてたので飛ばしました。

環境

OS: CentOS 7
nginx: nginx/1.11.3(yum install)→ nginx/1.11.3 (make install)
openssl: OpenSSL 1.0.1e(yum install) → OpenSSL 1.0.2h(make install)

nginx側の設定

http2に対応しているのが1.10.0以上ですが、yumで入ってるのが1.11.3なので何もしなくていい!余裕ですね。$nginx -Vで確認しても「–with-http_v2_module」がついてるので一安心です。そんなふうに思ってたら30分後に自分でビルドすることになったんですけどね。confのserverディレクティブに以下の設定をすると、http2で通信できるようになります。

listen  443 ssl http2;

あとはnginxを再起動すればOKですね。簡単。

http/2で通信してるか確認してみる

firefoxとedgeとchromeで確認してみました。
firefox以外http/1.1で通信していました。

原因を調べる

Supporting HTTP/2 for Google Chrome Users | NGINX
これでした。Chromeでhttp/2通信させようと思ったら、ALPNに対応させないといけないのですが、openssl 1.0.2以降でないと対応してないようです。薄いご本に「ALPNはopenssl 1.0.2以降じゃないと対応してないよ」って書いてあったけど、こういう理由だったんですね。(ALPNに対応させないといけない理由が本にはなかったので、そこはちょっと残念だったかも。)

必要なものをビルドする

opensslの最新版を展開(ビルド不要)。
# cd /usr/local/src
# wget https://www.openssl.org/source/openssl-1.0.2-latest.tar.gz
# tar -zxf openssl-1.0.2-latest.tar.gz
nginxをビルド。

予め$nginx -Vでconfigureがどうなってるのか調べておくと良いです。

SRPMがあるからそれを使う手もあります。
Index of /packages/mainline/centos/7/SRPMS/
RPMのコンパイルオプションを変更してインストールする方法 | あぱーブログ

今回は自力でmakeしました。コマンド書こうと思ったのですが、綺麗なまでに以下の記事と同じところではまったので、記事のURLを紹介しておきます。
nginxのコンパイルメモ – Qiita
上記Qiitaと違う点として、私の環境のconfigureではnjsのバージョンは0.1.0だったため、tipではなく0.1.0を指定しました。
njs: cdb8d20935ee
configureに以下を追加して使いたいopensslの場所を指定します。

--with-openssl=/usr/local/src/openssl-1.0.2h

無事、make installできました。

結果

SSL Labsの結果

SSL Labsの結果

HTTP/2 Testの結果

HTTP/2 Testの結果

SSL Server Test: retrorocket.biz (Powered by Qualys SSL Labs)
HTTP/2 Test | A simple HTTP/2.0 test tool

いくばくか早くなったと信じています。