カテゴリー別アーカイブ: Linux

Windows10でSage(SageMath)を使う (Bash on Ubuntu on Windows編)

いろいろと試していた結果やっと環境が固まってうまく動くようになったのでその記録として記事を書いてみたいと思います。以降の自分もいろいろな用途でSageを使うことになると思いますし、それ以外の人でこれを使って何かする人(後で解説)もかなり有用だと思います。

 

Sage(SageMath)とは

公式サイトを読んで見るなりWikipediaを調べるなりすればよいと思いますが数学の幅広い処理を扱うソフトウェアで計算機代数などを使用することができます。今現在の主な用途としては数値計算や計算機代数など計算機を使う数学において研究目的で使用されます。この場合ですと数学系の課題研究で担当の教授から紹介されたり代数学の論文でこのような計算方法で行います、という場合にSageのコマンドで紹介されていることがあり以降自分の研究を進めていく上で必要となることが多いようです。

もう一つ面白い使い方としては線形代数や数式処理も行うことができるため高校レベルまでのちょっと複雑な数式について数学の先生が答えから逆算して問題を作成したり、テスト問題を考えたときに解答が正しいかどうかをチェックしたり…という用途に使用できるのではないかと考えています。逆に考えると高校生が横着して数学の宿題についてSageで出した解答をそのまま持って行く、なんてことも考えそうな気もしています。高校生が使うのであれば途中式を書いて計算はしてみたけれど答えを提出する前に確認したい、という用途では使ってよいのでは?と考えていますがどうなのでしょうね。

なお、現在の正式な名称はSageMathと呼ぶようです。インストールするパッケージもsagemathという名前で書かれているようですので気をつけていきましょう。

 

Bash on Ubuntu on Windowsの環境を整備する

Windows10において2016年8月に公開されたAnniversary Updateですが、これの大きな更新の一つとしてBashをWindows環境で利用できるようになった、というものがあります。BashはLinux環境における代表的なシェル(この場合はOSとユーザーをつなぐ役割ととればよい)で、これのおかげで一部のLinuxのプログラムを余計な変換なしにWindows上で扱うことができるようになりました。昔からLinuxとWindowsを併用してきたユーザーから見ればかなりうれしい更新です。今回はこれを使うことにします。

Bash on Ubuntu on Windowsの環境を整備するのはいろいろなサイトで紹介されているので詳しい点はそちらに譲るとして簡単に説明すると作業は以下になります。

  1. 画面左下にあるWindowsのロゴを右クリックしてメニューより[コントロールパネル]を選択。[プログラム]=>[Windowsの機能の有効化または無効化]より[Windows Subsystem for Linux (Beta)]にチェックをして有効化する。(更新により再起動が必要になることもあり)
  2. 設定の[更新とセキュリティ]から[開発者向け]を選択してアプリの受け入れに関して[開発者モード]を選択する。
  3. 画面左下にあるWindowsのロゴを右クリックしてメニューより[コマンドプロンプト]を選択。プロンプト上で
     > bash 

    (先頭の>はプロンプト状態を表すもので実際には入力しない)と入力する。以下開発者のみの機能であることに同意した後Bash上のユーザー名、パスワードを入力して環境構築が行われる。

インストールにはしばらく時間がかかりますのでのんびり待ちましょう。環境の構築が完了するとスタートメニューにBash on Ubuntu on Windowsのショートカットが作成され、そのショートカットで起動すると上記のユーザーでログインした環境から処理が始まる、という状態になります。

ちなみにBash on Ubuntu on WindowsのインストールによってBash上で動くプログラムをgccなどのコンパイラによって作成することもできるのでC言語での簡単なプログラムも作ることができます。こういう目的で環境を構築するのもありかもしれません。

ただし、Bash on Ubuntu on Windowsの環境はWindows本体とは異なり自動では更新されません。そのため環境を構築していろいろなことをやるのであれば定期的にアップデートを確認して環境を更新していく必要が出てきます。環境の更新はインターネットへの接続が確保できている状態で

 $ sudo apt-get update 

というコマンド($はターミナル状態を示すもので実際には入力しない)で行います。また、この環境内ではマシン名の名前解決ということでsudoを使う場合などで変な警告を表示されることがあるので/etc/hostsに自分のマシン名(起動直後の表示では[(ユーザー名)@(マシン名):~$]となっているのでそれを目安に)をviなどで先頭行の127.0.0.1の後ろに書き加えてしまいましょう。

以降はBash on Ubuntu on Windowsを起動した場合はその窓のターミナルはUbuntuのコマンドラインだと思って作業することがある程度可能です。すべてのソフトウェアがあるわけではないのでapt-getで取得できないものはコンパイルがうまくできればなんとかなるかも、というレベルです。そのあたりは自己責任で。

 

XmingでGUIウィンドウが使えるようにする

