2015年12月29日火曜日

building php 5.6 on osx

PHP をビルドした備忘録

ICU

php intl を使うために ICU ライブラリをインストール

cd source
./runConfigureICU MacOSX --prefix=/usr/local/icu
make
sudo make install

PHP 5.6

./configure --prefix=/usr/local/php5.6 --with-pgsql=/usr/local/pgsql --with-openssl=/usr/local/ssl/ --enable-intl --with-icu-dir=/usr/local/icu

しかし、これだと configure が通らない。事前に作った libicu を探せていない。DYLD_LIBRARY_PATH を定義して configure を通す。

export DYLD_LIBRARY_PATH=/usr/local/icu/lib

make も通ったが、

sudo make install
のところで、再び libicu が見つからないエラー

su - 
export DYLD_LIBRARY_PATH=/usr/local/icu/lib
cd php-src-dir
make install
で、仕上げに .bash_profile に DYLD_LIBRARY_PATH を書いてやるという... できた php を otool -l でみると、libicu だけ絶対パス表示されていなかった。

mbstring

mbsting を configure で付け忘れていた。色々ぐぐると、ソースディレクトリが残っていれば、後から構築できる。

cd php-src-dir
cd ext
cd mbstring
phpize
./configure
make
sudo make install
vi /usr/local/php5.6/lib/php.ini
  extension=mbstring.so

pdo_pgsql

さらに pdo_pgsql をビルド ( php5.6 にパスを通してからやる )

cd ext/pdo_pgsql
phpize
./configure
make
sudo make install
vi /usr/local/php/5.6/lib/php.ini

2015年11月24日火曜日

NetBios と nssswitch の設定

自宅内の Linux ホストのネットワーク設定 (NetBios) の備忘録

2 台の Linux ホストは、DHCP から IP を取っているが、IP アドレスが変わることは滅多にないので、各 Linux ホスト+windows 機の hosts ファイルに全て IP アドレスを書いていた。 年に 1, 2回程度の作業だったが、なにか方法があるはずだと思うようになった。

最初に考えたのは、サブネットに片っ端から ping を打って、arp テーブルで MAC アドレスとホストファイルの対応を取り、結果をhosts ファイルに書き込む方法。しかし時間がかかるのと、 Windowsで、例えば ruby のスクリプトを定期的に自動実行するやり方もよくわからない。そもそも Windows 同士では DNS に登録してなくても相互の名前が見えている。なにかブロードキャストを 使う仕組みとかありそう。Windows の Netなんちゃら。それを調べてみた。

Netbiosは同じサブネット内のマシンの名前解決のための仕組みで、UDP/137 でブロードキャストして、返事をしたマシンからホスト名 (netbios名) と IP アドレスを教えてもらうもののようだ。 Linux でその仕組みを使うには Samba 関連のパッケージがインストールされていることが必要。 1 台の linux ホスト (hoge1) では samba を動かしてるので、もう 1 台の linux ホスト(hoge2)も samba 関連のパッケージを入れてみる。smbd と nmbd が起動するが、一旦止める。そして、手始めに hoge2 にて nmblookup というsamba付属のコマンドを使いhoge1 の IP アドレスを調べてみる:

user1@hoge2:~$ nmblookup hoge1
querying hoge1 on xxx.xxx.xxx.255
yyy.yyy.yyy.yyy hoge1<00>

host2 では、 samba 関連のパッケージを入れたが、smbd も nmbd もまだ起動していない。この状態で nmblookup でhoge1 の IP アドレスを知ることができたのだから、 起っていることは、hoge2 からブロードキャストに対して hoge1 が返事をしていると考えて良さそう。試しに hoge1 で hoge2 の IP アドレスを調べようとしても、

user1@hoge1:~$ nmblookup hoge2
querying hoge1 on xxx.xxx.xxx.255
name_query failed to find name hoge2

