メニュー 蕭寥亭 検索

自宅サーバ

11. Ubuntu 14.04 へ更新・覚書

 2012年7月にサーバーのOSを Ubuntu 12.04 へ更新し当分使い続けるつもりだったんですが、諸般の事情で2014年5月に早々と Ubuntu 14.04 へ更新しました。

 OSを変更すると毎度いろいろな問題が出てくるものですが、今回も例外ではなく対応に頭をひねらされました。無事、更新は済みましたが、放っておくと何をどうしてこうなったのか忘れて、次の更新の時にまた苦労することになるので、ここにメモしときます。

1.Ruby のバージョン問題

 今回、OSを更新することにした主たる理由は、Ruby のサポート期間にありました。

 Ubuntu 12.04 で採用されている Ruby は 1.8 系と 1.9 系でしたが、 1.8 系はすでに引退扱い となり、 1.9 系も来年2015年2月にサポート終了が予定されている ため、その前に新バージョンに移行する必要がありました。

 Ubuntu 14.04 で採用されている Ruby は 1.9 系と 2.0 系となり、じゃあ Ruby2.0 でいこうというところでしたが、 他のところで何度か書いているとおり、 Ubuntu 14.04 で Ruby2.0 をパッケージからインストールすると、頼みもしないのに Ruby1.9 がいっしょにインストールされて、デフォルトも 1.9 になってしまうという奇怪な設定になっており、 Ubuntu の開発コミュニティのバグ報告にも上がったものの、修正は Ubuntu の次期バージョンに先送りされてしまったようです。 弱りました。

 ではどうするか?

 パッケージを使わず自分で Ruby をコンパイルして管理するのはめんどくさいし、Ubuntu 14.04 の設定をいじってデフォルトを無理矢理 2.0 に変更してしまうという手もあるそうですが、後で問題が起きそうでヤだなと。

 調べていくうちに、Brightbox という英国のクラウド関係のサービスを提供している会社が独自に Ubuntu 向けの Ruby パッケージを提供していることを知りました。Ubuntu 14.04 用には 2.0 系と 2.1 系があったので、渡りに船と Brightbox 版の Ruby2.1 を使うことにしました。この方法でも問題が起こる可能性はありますが、自分でいろいろするより楽ですし。

 Brightbox 版の Ruby パッケージをインストールする方法は簡単で Brightbox のこのページ に書いてありますが、英文なので以下に手順を書いておきます。

 まずはインストールに必要なリポジトリ管理ツールを先にインストール。

$ sudo apt-get install python-software-properties

 Brightbox のリポジトリを追加。

$ sudo apt-add-repository ppa:brightbox/ruby-ng

 パッケージ情報の最新化。

$ sudo apt-get update

 Ruby2.1 をインストール。

$ sudo apt-get install ruby2.1

 Ruby のバージョンを確認して 2.1 になっていれば成功です。

$ ruby -v
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-linux-gnu]

 Phusion Passenger のコンパイルなどで使われる開発ヘッダが必要な場合は、ruby2.1-dev をインストールします。

$ sudo apt-get install ruby2.1-dev

 現在のところ、ウチのサーバーはこの Brightbox 版 Ruby2.1 と 「10. Ruby + Phusion Passenger + Nginx で Sinatra が動く環境を作る」 で解説した方法でインストールした Phusion Passenger + Nginx + Sinatra で問題なく動いています。

2.Phusion Passenger と Nginx をパッケージから導入

  「10. Ruby + Phusion Passenger + Nginx で Sinatra が動く環境を作る」 で Phusion Passenger と Nginx をコンパイル・インストールする方法について書きましたが、正直自分でコンパイルするのはめんどうなので、できればパッケージを使いたいです。

 実は Phusion Passenger の開発元のガイド によりますと、開発元が用意した Phusion Passenger のパッケージがあり、それと Ubuntu が提供している Nginx のパッケージを組み合わせて動かす方法が掲載されています(当然ながらこちらも英文)。

 残念ながら、ウチのサーバー更新の作業までに Ubuntu 14.04 用の Passenger のパッケージ提供がまにあわなかったため、今回の更新では採用を見送りましたが、その後作ったテスト環境では 前記の Brightbox 版 Ruby2.1 と組み合わせて問題なく動いています。次回の更新ではこっちでいこうかな・・・。

 せっかくなので、こちらも以下に手順を書いておきます。

 開発元の PGP キー をインストール。

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 561F9B9CAC40B2F7

 必要なツール類をインストール。