SageMath本体には直接影響はしないのですがこれが使えるとグラフなどを見せるときに非常に楽になります。特にSageのコマンドライン上から描画命令を発行したときにXmingが正常に動いていればxdg-openコマンドを経由して(内部の関連付けにもよりますが)ImageMagickが呼び出されて最終的にXmingにより画面上にウィンドウが表示されます。これがないとSageからの画像表示を行いたい場合に一度ファイルへ出力した後それをWindows領域から見やすい場所にコピーして画像ビューワを使う、という手順となりかなり面倒になります。ちなみにこれを入れておけばgnuplotも表示できるのでその意味でも数学の授業で扱うことを考えたり…ということもあります。

 

インストールの手順としてはBash on Ubuntu on Windows + XmingによるGUI – Qiitaが詳しいのでそちらを見てもらえばよいですが、簡単に手順を書くと

  1. 公式サイトよりXming-6-9-0-31-setup.exeとXming-fonts-7-7-0-10-setup.exe(記事を書いている時点)をダウンロードしインストール
  2. Xmingを起動する。以下一度シャットダウン処理やXmingを終了させてしまった場合は表示させる処理の前にXmingを起動させること。
  3. 環境変数DISPLAYにXmingのサーバー値を設定する。通常は0.0なので
     $ export DISPLAY=localhost:0.0 

    というコマンドを実行する。必要であれば.bashrcの終端にこの命令を記述しておくと状態が登録されるので楽になる。なお、.bashrcに登録されている場合はウィンドウを開いた後でXmingを起動させてもうまく表示されることがある。サーバー値が間違っていれば失敗するのでそこには注意すること。

となります。ちなみに参考にしたページではxeyesを使ったチェックをやっていますがこちらの場合はこの後SageMathをインストールしてチェックするのでそのタイミングでやってもよいと思います。(うまく表示されない場合の切り分けのために先にテストしてもよい)また、LXDEとVNCを併用してGUI環境を作り出す方法もありますが今回そこまでする必要はないと思いますのでこういう方法を使っていきます。

 

SageMathをインストール

SageMathの場合は本体がPythonで記述されているため今回の場合はほとんどの機能をインストールすることができます。ただ、Ubuntuの公式サイトからパッケージを取得する方法ですとうまくいかない場合があるのでリポジトリから作業を行います。こちらは以下のコマンドを実行することでインストールすることができます。

$ sudo apt-add-repository ppa:aims/sagemath
$ sudo apt-get update
$ sudo apt-get install sagemath-upstream-binary

注意点としては容量がかなり大きい(5GB前後ある)のでWindowsの本体ドライブにそれだけの空き容量が必要であること、またかなりのサイズのデータをダウンロードするため時間がかかることです。数時間くらいかかることもありますので気長に待ちましょう。

 

SageMathの初期環境を構築する

インストールが完了すればSageMathを起動させて初期環境を構築します。といっても一度目の起動の場合は勝手に環境を構築してくれるのでそれを待つだけです。つまり、

$ sage

と入力すればOKです。なお、完全なLinux上で動作している訳ではないためSageMathを起動させるたびにRuntimeWarningが出てしまいますがそれは無視しても問題ないと思います。

 

SageMathの画像表示チェック

最後に画像が表示されるかどうかを確認して完了です。適当にグラフをplotしてみればよいわけですが、わかりやすくcircle命令を使います。例えば

 sage> circle((0,0),1)

としてグラフとして中心(0,0)、半径1の円が描かれたグラフが表示されるかどうかを確認します。デフォルトであればおそらくImageMagickが起動してXming経由で画像ファイルを表示します。コマンド実行後しばらくたっても画像が表示されないときはターミナル(SageおよびBash)をいったん終了させて再度起動させてみてください。それでもうまくいかないときはWindows本体を再起動させてXmingを起動させた上でSageMathを起動させて確認してみてください。ここまでやってうまくいかないときはXmingの表示テストにより単体で動作することを確認する必要があると思います。もしかするとeogをインストールしておく必要があるかもしれませんが…。

 

SageMathで数学Ⅰや数学Ⅱにありそうな問題を解いてみる

ここからは遊びです。例えば代数学の問題(数と式など)をやってみます。

Q1. を因数分解せよ。

A1. SageMathで以下のように入力して答えを得る。

sage> a,b,c=var('a b c')
sage> y=a*(b^2+c^2)+b*(c^2+a^2)+c*(a^2+b^2)+2*a*b*c
sage> factor(y)
(a + b)*(a + c)*(b + c)

よって解答は(ちょっと並び替えを行うと)

Q2. を計算せよ。

A2. SageMathで以下のように入力して答えを得る。

sage> y=sqrt(3)/(sqrt(3)-sqrt(2))-sqrt(3)/(sqrt(3)+sqrt(2))
sage> y.simplify_full()
2*sqrt(3)*sqrt(2)