となる。そもそも samba には smbd と nmbd の 2 種類のデーモンが動いているのは何故かあまり考えなかったが、 smbd はファイルシステムで、 nmbd がNetBiosサービスだったようだ。 hoge1 から hoge2 の IP アドレスを調べることができるためには、hoge2 で nmbd が動いていればよい。nmbd の設定は /etc/samba/smb.conf にする。ネットを見ていると、ここで wins support = yes と書けばよいとあたっが、上記の目的(ブロードキャストに対して IP アドレスを答えさせる)だけなら no のままでよい。もし wins support を yes にすると、 その nmbd は NetBios 名のネームサーバ Wins サーバになるそうだ。そうすると、ブロードキャストする代わりに、そのサーバにIP アドレスを問い合わせることになる(はず)。 また、smb.conf では wins server = xxx.xxx.xxx.xxx として、他の Wins サーバの IP アドレスを指定することもできるようだ。しかし今回はブロードキャストベースの名前解決をすることに したので、Wins サーバは立てないことに。そして、hoge2 で nmbd だけを起動させるには、ubuntu 12.04lts だと /etc/default/samba で、 RUN_MODE を daemons 以外にすればよい:

# Defaults for samba initscript
# sourced by /etc/init.d/samba
# installed at /etc/default/samba by the maintainer scripts
#

#
# This is a POSIX shell fragment
#

# How should Samba (smbd) run? Possible values are "daemons"
#       or "inetd".
#RUN_MODE="daemons"
RUN_MODE="inetd"

と書いておけばよい。 /etc/init/smbd.conf はこのファイルを見て、smbd を起動するかどうかを判断している。ちなみに ubuntu 12.04lts の /etc/init/nmbd.conf では smb.conf に disable netbios = yes と書いてあると、nmbd を起動しない。

ここまできたら、あとは /etc/nsswitch.conf にホスト名解決を以下にした:

hosts:          files dns wins
これで hosts ファイルになにも書かなくても、 NetBios名で接続ができるようになった。 Windows マシンは nsswitch.conf 的なものはよくわからないが、とくになにもしなくても nmbd の 動いている linux ホストへ NetBios 名で接続できるようになった。

蛇足

さらに OSX でも nsswitch 的なことをしたかったのだが、やり方がわからない。しかたなく、スクリプトを書き、 hosts ファイルを定期的に更新するようにした。 ちなみに OSX には nmblookup というコマンドは見当たらず、 代わりに smbutil lookup でブロードキャストできるようだ:

smbutil lookup hoge1

2015年11月12日木曜日

iptable の備忘録

iptable で http ポートへのアクセス制限をした記録

VPS で運用している nginx を自宅と sim 端末からだけアクセスできるようにした。

事前準備として必要なことが1点。iptables の設定ミスで ssh が不通になった場合に備え、VPS のコンソールが取れ、 root でログインできることを確認すること。

まず自宅から VPS で動かしている sshd と nginx へアクセスできるようにするには、こんな感じの設定ファイルを作成する。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -s <Home IPAddress> -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s <Home IPAddress> -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT

  1. 1行目はルールを記載するテーブル として filter を指定している。これがデフォルトのテーブルであり、この備忘録ではおまじないと考えることにする。
  2. 2行目では INPUT チェインのポリシーを DROP に設定。入ってきたパケットは全て捨てるポリシーを指定している。この後、受け取りたいパケットのルール(例外)を登録する。
  3. 3行目では FORWARD チェインのポリシーを DROP に設定。転送はしない。
  4. 4行目はVPS から外へ出て行くパケットは全て許可。
  5. 5行目は ssh を開けている。 -A INPUT では、ルールを登録するチェインとして INPUT を指定している。チェインはパケットの選択ルールを登録するためのリストである。デフォルトテーブル filter で VPS へのアクセス制限をする場合、組み込みチェインは INPUT, OUTPUT, FORWARD の3つになる。この他にユーザ定義チェインを作ることもできるが、それについては一旦置いておく。この行では VPS に入るパケットを選ぶルールを指定したいので、INPUT チェーンに対してルールを設定する。-s でアクセス元の自宅 IP アドレスを指定、ssh を 22 番ポートで動かしているので --dport 22 としている。末尾の -j オプションは --jump の省略形で、ACCEPT という組み込みターゲットを指定している。入ってきたパケットが -s で指定したアドレスからで、22 番ポート宛であれば、この行がマッチして、 -j で ACCEPT と指定しているので、パケットは VPS 内の sshd に届く。
  6. 6行目は http を開けている。5行目と同様に INPUT チェインに対してルールを設定している。
  7. 7行目は ping を受けとる。
  8. 8行目は自分自身へのパケットを受け取るようにしている。
  9. 9行目はVPS から外部ホストへアクセスした結果、返ってくるパケットを受けとるようにしている。