$ sudo apt-get install apt-transport-https ca-certificates

 新たに /etc/apt/sources.list.d/passenger.list というファイルを作成し、Ubuntu のバージョンに合わせてパッケージのダウンロード元を記載します。Ubuntu 14.04 の場合は下記の1行を /etc/apt/sources.list.d/passenger.list に記載します。

deb https://oss-binaries.phusionpassenger.com/apt/passenger trusty main

  /etc/apt/sources.list.d/passenger.list の所有者とパーミッションを変更してパッケージ情報を最新化。

$ sudo chown root: /etc/apt/sources.list.d/passenger.list
$ sudo chmod 600 /etc/apt/sources.list.d/passenger.list
$ sudo apt-get update

 Nginx と Phusion Passenger をパッケージからインストール。

$ sudo apt-get install nginx-extras passenger

 Nginx の設定ファイル /etc/nginx/nginx.conf を修正します。インストール直後は下記のように passenger に関する設定がコメントアウトされています。

# passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
# passenger_ruby /usr/bin/ruby;

 この部分のコメントを解除します。

passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
passenger_ruby /usr/bin/ruby;

 他に必要な設定があれば記載して、Nginx を再起動すれば passenger が使えるようになります。

$ sudo service nginx restart

 うっ、簡単・・・。

3.Ruby と PHP の共存

 うちのサーバーサイド言語は去年 PHP から Ruby に移行しましたが、テスト環境ではたまに「 PHP も使いたいぜ!」ってなことがあります。

 Ruby + Phusion Passenger + Nginx の環境にも php5-fpm という Fast/CGI 用のパッケージを追加すれば共存できます。

 php5-fpm をパッケージからインストール。

$ sudo apt-get install php5-fpm

 で、設定は目的や環境によって変わってくるので一概には言えませんが、極端な話、最低限 /etc/nginx/nginx.conf を下記のようにすると、拡張子 php のリクエストは php5-fpm で処理し、それ以外は Passenger で、とすることができます。

events {

							
}

							
http {
      passenger_root /usr/lib/ruby/vendor_ruby/phusion_passenger/locations.ini;
      passenger_ruby /usr/bin/ruby;
      server {
          listen 80;
          server_name localhost;
          root /var/www/public;
          location / {
              passenger_enabled on;
          }
          location ~* ^/(.*\.php)$ {
              alias /var/www2/php/$1;
              fastcgi_pass unix:/var/run/php5-fpm.sock;
              include fastcgi_params;
          }
      }
}

 Ruby と Passenger と Nginx は前記の通りパッケージからインストールし、php5-fpm については Ubuntu 14.04 での初期設定のままという前提です。

 php のリクエストは alias で設定したディレクトリ /var/www2/php 以下に置かれたファイルが対応することになります。

4.Nginx で不要なヘッダ情報を消去する

 気がつかないところでサーバーの情報が漏れてしまうことがあります。

 例えば前記のように Nginx や Passenger をインストールして、特に対策を取らなかった場合、閲覧者のリクエストに対して送り返されるレスポンスのヘッダは以下のようなものになります。