よって解答は(根号の数を整理して)

Q3. 方程式を解け。

A3. SageMathで以下のように入力して答えを得る。

sage> y=x^4+x^3+2^x-4
sage> solve(y,x)
[x == 1, x == -2, x == -I*sqrt(2), x == I*sqrt(2)]

よって解答は(iを虚数単位として)

見事に途中式を無視して解答だけ出してしまったパターンとなってしまいました。これで数学の宿題として先生に提出したらほぼ確実にやり直しですね…。なお、記事を書いているときに書いている当の本人が本当にこんなことができるのだ、と妙な感動を起こして笑ってしまったのはおいておきましょう。

上記では問題を解く方向でやりましたが問題を構築するとき(例えば因数で表された状態の式を展開して問題にする)もexpandなどでかなりうまくできます。なお、根号の状態など一部の処理は(A2のように)必ずしも簡単になるとは限りませんので解答が出た後で整理するなどが必要だったりそもそもその式をうまく表現できない場合がありますのでそこまで期待しない方がよいでしょう。もちろん研究にSageMathを使う場合は普通に必要な処理を使っていってください。

 

blog(WordPress)の高速化を行ってみた php-fpm編

というわけでまたもやblog(WordPress)の高速化に挑んでみます。前回はWordPressの内部の設定でできる限りの高速化を行う、ということをやってみました。前回の場合だとWordPressを運営しているほとんどのサイトで取り入れることができる方法ですのである意味一般向けになっています。そして今回はWordPressをVPSなど自分でサーバーのソフトウェア環境を変更することができる場合だとどのようにすれば高速化ができるか?ということに着目してやってみました。

 

PHPの実行速度を向上させるには?

当たり前ですがWordPressはPHPを使って動いています。そのため、PHPの実行速度を向上させることができれば応答速度を上げることができ、すなわちPageSpeed Insightsなどで高得点をとることができるようになり、最終的にはユーザー数向上につながります。問題なのはどうやればPHPの速度を向上させることができるのか、です。たとえばPHP5系を使っている場合ですとPHP7系は速度が向上しているらしいので有効である可能性があります。この方法の問題点はPHP7が導入可能な環境なのか(サーバーやパッケージ管理の問題)およびWordPressでPHP7に対応していないプラグインを使用していないかどうか(WordPress本体は4.4でPHP7に対応したらしいですが周りはそうとは限らない)を考える必要があることです。もう一つはPHPの実行に関してPHP側のキャッシュ処理を有効にする方法があります。この方法は意外と汎用的なのですが…。

 

mod_suphpの処理のためにキャッシュ処理が利用できなかったのでphp-fpmに変更した

phpを実行するときのユーザー環境をmod_suphpによって処理していたためphpの実行は「一つのphpファイルにつきphpを起動させて終了させる」というシーケンスとなり、通常キャッシュを使うために必要となる「何回もphpのファイルを実行させる」ができなかった、という問題点がありました。で、今回これを解決するためにphpをFastCGIとして実行できるようにするためサーバー型で実行するphp-fpmを導入して実行ユーザーをphp-fpm側で管理できるようにする、という方式をとることにしました。が、これを使うための設定で難儀したためphpが実行されない状態になるといった状態が途中でできてしまいました…。そのあたりも説明していきたいと思います。

 

php-fpmおよびphpキャッシュ処理モジュールを導入する

実はPHPの「Fatal error: Can’t use function return value in write context」に要注意という記事を書きましたがこれの対応のためにPHPのバージョンを5.4系から5.5系へと変更しています。そのため、キャッシュ処理のパッケージも微妙に異なることに注意しながらやってみます。CentOS6系の場合、PHP5.5などCentOS6標準のPHPより上位のバージョンをパッケージインストールする方法として別のリポジトリを使う方法が有効です。今回はその中でもRemiを使った場合で行います。php-fpmのほかに実行キャッシュ処理などのためにphp-opcacheおよびphp-apcuを導入します。もちろん先にRemiが有効になっていることが条件ですが…。

 

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

# yum install php-fpm php-opcache php-apcu --disablerepo=base,updates --enablerepo=remi-php55

面倒なのはRemiが提供しているPHPはPHP5.4系、PHP5.5系、PHP5.6系、PHP7系と複数あるのでどのリポジトリを参照するのか指定しなければならないこと、CentOS標準のリポジトリを無効にした状態でパッケージをインストールしなければならないことですね。

 

php-fpmの設定

今回重要なことはPHPを外部で実行できることと同時にPHPを実行するディレクトリで異なるユーザーを設定できることがあります。つまりmod_suphpの役割を設定から担えることがあります。というわけでそれに準拠した設定をするとこうなります。/etc/php-fpm.confはデフォルトでも問題ありませんが/etc/php-fpm.d/以下の設定ファイルに細工が必要です。設定ファイルは各ユーザーごとに設定ファイルを用意して記述する必要があるわけです。たとえばユーザーとしてhtmluserで動作させたい場合はこうします。

