Ubuntu serverでNIC毎に宛先ルータを変える

Ubuntu server 12.04 LTSで2枚のNICを使って、それぞれ別のネットワークに接続。先のルータでは別々のプロバイダに接続していて、NICを指定して通信すると、使用回線を切り替えできるようにする。

まず、/etc/sysctl.conf を設定
28行目をコメントアウト

net.ipv4.ip_forward=1

保存したら
sudo sysctl -p
で適用。

次に、/etc/network/interfaces
今回はDHCPを使用せずに設定

auto eth0
iface eth0 inet static
  address 192.168.34.25
  netmask 255.255.255.0
  network 192.168.34.0
  gateway 192.168.34.254
  
auto eth1
iface eth1 inet static
  address 192.168.206.25
  netmask 255.255.255.0
  network 192.168.206.0

見ての通り、デフォルトのGWは192.168.34.254で、もう一方のネットワークにはGWを指定しない。

次に、/etc/network/if-up.d/routes
を新規に作成

#!/bin/sh
IF1=eth0
IF2=eth1
IF1_IP=192.168.34.25
IF2_IP=192.168.206.25
GATEWAY1_IP=192.168.34.254
GATEWAY2_IP=192.168.206.254
IF1_NET=192.168.34.0/24
IF2_NET=192.168.206.0/24
ROUTING1_NAME=gate1
ROUTING2_NAME=gate2

case $IFACE in
"eth0")
  # eth0
  /sbin/ip route add $IF1_NET dev $IF1 src $IF1_IP table $ROUTING1_NAME
  /sbin/ip route add default via $GATEWAY1_IP table $ROUTING1_NAME
  /sbin/ip rule add from $IF1_IP table $ROUTING1_NAME
;;

"eth1")
  # eth1
  /sbin/ip route add $IF2_NET dev $IF2 src $IF2_IP table $ROUTING2_NAME
  /sbin/ip route add default via $GATEWAY2_IP table $ROUTING2_NAME
  /sbin/ip rule add from $IF2_IP table $ROUTING2_NAME
;;
esac

保存したら実行権限を与える事。
ここはinterfacesで指定したIPなどと一致させるように記述。
あと、ROUTING1_NAMEとROUTING2_NAMEを覚えておくこと。

次に、/etc/iproute2/rt_tablesを設定

200 gate1
201 gate2

を追記。gate1, gate2 はroutesで設定したROUTING1_NAME, ROUTING2_NAMEと一致させる。

最後に、DHCP環境じゃなくても/etc/resolv.confが勝手に書き換わるようなので
/etc/resolvconf/resolvconf.d/base を書き換える。

nameserver 192.168.34.15
nameserver 192.168.34.12

これで再起動すると反映される。

PHPで平仮名からローマ字書きに変換したかった

PHPで平仮名からローマ字書きに変換したかった。と、諸事情があってひとまずリストを配列で書き出した。

またいつか何かの機会に使うかもしれないので貼っておく。でももうこういうのやりたくない。