設定ファイルを例えば /etc/iptables.up.rules として保存して、 iptables-restore で以下のように読み込ませれば、その時点からアクセス制限がかかる。
iptables-restore < /etc/iptables.up.rules
但し iptables-restore コマンドは、オプションを指定しないと、すでに登録されていたルールが全て消える。例えば ssh 許可のルールが登録されている状況で、オプション無しで実行すると、ssh が不通になる。既存のルールをフラッシュせずにルールを追加するにはオプション --noflush を付ける。

次にSIM 端末からのアクセスはどうするか。現在使っている SIM は iijmio で、APN をみると vmobile.jp とある。そこで WHOIS で IIJNET を調べ、そのうちで vmobile.jp である IP アドレスを調べてみる
whois -h whois.apnic.net IIJNET | grep inetnum
 ずらずらと出てくる(結果は省略)。この中から vmobile.jp なアドレスを拾う ruby スクリプトを作った。
require 'ipaddr'

NSLOOKUP =         '/usr/bin/nslookup'
WHOIS    =         '/usr/bin/whois'
GREP     =         '/bin/grep'

class IPAddr
  class << self

    def ipcount(ip1, ip2)
      bit = 0
      ip = ip1.dup
      loop {
        while ! ( (ip >> bit) == (ip1 >> bit) )
          bit += 1
        end

        if ip == ip2
          break
        end
        ip = ip.succ
      }
      "#{ip1}/#{32 - bit}"
    end

  end
end

module Net
  class << self

    def hostname(ip)
      `#{NSLOOKUP} #{ip}` =~ /name = (\S+)\./m
      $1
    end

    def get_ranges(netname)
      ranges = `#{WHOIS} -h whois.apnic.net #{netname} | #{GREP} inetnum`.split(/\n/)
      ranges.map {|line|
        line =~ /inetnum:\s+(\S+) - (\S+)/
        (IPAddr.new($1) .. IPAddr.new($2))
      }
    end

  end
end

rules = open('/etc/iptables.d/nginx.rules', 'w')

rules.puts <
*filter
-F nginx
EOF

ranges = Net.get_ranges('IIJNET')
ranges.each do |rg|
  host = Net.hostname(rg.first.to_s)
  if host && host =~ /vmobile/
    m = IPAddr.ipcount(rg.first, rg.last)
    rules.puts "-A nginx -s #{m} -p tcp -m tcp -j ACCEPT"
  end
end

rules.puts <<EOF
COMMIT

EOF

rules.close

このスクリプトを動かすと下記の /etc/iptables.d/nginx.rules というファイルが作られる。
*filter
-F nginx
-A nginx -s <IPAddress range 1> -p tcp -m tcp -j ACCEPT
-A nginx -s <IPAddress range 2> -p tcp -m tcp -j ACCEPT
-A nginx -s <IPAddress range 3> -p tcp -m tcp -j ACCEPT
COMMIT


  1. 1行目はおまじない
  2. 2行目は -F で nginx というユーザ定義チェインのルールをフラッシュしている。この nginx というユーザ定義チェインについては後でまた触れる。
  3. 3行目以降でユーザ定義チェイン nginx にたいしルールを追加している。iijmio のアドレスレンジは幾つかあるので、それぞれを -s で指定し、-j ACCEPT で許可している。
このルールをロードする前に、ユーザ定義チェイン nginx を作成する。ユーザ定義チェインの作成は -N <チェイン名> で行う。詳細は後述するが、-N nginx でチェインを作成したら以下のコマンドでチェイン nginx にルールを登録できる。
iptables-restore --noflush < /etc/iptables.d/nginx.rules
この段階では、チェイン nginx が評価されることはない。このチェインを評価させるにはチェイン INPUT で、ポート 80 番へのパケットが来た時にチェイン nginx に jump するよう指示すればよい。そこで一番最初に作った設定ファイル /etc/iptables.up.rules に2行追加する。
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-N nginx
-A INPUT -s <Home IPAddress> -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -s <Home IPAddress> -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT                     -p tcp -m tcp --dport 80 -j nginx
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
COMMIT