[htmluser]
listen = /var/run/php-fpm/htmluser.sock
listen.owner = apache
listen.group = apache
listen.mode = 0600
user = htmluser
group = htmluser
pm = dynamic
pm.max_children = 8
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 12
pm.max_requests = 10000
request_terminate_timeout = 600
request_slowlog_timeout = 100
slowlog = /var/log/php-fpm/htmluser-slow.log 
php_admin_value[error_log] = /var/log/php-fpm/htmluser-error.log
php_admin_flag[log_errors] = on
php_value[session.save_handler] = files
php_value[session.save_path]    = /var/lib/php/session
php_value[soap.wsdl_cache_dir]  = /var/lib/php/wsdlcache

同一サーバー上で動作させる場合はsocketで受け渡した方がよいと思われます。別サーバーに分離する場合はlistenの記述を通常のサーバーの待ち受けにすればOKです。

また、listenに設定するlisten.ownerやlisten.groupはPHPを実行するサーバープロセスの実行者がわかっている場合はそれを設定することでlisten.modeを0600と最小限の設定にすることができます。これがわからなかったり別の実行者からもアクセスできるようにするのであればlisten.ownerおよびlisten.groupにnobodyを設定してlisten.modeを0666としておくのがよいと思います。

次に実行ユーザーの設定はuserおよびgroupで行います。対象のsokcetに接続した場合はここで設定したユーザーで実行することになります。これを利用して実行者を分離することが可能になります。ただし、設定ファイル1つにつき1つのユーザーが対応するのでユーザー数だけこのファイルを(セクション名やユーザー名を変更して)増やしていく必要があるわけですね。

残りはphp-fpmのサーバー動作に関する設定です。pm系はphpを同時に処理できる数などを設定します。基本的にはPHPを実行するサーバープロセスの設定に従ってして置けばOKです。その他PHPの実行設定もある程度はここで行えます。

最後にphp-fpmはdaemonとして動作するので起動処理および起動設定を行います。CentOS6系だとこうなります。

# service php-fpm start
# chkconfig php-fpm on

CentOS7系などsystemctlを使う場合はそちらの処理に置き換わります。また、php-fpmはサーバー動作なので設定ファイルを変更した場合はそれをphp-fpmに通知する必要がありますので注意してください。面倒なら再起動すればOKでしょう。

 

php-opcache、php-apcuの設定

次にキャッシュに関する処理です。php-opcacheはPHP5.5系からPHPの実行キャッシュ処理を担当しています。設定ファイルは/etc/php.d/opcache.iniになります。

zend_extension=opcache.so
opcache.enable=1
opcache.enable_cli=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=4000
opcache.revalidate_freq=60
opcache.fast_shutdown=1

注意としてはenable_cliは1に設定することが重要です。これがないとphp-fpm経由で実行したときにキャッシュされない、ということになりますので。

php-apucも設定してしまいましょう。こちらはPHPのデータキャッシュを担当しています。設定ファイルは/etc/php.d/apcu.iniになります。

apc.enabled=1
apc.enable_cli=1
apc.shm_size=64M
apc.ttl=86400
apc.gc_tll=86400

こちらでもenable_cliは1に設定します。また、shm_sizeはキャッシュサイズですのでサーバーのメモリ容量と相談して設定します。

 

Apacheでphp-fpmを使えるようにする

今回難航したのがこの手順です。nginxからphp-fpmを使う手順はいろいろなところにあるのですがApacheから使う手順があまりないこと、またApacheの2.2系と2.4系で使用方法がかなり異なるので苦労しました。今回はCentOS6系だと標準がApache2.2系ですのでそちらに準拠して説明します。Apache2.4系だといくつか変更が必要になりますので注意してください。

 

mod_fastcgiを導入する

php-fpmを使うためにはCGIを実行するモジュールが必要になります。php-fpmの場合はmod_fastcgiを使うとよいと思います。ただし、標準のリポジトリからだとインストールできないのでrpmforgeを使えるようになっていることが条件です。その場合のインストールは

# yum install mod_fastcgi

でOKです。

 

mod_fastcgiを設定する

実は今回一番苦労したのがこの設定です。すべての設定を正しく行ったはずなのにPHPがうまく実行されない場合はこの部分の設定が誤っていることがほとんどだと思います。

まずPHPをFastCGI経由で実行することになるのでモジュールとして連結している設定を解除します。いままでPHPの設定は/etc/conf.d/php.confおよび/etc/conf.d/suphp.confが担当していたのでこれらのファイルを読み込まないように設定します。単純に拡張子を変えてしまえば読み込まれなくなりますので

# mv /etc/httpd/conf.d/php.conf /etc/httpd/conf.d/php.conf.bak
# mv /etc/httpd/conf.d/suphp.conf /etc/httpd/conf.d/suphp.conf.bak