$hoge = array
('あ' => array('a'), 'い' => array('i'), 'う'=>array('u'),
'え'=>array('e'), 'お'=>array('o'),
'か'=>array('ka'), 'き'=>array('ki'), 'く'=>array('ku'),
'け'=>array('ke'), 'こ'=>array('ko'),
'さ'=>array('sa'), 'し'=>array('si', 'shi'), 'す'=>array('su'),
'せ'=>array('se'), 'そ'=>array('so'),
'た'=>array('ta'), 'ち'=>array('ti', 'chi'), 'つ'=>array('tu', 'tsu'),
'て'=>array('te'), 'と'=>array('to'),
'な'=>array('na'), 'に'=>array('ni'), 'ぬ'=>array('nu'),
'ね'=>array('ne'), 'の'=>array('no'),
'は'=>array('ha'), 'ひ'=>array('hi'), 'ふ'=>array('hu', 'fu'),
'へ'=>array('he'), 'ほ'=>array('ho'),
'ま'=>array('ma'), 'み'=>array('mi'), 'む'=>array('mu'),
'め'=>array('me'), 'も'=>array('mo'),
'や'=>array('ya'), 'ゆ'=>array('yu'), 'よ'=>array('yo'),
'ら'=>array('ra'), 'り'=>array('ri'), 'る'=>array('ru'),
'れ'=>array('re'), 'ろ'=>array('ro'),
'わ'=>array('wa'), 'を'=>array('wo'), 'ん'=>array('n', 'nn'),
'が'=>array('ga'), 'ぎ'=>array('gi'), 'ぐ'=>array('gu'),
'げ'=>array('ge'), 'ご'=>array('go'),
'ざ'=>array('za'), 'じ'=>array('ji'), 'ず'=>array('zu'),
'ぜ'=>array('ze'), 'ぞ'=>array('zo'),
'だ'=>array('da'), 'ぢ'=>array('di', 'ji'), 'づ'=>array('du', 'zu'),
'で'=>array('de'), 'ど'=>array('do'),
'ば'=>array('ba'), 'び'=>array('bi'), 'ぶ'=>array('bu'),
'べ'=>array('be'), 'ぼ'=>array('bo'),
'ぱ'=>array('pa'), 'ぴ'=>array('pi'), 'ぷ'=>array('pu'),
'ぺ'=>array('pe'), 'ぽ'=>array('po'),
'きゃ'=>array('kya'), 'きゅ'=>array('kyu'), 'きょ'=>array('kyo'),
'しゃ'=>array('sya', 'sha'), 'しゅ'=>array('syu', 'shu'),
'しょ'=>array('syo', 'sho'),
'ちゃ'=>array('tya', 'cha'), 'ちゅ'=>array('tyu', 'chu'),
'ちょ'=>array('tyo', 'cho'),
'にゃ'=>array('nya'), 'にゅ'=>array('nyu'), 'にょ'=>array('nyo'),
'ひゃ'=>array('hya'), 'ひゅ'=>array('hyu'), 'ひょ'=>array('hyo'),
'みゃ'=>array('mya'), 'みゅ'=>array('myu'), 'みょ'=>array('myo'),
'りゃ'=>array('rya'), 'りゅ'=>array('ryu'), 'りょ'=>array('ryo'),
'ぎゃ'=>array('gya'), 'ぎゅ'=>array('gya'), 'ぎょ'=>array('gyo'),
'じゃ'=>array('zya', 'ja', 'jya'), 'じゅ'=>array('zyu', 'jyu', 'ju'),
'じょ'=>array('zyo', 'jyo', 'jo'),
'びゃ'=>array('bya'), 'びゅ'=>array('byu'), 'びょ'=>array('byo'),
'ぴゃ'=>array('pya'), 'ぴゅ'=>array('pyu'), 'ぴょ'=>array('pyo'),
);

PHPでマルチバイト(日本語)に対して正規表現を使って後方参照したかった

PHPでマルチバイト(日本語)に対して正規表現を使って後方参照したかった。ちょっと正規表現でごにょごにょしてるとつっかえたことがあったのでメモ。

まず、次のような試験がうまく通らなかった。



<?php

$str[] = '1あああ2'; // 1) hit => OK
$str[] = '1ああ)あ2'; // 2) not hit => OK
$str[] = '1ららら2'; // 3) not hit => NG
$str[] = '1らら)ら2'; // 4) not hit => NG
$ptrn = '/1([^\)]*)2/';

foreach($str as $val){
if(preg_match($ptrn, $val, $matches)){
var_dump($matches);
}
}


この例の場合、”あ”が検査対象となっている場合には思った通りの動作をしてくれる。でも”ら”が入った文字列には思い通りの動作にならない。

いろいろ悩んだところ、これはマルチバイトの問題だろう,というところに行き着いた。

まず最初に、preg_matchのマルチバイト版がないか探した。mb_preg_match的な関数で探した。でも無い。残念。

どうやらmb_ereg系はあるらしい。でも最近のPHP (5.3以降)ではeregじゃなくてpreg_matchが推奨されている。

>PHP: PHP 5.3.x で推奨されない機能 – Manual

そしてmb_eregを使うと後方参照(あとで括弧を使って正規表現で合致した文字列の一部を利用できるようになる機能)が使えない。なのでmb_eregは今回の解決方法対象外。

で、ぐぐってると正解にたどり着けた。

どうやら検査パターンの最後のオプションにuを付けるとイイらしい。おそらくutf-8で解釈しなさいよ、ってことかな。

preg系でオプションを付けるには終了デリミタ(って言えば良いのかな)の後ろに文字を列挙して指定する。今回の場合にはこんな感じ。


<?php

$str[] = '1あああ2'; // hit => OK
$str[] = '1ああ)あ2'; // not hit => OK
$str[] = '1ららら2'; // not hit => NG
$str[] = '1らら)ら2'; // not hit => NG
$ptrn = '/1([^\)]*)2/u';

foreach($str as $val){
if(preg_match($ptrn, $val, $matches)){
var_dump($matches);
}
}

?>

原因についても考えてみた。今回は文字(列)”ら”と文字(列)”)”が問題を起こしていた。双方のUTFコードは以下の通りである。

ら E38289

)EFBC89

パっと見た感じ、下二バイトが合致してるとダメみたい。試しに同様に下2バイトが合致する”ド”で試したら案の定”)”と区別できなくなってた。ほむー。

JavaScript Unicode Charts