追加したのは 5 行目の -N nginx と 8 行目である。5 行目で チェイン nginx を作成し、8 行目では、80番ポートに来たパケットのうち自宅 IP アドレスにマッチしなかった( 7 行目でマッチしなかった)ものは、-j nginx で、チェイン nginx に飛ばすように指定している。

後は、起動時に /etc/iptables.up.rules と /etc/iptables.d/nginx.rules を順に読み込むスクリプトを書くなりすればいい。

#!/bin/bash
/sbin/iptables-restore < /etc/iptables.up.rules
/sbin/iptables-restore --noflush < etc/iptables.d/nginx.rules

2015年1月14日水曜日

curses で文字化け

Ruby から Curses ライブラリを使うとき、漢字を出すと文字化けした。

環境
  • Ubuntu 12.04
  • Ruby 2.1.4 + curses gem (1.0.1) 
経緯
  • gem install curses → curses ライブラリが無くエラーがでた
  • libncurses5-dev を apt-get install する
  • 再度 gem instal curses → バンドルのビルドに成功
  • しかしcurses で漢字を出そうとすると文字化け
  • libncursesw5-dev を apt-get install する
  • 一旦 gem uninstall curses して、再度 gem install curses 
  • 漢字がでた

wide character support の付いた libncursesw5-dev を入れればよいと

2014年6月3日火曜日

TimeCapsule のファンを交換

最近の気温の上昇とともに TimeCapsule のファンが異音をたてるようになってきた。中にはDelta 60*60*15MM BFB0605MB 5V 0.32A Notebook CPU Cooler Fan,Cooling Fanというファンが入っており、購入可能だった。送料込みで 1300 円 程度と、微妙な値段だったが。

分解の仕方はグーグル先生が参考になった。ハードディスクの交換や電源コンデンサの交換など先人の足跡をみることができる。しかしファンはきれいに取り外すことができなかった。3つのゴム足で底蓋に固定されているが、それをうまくはずすことができず、仕方ないのでゴム足を引きちぎってはずした。写真をとるのも忘れ、新しいファンをケースに押し込めて蓋を閉じた。

音は静かになり、これまで通りに使えている。さて 6 回目の夏を越せるだろうか。

2014年5月10日土曜日

Installing Ruby 2.1.2 on OSX

ruby 2.1.2 を osx に入れた記録

openssl_1.0.1g

./Configure darwin64-x86_64-cc --prefix=/usr/local/openssl_1.0.1g shared
make
make instal
cd /usr/local/
ln -s openssl_1.0.1g openssl

yaml_0.1.6

./configure --prefix=/usr/local/yaml_0.1.6
make
make install
cd /usr/local/
ln -s yaml_0.1.6 yaml

readline_6.3

./configure --prefix=/usr/local/readline_6.3
make
make install
cd /usr/local/
ln -s readline_6.3 readline

ruby_2.1.2

./configure --prefix=/usr/local/ruby_2.1.2 \
  --with-openssl-dir=/usr/local/openssl \
  --with-libyaml-dir=/usr/local/yaml \
  --with-readline-dir=/usr/local/readline
make
make install
見ていて少し気になったのは dl 。以前は入ってた気がするが
Failed to configure -test-/win32/dln. It will not be installed.
Failed to configure -test-/win32/fd_setsize. It will not be installed.
Failed to configure dl. It will not be installed.
Failed to configure dl/callback. It will not be installed.
Failed to configure gdbm. It will not be installed.
Failed to configure tk. It will not be installed.
Failed to configure tk/tkutil. It will not be installed.
Failed to configure win32ole. It will not be installed.

2014年5月1日木曜日

Ubuntu 12.04 LTS で音がでない

root だと音がでるのに、一般ユーザーだと出ない

以下のコマンドを実行すると root では音がでるのに、一般ユーザーでは音がでなかった
ogg123 -q /usr/share/sounds/ubuntu/stereo/phone-incoming-call.ogg
 理由は判らないが、pulseaudio というサービスを root 権限で止めたら一般ユーザーでもなるようになった。/etc/init.d/pulseaudio stop では駄目で kill -9 PID した。その後一般ユーザーで ogg123 コマンドを使うと音がでた。

ogg123 コマンドを利用した後にプロセスを確認すると、そのユーザーで pulseaudio というサービスが動いていた。再起動すると一般ユーザーで再び音がでなくなるかもしれない。