とすればOKです。また設定が終わったらmod_suphpは削除しても問題ないと思います。

次にFastCGIの設定をします。設定ファイルは/etc/httpd/conf.d/fastcgi.confになります。肝となる設定は以下のようになります。

FastCgiWrapper Off
DirectoryIndex index.php
AddType application/x-httpd-php .php
Alias /php-htmluser /var/www/fcgi-bin/php-htmluser
Action php-fpm-htmluser /php-htmluser
FastCGIExternalServer /var/www/fcgi-bin/php-htmluser -socket /var/run/php-fpm/htmluser.sock

ここで間違いやすいポイントを挙げると

  • FastCGIWrapperは基本Offにする。
  • FastCGIExternalServerで設定する呼び出し用仮想実行ファイルは存在する必要はないがその上のディレクトリ(この場合は/var/www/fcgi-bin/)までは実際に存在する必要がある
  • ActionだけではなくAliasも設定しておくこと
  • 複数ユーザーに対応する場合SetHandler(AddHandler)はここでは設定しない
  • 複数のユーザーが存在する場合はその数だけAlias、Action、FastCGIExternalServerを設定する(htmluserの部分を変更する)

があります。実は今回の更新で画面を真っ白にしてしまった理由がFastCGIWrapperをデフォルトの設定であるOnのままにしたためでした。いろいろと調べて判明しましたがまさかこれが原因だとはわかりませんでしたよ…、ということです。あとFastCGIExternalServerで設定したファイルは実際には作成されません。あくまでApache内部でアクセス処理を行ったときに実行ファイルとして内部的に見えるようになっているためです。そのためファイルが作成されていない、と慌てないでくださいね。

ちなみにApache2.4系以降だとDirectoryディテクティブから/var/www/fcgi-bin/にgrant allを設定しないと実行できないようです。アクセス権限が厳密になっているようですね。

 

Directoryの設定を変更する

FastCGIでの実行はCGIの実行権限がディレクトリに必要になります。ファイルを実行可能にする必要はありませんが…。例として/var/www/以下をhtmluser権限でPHPを実行できるようにします。

<Directory "/var/www/">
    Options ExecCGI
    <FilesMatch ".+\.php$">
        SetHandler php-fpm-htmluser
    </FileMatch>
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

注意点としては

  • OptionsにExecCGIが必要になる(これがよく忘れる)
  • SetHandlerを拡張子phpに設定する。このときhtmluser権限で実行することをActionの設定から持ってくる

があります。これを使って各ディレクトリの設定でSetHandlerとActionの定義よりユーザー名を指定して実行する、ということが可能になるわけです。

 

Apacheに設定変更を通知する

変更した設定が正しいかどうか確認してから再読込を行いましょう。

# service httpd configtest
# service httpd reload

 

で、速度は向上したの?

これで向上しなかったら悲しいですよね…。速度測定はPageSpeed InsightsよりWPtouchを使っているモバイルのサイトを対象にしたところ2.8秒から0.6秒まで向上させることに成功しました。ポイントも70点を上回る結果となりまあ改善した甲斐はあったかな、というところです。これ以上の向上を考えるとPHPのバージョンアップやVPSの乗り換えとかそんな話になりそうですね。

 

HTTP/2に完全対応してみた nginx編

もしかしてPageSpeed Insightsの成績が上がるかな~ということも期待してHTTP/2に完全対応してみました。実はこのサイト、とある理由のためにブラウザによってはHTTP/2で通信されないことがあったですよね。

 

CentOS6系でnginxをパッケージインストールするとHTTP/2を使わないブラウザもある

何を隠そうGoogleChromeがそれです。というのも、GoogleChromeがHTTP/2を使って通信をするための条件としてALPNに対応している必要があるのですが、このALPNはOpenSSL1.0.2系以上が必要で、CentOS6系のパッケージではOpenSSL1.0.1系が使われる関係で対応していない状態となってしまいHTTP/2による通信ができない、という結論が得られます。ちなみに先にテストでチェックしておけばよかったのですが気がついたときには更新が完了して新しいnginxで動き始めていたのでもうどうしようもありません。もしチェックし直すのであればわざと古いバージョンに戻した上で、とやる必要があるのでまだ更新していない人は自分の環境をチェックしてみるといいと思います。

 

nginxを最新版にしてALPNに対応しているOpenSSLを連結することで使えるようにする

今回の作業はこれになります。それほど難しい方法ではないと思いますので簡略にやり方を書いていきます。

 

OpenSSL1.0.2系をインストールする

まずはOpenSSLとして1.0.2系以上をインストールします。今回は素直にOpenSSL1.0.2jをインストールしてみます。OpenSSL1.1.0系でもいいような気はしますが、実は前からこれに備えてバージョンを上げていたのでこちらにしたことにさせてください…。