レスポンスヘッダ・対策なし

  X-Powered-By という項目で Phusion Passenger 4.0.44Server という項目で nginx/1.6.0 + Phusion Passenger 4.0.44 と、このウェブサイトで使われているソフトウェアとバージョンの情報が含まれています。

 このヘッダ情報というもの、普通にブラウザで閲覧している分には見えませんが、Internet Exloprer を使っているなら付属の開発者ツールという機能で、FireFox なら foxmeter というアドオンで簡単に表示させることができます。

 そもそも、こういう情報が外部の不特定多数の閲覧者になぜデフォルトで開示されるようになっているのかはさておき(個人的にもとっても謎ですが)、サイト攻撃のヒントになってしまうようなものは見せないようにしたいもの。

 Nginx に追加可能なモジュールに HttpHeadersMore というものがあり、これを使えばレスポンスヘッダの特定の項目を表示させないようにすることができます。

 Ubuntu 14.04 では Nginx について組み込まれたモジュールが異なるパッケージが複数提供されていますが、HttpHeadersMore が組み込まれているのは nginx-extras だけのようですので、使いたければ nginx-extras を選択することになります。

  「10. Ruby + Phusion Passenger + Nginx で Sinatra が動く環境を作る」 で解説したやり方で Nginx をコンパイルする場合は、コンパイル時の設定で HttpHeadersMore の組込を指定しておかなければなりません。

 その場合は、コンパイルの前に GitHub の HttpHeadersMore のページ からソースコードをダウンロードし、任意のディレクトリに展開しておきます。

 それから passenger-install-nginx-module を実行してコンパイルしていきますが、 "Automatically download and install Nginx?" では、必ず 2 の「カスタマイズする」を選択し、Nginx のコンパイルオプションを指定する Extra arguments to pass to configure script: で HttpHeadersMore を展開したディレクトリを指定します。展開したディレクトリが /download/httpheadersmore なら

Extra arguments to pass to configure script: --add-module=/download/httpheadersmore

と入力します。

 なお、コンパイルオプションは複数指定することができるので、 「10. Ruby + Phusion Passenger + Nginx で Sinatra が動く環境を作る」 の例のように設定ファイルの配置場所を

Extra arguments to pass to configure script: --add-module=/download/httpheadersmore --conf-path='/etc/nginx/nginx.conf'

とスペースで区切って追加することもできます。

 コンパイルが成功すれば HttpHeadersMore の機能が使えるようになります。

 例として、レスポンスヘッダに X-Powered-ByServer を表示させないようにするには、Nginx の設定ファイル nginx.conf で下記のように指定します。