OpenSSLはconfigureの処理として専用のスクリプトがあるのでそちらを使って設定します。あまりコンパイルオプションはほとんどないので元々インストールされているopenssl 対してコンパイルオプションを照会して同じように設定すればよいと思います。今回は/usr/local/src以下にopenssl1.0.2jで展開したとして書いてみます。照会を行った後でopenssldirをそろえるようにconfigを設定してコンパイルします。

# openssl version -a
# ./config shared zlib --openssldir=/etc/pki/tls
# make
# make install

もしかするといくつかライブラリが不足しているかもしれません(zlib-develとかperlとか)のでその場合はyumでインストールしてください。ちなみにこの作業で書き換えた場合はパッケージ側のバージョンは元のままですので後でCentOSの標準パッケージが更新されたときにそのまま更新してしまうと上の更新情報が上書きされてしまいますので覚えておく必要があります。

 

最新版のnginxをインストールする

そして最新版のnginxをインストールします。コードを/usr/local/srcにダウンロードした後は展開してコンパイルとインストールを行えばOKです。以前にnginxをパッケージ経由でインストールした場合はnginxのコンパイルオプションを引き継ぐように設定して最後にopensslのソースコードディレクトリを指定することでCentOS側が標準で持っているライブラリではなく先ほど上の作業でコンパイルできたOpenSSLを使うことができます。この記事を書いている段階ではnginxの最新は1.11.7なのでそれをダウンロード、オプション照会、コンパイルの手順をそれぞれ書くと

# wget "https://nginx.org/download/nginx-1.11.7.tar.gz"
# tar -xzf nginx-1.11.7.tar.gz
# cd nginx-1.11.7
# nginx -V
# ./configure --prefix=/etc/nginx … --with-openssl=../openssl-1.0.2j/
# make
# make install

nginxのコンパイルオプションは省略していますが実際にはかなりずらずらと書かれています。今回はそれをすべてコピーしてコンパイルしました。環境によってはpcre-develが必要だったりしますのでその場合はyumで入れておきましょう。またこちらもnginxのパッケージが更新されると上書きされてしまうので要注意です。あとはnginxの再起動を行えばOKです。

 

フロントエンド側がHTTP/2に対応することで効果を発揮できるのか?

今回の更新でChromeでもHTTP/2でアクセスを行っていることは確認できましたし、バージョンも最新になったのでセキュリティ的にも少しよくなったかな、と考えています。ただnginx単体の環境であればこれで十分な力を発揮できるのですが今回nginxはフロントエンドでありバックエンドとしてApacheが動作しているので意味があるのか微妙に疑問だったりします。キャッシュにヒットした状態が続けば十分に意味はありそうですがキャッシュを用いないページでは結局バックエンド側にアクセスがかかるのであまり改善にならない、という可能性が大きいような気もします。比較実験が必要かもしれませんね。

ちなみに期待していたPageSpeed Insightsに結果が反映されたのか?については…ご想像にお任せします。まあ上に書いてあることでどうなったのかわかると思いますが…。

 

Fedora25をインストールしてみた

2016/11/22にFedora25が公開された、ということでFedora23が入っていたサーバーに新規インストールで入れ直してみました。基本的にはFedora系ということでインストールの手順やパッケージの使い方には変化はなかったのですが…。

 

Server版の場合DVDからインストールするときDovecotを含まないようにパッケージ選択するように

なんと一カ所やらかしてくれました。パーティションもFedora23の時とほぼ同様にしてServer版なので先に一部のパッケージをインストールしておけば楽だろう…と思ったのですが、そういうわけにもいかなかったようです。Dovecotを含むようにインストールを行うとパッケージマネージャであるdnfがエラーを起こしてインストールが停止するという事態が発生してえらいことになりました。びっくりでした。いったい何が引っかかっていたのか気にはなりますが…。

そのため、Server版かつDVDからのインストールの時は追加のパッケージをDVDからインストールせずにネットワークからのdnfのインストールでやることを前提にほぼ素の状態のServer版をインストールしました。一応エディタだけは追加で入れておきましたが、メール系のサービスがインストールされないように設定すれば通ったのかな。まあ、逆に必要なパッケージを別に入れる必要があるためサーバー構築の手順を相手に説明するなどということにはわかりやすくなっているところがいい、ととらえておきましょうか。

 

それ以外はFedora系のインストールと言うことで

普通にインストールして終わりです。一応パーティション関係で書いておくと/bootは先頭パーティションに別で確保してしかもext4にしないと起動できないようなので注意。以降はLVMで確保して適当に分けるなりbtrfsで確保して適当に分けるなりすればいいと思います。これのおかげで(2.2TB以下のストレージであれば)MBRで設定されていても複数パーティションを簡単に扱うことができます。この頃は楽になりましたね~としみじみ。ちなみに昔はパーティションを分けるときは/と/usrと/varで分けていたのですが/がほぼ使われないので領域がもったいない、という結論になり/usrを/に統合してパーティションを設定しています。/varはデータやログ領域なのでテストサーバーといえども分けておいた方がログインできなくて困る、という事態をふせぐことができます。

残りはまあそんなもんかな、ということで詰まることなくいけます。今回は設定すべきIPアドレスを間違えてしまいNetworkManagerをコンソールから操作するのに四苦八苦してみたり、素の状態であったために必要なパッケージを後入れすることとなり、テストサーバーと言うこともあってsslhがなぜか先頭でSamba、Perl、Apache、PHPと一つずつ設定をやっていきました。PHPのバージョンが7.0系になっているのでテストで使う場合にはかなり注意が必要、ということも覚えておく必要があります。今のところRDBMSを使うようなサービスを入れたりシステムを構築していないのでこちらは後回しです。メールサーバー系も構築していません。インストールが終わり安定した状態になったのにdnf経由でDovecotをインストールしようとして失敗する、なんてことがあったそれはそれでいやなので…。

また、今回はSELinuxを有効にしたままインストール作業を行いましたのでSambaの設定時に一部のフラグを解除しないと動かないということも気をつけて行いました。このあたり、blogに書いておくと検索で設定項目が見つかるので簡単でいいですね~と。

 

Telnetも内部ネットワーク用ならまだまだ使える?

普通ならば考慮に値しないのですが内部の簡易ネットワークで使う+SSHでのログインが面倒(鍵指定など)という場合にはTelnetを(Firewalldなどで)内部ネットワークのみ許可して使う、というのもありです。SSHのログインでパスワードログインを認めないように設定するとセキュリティが向上するのですがパスワードログインの方が簡単だったりなじみがあったりするので内部で使う場合はだいたいこっちになりますね。

Fedora系で使用する場合はdnfでtelnet-serverをインストールした後、systemctlからtelnet.socketを有効にする(startとenable)ことと、Firewalldからtelnetの通信をローカルネットワークのみで許可するように設定すればOKです。その辺はセキュリティがないよりましのレベルでしかありませんが。またsystemctlから有効にするのがtelnet-serverではなくtelnet.socketになることも注意です。

 

これにてインストールは一段落

設定ファイルについてはFedora23が動作しているうちに/etc以下をバックアップしておいたので必要であればそちらから設定を参照する、ということでクリーンインストールによって設定がわからなくなる、という現象を回避しています。ちゃんとデータファイル群もサーバー更新前にバックアップしているので準備に抜かりはなかったですしね。このあたりはもうなれたものです。みなさんもきをつけてあたらしいFedoraを体験してみましょう。

 

sslhを使ってsshをPort443から使えるようにしてみる

特に自宅にサーバーを立てているときに外部回線経由でSSHアクセスしたいのだけれども…というときはたまにあります。ただ、その回線によっては特定のポートへの通信しか許可しない、といった設定となっている環境も多いようで、格安SIM経由の通信でもそういうことが起こりうるようです。そうなると何らかの理由で自宅サーバーの環境を変更したい、といったことや自宅サーバー経由で内部にあるメインマシンにリモートデスクトップでアクセスしてごにょごにょ、なんていうことも生まれてくるでしょう。そういうときに効果を発揮する対策です。

先に書いておきますとこのsslhを使った方法は自宅サーバーなどプライベートなサーバーに設定するにはかなり有用なのですがある問題点のためにHTTPSでWebページを公開しているようなサーバーには設定すべきではないと考えています。その点については後ほど。(なのでこのblogがあるWebサーバーのwww.timbreofprogram.infoには設定されていません)

 

sslhとは