http {
      more_clear_headers 'X-Powered-By';
      more_clear_headers 'Server';
      # 以下略

 それから Nginx を再起動するとレスポンスのヘッダの内容は以下のように変化します。

レスポンスヘッダ・HttpHeadersMore で対策後

  X-Powered-ByServer が表示されなくなっています。

5.内部向け Git サーバーを立ち上げる

 バージョン管理システムとして今までは Subversion を使っていたんですが、「これからは Git だぜ!」という話なので、ミーハー根性丸出しで導入することにしました。自宅サーバー用のシステムを自分一人で作っているだけなのにそもそもバージョン管理なんか必要なのか、という点についてはいずれゆっくり考えるとして・・・。まあ、バージョン管理というよりほとんどバックアップ感覚で使っているのですが。

 そうそう、Git については こちら にかなり詳しい文書がありますんで、ご参考まで。

 さて、 この文書の Git サーバーの項 によりますと、Git サーバーは Local 、SSH 、Git 、HTTP の4つの通信プロトコルが使用可能で、サーバーを構築する前に用途に応じて選択する必要があるということです。

 各プロトコルの長所・短所の解説を読んだ上で、わたしは Git を使うことにしました。Git は高速である代わりに認証ができないということでしたが、家庭内LANでわたしが使うだけなので問題なしと判断しました。

 まず、必要なパッケージをインストール。

$ sudo apt-get install git-core git-daemon-run

 次に Git サーバー用のディレクトリを作ります。ここでは仮にディレクトリを /var/gitrepo とします。

$ sudo mkdir /var/gitrepo

 作ったディレクトリに移動します。

$ cd /var/gitrepo/firstrepo.git

 リポジトリを配置するディレクトリを作ります。このディレクトリは仮に firstrepo.git とします。 サーバー用のベアリポジトリ(作業ディレクトリを持たないリポジトリ)のディレクトリ名の最後は .git とすることが慣例になっているそうで、それに従っています。

$ sudo mkdir firstrepo.git

 作ったディレクトリに移動します。

$ cd firstrepo.git

 リポジトリを作成します。

$ sudo git init --bare --shared

 Git プロトコルを使ってリポジトリを公開する場合、 git-daemon-export-ok というファイル(中は空でよい)が必要とのことなので、作成します。

$ sudo touch git-daemon-export-ok

 Git デーモンがディレクトリを操作できるように、オーナーを変更します。Git デーモンの実行ユーザーは Ubuntu 14.04 では gitdaemon となっているのでは、例えば下記のようにします。

$ sudo chown -R gitdaemon:root /var/gitrepo

 Git デーモンの設定を変更する前に、念のためデーモンを停止。

$ sudo sv stop git-daemon

 Git デーモンの設定 /etc/service/git-daemon/run の Ubuntu 14.04 での初期状態は下記のとおり。

#!/bin/sh
exec 2>&1
'git-daemon starting.'
exec chpst -ugitdaemon \\
  "$(git --exec-path)"/git-daemon --verbose --reuseaddr \
    --base-path=/var/lib /var/lib/git

 これを環境に合わせて修正します。ここでの例の場合、最後の行を

    --enable=receive-pack --export-all --base-path=/var/gitrepo

とします。 --base-path= 以降が Git サーバー用のディレクトリの指定です。

 修正したら、デーモンを起動して

$ sudo sv start git-daemon

クライアントからサーバーに接続できたら成功です。そうそう、サーバーは待受ポートに 9418 を使用するので、必要に応じてファイアウォール等の設定変更を忘れずに。

6.GeoIP の活用( Ruby で)

 相変わらず不審アクセスは毎日多発しており、まともなお客さんより多いくらいなのがムカつきます。

 何かの役に立つこともあるだろうと、不審アクセスの情報はデータベースに記録しているのですが、過去のデータを眺めていた時に記録していたIPアドレスから発信元の国がわからないかなと考えました。

 最初はNICに問い合わせるスクリプトを書こうかと思ったのですが、めんどくさいし(またかい)問い合わせだと一々外部への通信が発生してしまうのもまだるっこしい。もっとお手軽に調べる方法はないかと思っていたところ、GeoIP というデータベースが使えることがわかりました。

 GeoIP はIPアドレスの位置情報データベースで有償版と無償版があり、無償版は Ubuntu 14.04 Server に始めから入ってました( Linux Mint 17 にも入ってました)ので、ありがたく使わせてもらうことにしました。

 当サイトのシステムで使うので Ruby から検索することになります。gem にまんま geoip という GeoIP 検索用ライブラリがあったので、これを使います。まずインストール。

$ sudo gem install geoip"

 使い方の例は下記。

# ライブラリ読込
require 'geoip'

							
# GeoIP 検索オブジェクト生成
obj = GeoIP.new('/usr/share/GeoIP/GeoIP.dat')

							
# 検索
info = obj.country('xxx.xxx.xxx.xxx')

						
# 結果=struct GeoIP::Country request="xxx.xxx.xxx.xxx", ip="xxx.xxx.xxx.xxx", country_code=111, country_code2="JP", country_code3="JPN", country_name="Japan", continent_code="AS"

  GeoIP.new で検索オブジェクトを生成する際には GeoIP のデータベースファイルを文字列で指定します。Ubuntu 14.04 Server・Linux Mint 17 なら /usr/share/GeoIP/GeoIP.dat です。

 検索するには生成したオブジェクトの country メソッドを使い、IPアドレス(例では xxx.xxx.xxx.xxx にしていますが、ここを実在するアドレスに置き換えてください)を指定します。ホスト名でも可。ちなみに Sinatra では request.ip でクライアントのIPアドレスにアクセスできますので、これを指定するといいでしょう。

 結果は例の黄文字部分の形式で返ります。

 割と簡単に使えて便利ですが、欠点はデータベースに抜けがあるらしく、まれに結果が空で返ってくることがあること。無償版なんだから、しゃあないか・・・。

7.Simple Shutdown Software は Ubuntu 14.04 でも使えず

 オムロン製の無停電電源装置(UPS)用のシャットダウンソフトウェア・ Simple Shutdown Software は Ubuntu 14.04 でも使えませんでした・・・。OSも Simple Shutdown Software 自体もバージョンが上がったので、ちょっと期待していたんですが、残念。

  NUT とオムロン・BY50S の組み合わせは以前同様動作しています。