適当に検索していると出てきたとあるプログラムです。基本的には軽量のプロキシサーバーと考えればOKです。ただし、対応している通信の種類として暗号通信系が入っているので今回の用途には最適ということが特徴となっています。プロキシとして使うことができる通信が(私がインストールした環境で有効になっているものとして

  • ssh
  • openvpn
  • tinc
  • xmpp
  • http
  • ssl
  • tls
  • adb
  • anyprot

となっていました。今回はこの中のsshとsslが対象になります。使い方によってはそのほか(openvpnなど)も設定するといろいろと使えるかもしれません。

 

sslhのインストール

パッケージが用意されているようなLinuxのディストリビューション(今回試したのはFedora系)であればパッケージのインストール作業でOKです。私の場合はインストール作業

$ sudo dnf install sslh

だけでした。パッケージがない場合はソースコードをダウンロードしてコンパイルします。基本的には単一のプログラム(設定ファイルを作るor起動時にオプションとして与える)だけですのでコンパイル後は/usr/local/以下にプログラムを置くように設定すればOKです。パッケージからインストールした場合は大体設定ファイルが別の場所におかれます。Fedora系では/etc/sysconfig/sslhに起動時のオプションを設定するファイル(単に設定ファイルを参照するように書かれている)があり、/etc/sslh.cfgに実際の設定ファイルが置かれます。

 

sslhの設定

まずはsslhの設定から。sslh.cfgを編集して自サーバーに来たPort443への通信を受け付けられるようにしてsslが来た場合はlocalhostのPort443へ、sshが来た場合はlocalhostのPort22へ流すようにします。設定ファイルはこんな感じ。中にあるIPは自サーバーのIPもしくは自サーバー内でDNS処理を行ったとき自サーバーのIPとなるような名前を設定します。例では192.168.0.2としておきます。

listen:
(
    { host: "192.168.0.2"; port: "443"; }
);

protocols:
(
     { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; },
     { name: "ssl"; host: "localhost"; port: "443"; log_level: 0; }
);

設定ファイルの場合は括弧の種類やカンマ、セミコロンを間違えるとSyntax Errorで起動できません。

また、パッケージインストールの場合は丁寧なファイルがついてくるので編集は簡単ですがプログラムを直接起動する場合は引数として与える必要があります。その場合のコマンドラインは

--user sslh --listen 192.168.0.2:443 --ssh localhost:22 --ssl localhost:443

のようになります。これを設定してdaemonを起動…だけでは無理ですよ。

 

httpd(Apache)からhttps側のlistenをlocalhostのみに変更

たいていの場合Port443は自宅サーバーとして起動している場合だとApacheがListenしているはずです。その場合はApacheのListenを変更しないとsslhがPort443をListenできなくなってしまいますので注意です。設定変更はApacheのsslを設定している場所(Fedora系の場合は/etc/httpd/conf.d/ssl.conf)に対して

#
# When we also provide SSL we have to listen to the
# the HTTPS port in addition.
#
#Listen 443 https
Listen localhost:443 https

とした上で再起動をします。これをしておかないとlocalhost以外のListenがされたままになるのでsslhがPort443をListenできない、ということになってしまいます。またsslhからApacheにhttpsの接続を流すこともできなくなるので注意です。もちろん、ApacheのListenするポートを443から別のポートに変えてsslhから接続するポートの設定を変える、というのもありかもしれません。プライベートサーバーならそういったことも考えてみるとよいかもしれません。

 

sslhをsystemctlから起動

Fedora系でパッケージインストールした場合は

$ sudo systemctl start sslh

で起動できます。サービスとしてサーバー起動時に自動起動させるときは

$ sudo systemctl enable sslh

も実行しておきましょう。また、サービスがちゃんと起動できたかどうかステータスの確認をしておきましょう。失敗しているときは設定ファイルやPort443で競合していないかどうかを調べるとよいと思います。

 

各サービスへの接続チェック

Port443に外部から接続してそれぞれに接続できているかをチェックします。これは設定したサーバー内だとうまくいきませんので注意しましょう。sshはTeraTermなどから、sslはブラウザでアクセスしてみればわかりますね。

 

sshとssl(https)以外にもいろいろと設定してみると使えるかも

見た感じでは使えそうなのはopenvpnですね。vpn接続を行うことができればサーバーのイントラネットへアクセスできるのでスマートフォンからでもいろいろとできることはあると思います。まあ同等の機能としてsshのポート転送を組み合わせてなんとかするのありだとおもいます。Androidのアプリでもポート転送を行うことができるものはありますのでそれを使うとssh単体以外にもリモートデスクトップでWindowsを操作する、といった活用も考えられると思います。

ちなみにこれを設定した後で直接sshのポートに接続できないとある外部のネットワークからssh接続をかけてみるとなんとうまくいきました。格安SIMでもVPN接続を行わずに接続できた(というより格安SIM経由だと接続ができなかったことが今回のテストで初めてわかった、ということでもあります)のでこのシステムはかなり有用そうだな~というところです。

 

接続ログがちょっと微妙

少し問題なのがこのsslhが基本的にはproxyである、ということです。つまり接続先の各サービス(この場合はsshとhttpd)には接続ログとして「自ローカルIPからアクセスがあった」というログだけが残ってしまい、元々どのIPからアクセスがあったか(サーバーに何らかの攻撃があったか)という情報がつかみづらくなる、ということになるからです。設定ファイルのオプションを見る限りhttpsに関してはなんとかなる可能性はありそうですがssh側はそうはいかないようです。これがプライベートなサーバー以外で設定をしない方がよい、という理由となります。

 

プライベートサーバーに設定しておくと外出時などで使える

まあ、これが結論ですね。Port443はhttpsのポートなのでプライベートサーバーであればダミーを用意しておいてそれを公開する「ふり」をしておいてもう一方でsshを有効にしておけば自宅にデータを忘れてきた、というときやメインマシンで何かやる指示を外部から出せるというのはありがたいと思います。