初級情報インフラ管理者の技術メモ

ほぼ自分用の技術メモです。

Ubuntu 16.04 LTSでSoftether VPN Clientを使う

ノートPCで実家から自宅にVPN接続しようと思ったら、ノートPCのOSをUbuntu 14.04 LTSから16.04 LTSにアップグレードした時に、VPN接続用のシェルスクリプトを消してしまっていたことに気付き、VPN接続できるようになるまで手こずったため、手順をメモ。なお、Softethr VPN Serverの設定は事前に済んでいることが前提です。

Softether VPN Clientのインストール

Softether VPNの公式サイトにVPN ClientのLinuxへのインストール手順がないのですが、VPN Serverのインストール手順はあり、serverの箇所を全てclientに書き換えるだけでVPN Clientのインストールができます。

7.3 Linux へのインストールと初期設定 - SoftEther VPN プロジェクト

VPN Clientの設定

上記公式サイトを参考に、クライアント側でvpncmdを起動します。

NicCreateコマンドで仮想LANカードを作成し、AccountCreateコマンド、AccountPasswordSetで接続先を設定。最後にサービスモードのVPN Clientを起動した時に自動でVPN接続を開始するよう*AccountStartupSetコマンドを設定します。詳細は公式サイトのコマンドリファレンス参照。

6.5 VPN Client の管理コマンドリファレンス - SoftEther VPN プロジェクト

なお、仮想LANカードを作成する際に指定した名前は、VPN接続時のUbuntuのインターフェース名に使用されます。例えば仮想LANカードの名前を「tun0」にした場合、Ubuntuのインターフェース名は「vpn_tun0」となります。このインターフェース名は後でIPアドレスを設定する際に使用することになります。

VPN接続の開始

VPN Clientのサービス起動

上記までの手順が完了したら、次のコマンドでVPN Clientサービスを開始します。

/etc/init.d/vpnclient start

ip addrコマンドでvpn_仮想LANカード名のインターフェースが表示されることを確認します。また、このインターフェースにIPアドレスが設定されていないことが分かるため、次の手順でIPアドレスを設定します。

IPアドレス・ルーティングの設定

当初DHCPIPアドレスを割り当てようとdhclientコマンドを試したのですが、。どうもVPN Clientで作成された仮想のインターフェースにdhclientコマンドでのIPアドレス割当はできないっぽいです。そこで、別のコマンドで固定IPアドレスを割り当てることにします。

IPアドレスの割当と一緒にDNSのアドレスも設定したいのでnmcliコマンドを試したのですが、これも何故かうまく行かないため、ipコマンドで設定することにしました。

以下固定IPアドレスを192.168.1.1、サブネットマスクを255.255.255.0、仮想LANカード名をtun0とした場合の例です。また、VPN接続先のLANに192.168.0.0/16のネットワークがあり、そこへのゲートウェイが192.168.1.254とします。

ip address add 192.168.1.1/24 brd 192.168.1.255 dev vpn_tun0
ip route add 192.168.0.0/16 via 192.168.1.254 dev vpn_tun0

DNSゾルバの設定

nmcliが使えないため、邪道ですが直接/etc/resolv.confファイルを書き換えることとします。後述しますが、VPN接続を切断した際には必ず/etc/resolv.confを元に戻す必要があります。

以下参照するDNSサーバのアドレスを192.168.0.1とした場合の例です。

sed -i -e "s/127\.0\.1\.1/192.168.0.1/g" /etc/resolv.conf

以上でVPN接続してネットワーク接続するまでの手順は完了です。

VPN接続の切断

VPN Clientサービスの終了

VPN Clientサービスを止めることで、作成されていた仮想のインターフェースは削除されます。

/etc/init.d/vpnclient stop

DNSゾルバの復元

/etc/resolv.confを元に戻します。なお、後述するNetworkManagerの再起動の際に自動で元に戻るのですが、念の為先に手動で元に戻しておくものです。

sed -i -e "s/192\.168\.0\.1/127.0.1.1/g" /etc/resolv.conf

NetworkManagerの再起動

最後に念の為ネットワークの設定をリセットします。

systemctl restart NetworkManager.service

以上でVPN接続の切断は完了です。

これらの手順をシェルスクリプトにまとめておくと便利です。が、間違えてシェルスクリプトを無くしてしまったときに苦労するので注意ですね。

Rubyでひらがなカタカナをヘボン式ローマ字に変換する

業務で大量の人名の読み仮名データ(しかも半角カタカナ)をヘボン式ローマ字に変換しなくてはならなくなったので、Rubyでひらがなカタカナをヘボン式ローマ字に変換するライブラリを作成してみました。

github.com

個人的には訓令式の方が読みやすくて好きなのですが……。

旭川市オープンデータを使った避難場所検索Webアプリを作ってみた

旭川市オープンデータライブラリ が公開されていて、その中に旭川市指定避難場所の一覧が位置情報付きで公開されているのを知って、プログラミングの勉強がてら、旭川市避難場所検索Webアプリを試作してみました。

旭川市避難場所検索(ベータ版)

2017/03/12 追記 : YOLPが常時SSL(AOSSL)対応となり無料版でもHTTPSが使えるようになった ため、現在位置が取得できない問題が解決しましたので、エントリの内容を一部修正しました。

JavaScriptでクライアントの現在位置の緯度経度を取得し、オープンデータから取得した避難場所の緯度経度と計算し、避難場所までの距離を算出し、現在位置から近い避難場所の情報を表示するものです(距離は三角関数を使って算出しているもので、実際の道路状況を考慮した近さを算出できるわけではないので、あくまで近さの目安を確認するものになります)。

最初Ruby on Railsの勉強として作ろうと思ったのですが、やっているうちにERBの使い方や、Rackの仕組みを勉強したいと思い、プログラムはRubyで書き、HTTP周りの部分はRackを使いました。

地図はYahoo! Open Local Platform (YOLP)API(無料版)を使わせてもらっています。

サーバーはHerokuのdyno無料版を使わせてもらっています。

無料版のみで構築したので、このWebアプリには次のような弱点があります。

  1. 1日18時間しかアクセスできない。
  2. 前述のとおり、道路状況を考慮した避難場所までの近さを表示できていない。

1番目の弱点はHeroku dyno無料版の制限です。有料版に移行するか、自分のWebサーバに移すかすれば解決できそうです。

2番目はYOLPのAPIの機能でなんとかできるのかな?これから調べてみたいと思います。

そんなわけで、あくまで私の個人的なプログラミングの練習材料ということで……。

iPhoneから快適にsshするために持ち運びできるblootoothキーボードを買った

時々空いた時間にiPhoneから自宅にVPNを張って、自宅鯖にsshして色々(最近はRuby on Railsチュートリアルやってます)していたのですが、iOSのソフトウェアキーボードでちまちまコマンド打ったりテキスト書いたりするのが辛いので、Ankerというメーカーのbluetoothキーボード買いました。

横幅がiPhone 6を2台縦に並べたくらいあり、折り畳みもできないのだけど、軽いのでカバンの中でさほど邪魔にならない感じ。作りはしっかりしていてキーは打ちやすいです。あとESCキーがちゃんとある。amazonで他のモバイル用bluetoothキーボード見てたらESCキーが無いものが結構あって、自分はNEC Express5800のBMCにsshしてテキストコンソール使うときに、コンソールから抜けるのにESCキーが要るから、ESCキーの有無も選定理由になりました。ちなみにこの手のキーボードは英語配列のものが多いようで、今回買ったキーボードもそうでしたが、元々英語配列キーボード使いの自分には好都合でした。

早速iPhoneのServerauditorという無料だけど使い勝手のいいsshクライアント立ち上げて、bluetoothキーボード繋いで使ってみたら、「これsshするだけならノートPC要らなくね?」ってレベルで快適でした。

Serverauditor - SSH Shell / Console / Terminal

Serverauditor - SSH Shell / Console / Terminal

  • Crystalnix
  • ユーティリティ
  • 無料

今までソフトウェアキーボードで画面の下半分が隠されていたのがなくなり、それなりに表示領域が確保できるし、キー入力の反応もストレス感じないです。唯一ちょっと不満なのは、キー押しっぱなしを認識してくれないこと。例えばVimでざっと行を下に移動しながら中身見ようとJのキーを押しっぱなしにしてもカーソルは1行しか動いてくれないです。まあ普通にキー連打すればいい話なんだけど。

自分はiPhone6だけど、6 plusならもっと快適なんじゃないかなと思います。2000円前後の値段でこの快適さが手に入るならもっと早く買っていれば良かった。

そんなわけで快適な環境が手に入って大満足なのですが、iPhoneの小さい画面にsshクライアント立ち上げてコマンド打ってる様は正直絵面にキツイものがあるようです。家でウキウキでセッティングしていたら妻にまるで犯罪者を見るような目で見られました。ただ小学生の息子がえらい食い付いてきて、「(お下がりした)iPhone4に繋ぎたい!」とか言い出してちょっと困った。何する気なんだろう……。

YAMAHA RTX1200とIIJmio FiberAccess/NFでDS-Lite (IPv4 over IPv6) を使ったIPv4接続環境を構築する

NTTのフレッツ光ネクストファミリー・ハイスピードタイプで、インターネット接続プロバイダーサービスにIIJmio FiberAccess/NFを使うと、IPoE接続のIPv6通信が可能です。IPoE接続の場合、ファミリー・ハイスピードタイプの下り通信速度200Mbpsの制限を受けず、下りの通信速度が概ね1Gbpsとなります(上りは100Mbpsで変わらず)。なので、Gigabitのインターフェイスを持つルーターを使えば、IPv6については上位の通信回線プランを使わなくても下り1Gbpsの通信ができることになります。

とはいえうちのルーターYAMAHA RTX1100だったので、さほど恩恵を受けられずにいました。そんな時にtwitterで、DS-Liteについて書かれたブログを発見しました。

IIJmio FiberAccess/NFでは、DS-LiteというIPv4 over IPv6によるIPv4接続サービス(要するにプロバイダーが用意するNATルーター経由でIPv4インターネット接続ができるもので、NATルーターまでの足回りにIPv6が使う(IPv6でNATルータとIPIPトンネルを張る)というもの、と私は理解しています。)が使えるため、これを使えば、トンネルのオーバーヘッドはあるにせよ、IPv6での通信速度と同程度のIPv4インターネット接続が期待できるものです。

DS-Liteとは

DS-Lite(Dual-Stack Lite)は、RFC6333で規定された通信規格で、本機能を利用することにより、IPv6のみの通信環境においてIPv4 over IPv6技術を利用し、IPv4での通信も可能となります。DS-Lite対応の通信機器をご用意いただければ、一台の機器でIPv6/IPv4双方の通信が可能となります。また、通信速度はIPv6ネットワークの通信速度に準じますので、ご利用回線によっては、IPv4 PPPoE接続での通信速度よりもより高速な通信をご利用いただけます。

IIJmio:DS-Liteについてから引用

今までIPv4インターネット接続はIIJmio FiberAccess/NFのPPPoEと、格安で固定IPv4アドレスが一つ貰えるi-revoのPPPoEをPPPoEマルチセッションで使っていたのですが(フレッツ光ネクストは基本料金でPPPoEを2セッションまで張れる)、このブログ記事を見て早速RTX1100にDS-Liteの設定を投入したところ、PPPoEでの接続時に比べて倍近く下りの通信速度が出るようになりました。

こうなるとGigabitインターフェイスを持っているルーターで試したい気持ちが抑えられず、オークションをさまよってみたら運良く安く中古のRTX1200が手に入ったので、これを機にIPv4接続はDS-Liteのみに切り替えることにしました。

RTX1200のコンフィグは次の通りです。ちなみに同じコンフィグでRTX1100でもDS-Lite接続できました。

# IPv4のデフォルトルートをIPIPトンネルへ向ける設定
# (IPIPトンネルインターフェイスをtunnel 1とする場合)
ip route default gateway tunnel 1

# IPIPトンネルの設定
tunnel select 1
 tunnel encapsulation ipip
 tunnel endpoint address (DS-Lite対向ルーターのIPv6アドレス)
 ip tunnel mtu 1500
 ip tunnel tcp mss limit auto
 tunnel enable 1

最低限のコンフィグはこれだけです(IPv6接続の部分は既に確立している前提で)。PPPoEでIPv4インターネット接続していたらデフォルトルートをppインターフェイスに向けていると思いますが、これをIPIPトンネルインターフェイスに向けて、IPIPトンネルの設定を入れるだけです。もちろんトンネルインターフェイスには適切なip filterを設定することが必要かと思いますがここでは割愛します。

嵌まりポイントが一つあって、トンネルの対向を指定する箇所(tunnel endpoint address 〜の部分)をtunnel endpoint name 〜とすれば対向ルーターIPアドレスではなくホスト名で指定できるのですが、ホスト名で指定するとRTX1200ではトンネルが張れませんでした。

どうも対向ルーターのホスト名の名前解決ができないっぽいのが原因のように思える(IIJDNSサーバーを指定してdigで引いてもIPv6アドレスを返してくれないっぽい)のですが、インターネットマルチフィードの「DS-Lite接続確認情報」のYAMAHA NVR500の設定例を見ると、ホスト名ではトンネルを確立できないと書いてあるので、YAMAHAルーターの仕様で駄目なのかもしれません。おとなしくホスト名での指定を諦めて、直接対向ルーターIPv6アドレスを指定することでトンネルが張れるようになりました。

ちなみに対向ルーターのホスト名は、IIJの会員専用ページ(要ログイン)の「サービス詳細情報」→「FiberAccess/NF」→「設定情報」に書かれています。

対向ルーターIPv6アドレスも上記インターネットマルチフィードのWebページに記載がありますが、NTT東西でアドレスが違うので注意です。

DS-Liteの詳細については、IIJ Technical Week 2014の講演資料(番外編)てくろぐ・セレクト「自宅でもIIJをつかってみませんか?」がとても参考になりました。

さて肝心の通信速度ですが、Speedtest.net by Ooklaで確認したところ、筑波のSoftEtherのサーバー相手に下り350Mbps近く出ていました。フレッツ光ネクストファミリー・ハイスピードタイプの上限200Mbpsを大きく超えており、十分に試す価値ありかと思います。

ただ注意点として、DS-Liteのルーターが東京にあるようで、RadikoのようなIPアドレスから接続している地域を判別するサービスで東京地区と判定されてしまいます(AIR-G'が聞けない……)。

もう一つ重要な注意点が。IIJmio FiberAccess/NFはIPv6は固定のPrefixを貰えますが*1、DS-Liteの出口のIPv4アドレスは非固定です。というかそもそも自分で設定をいじれないNATルーターの配下です。つまり、IPv4でサーバーを外部へ公開したり、VPNで接続したりすることはできないことになります。

これで自分は嵌ってしまいました……。今まで外出先から自宅鯖にアクセスしたい時は、RTX1100とIPv4でL2TP/IPSec接続し、自宅鯖のNEC Express5800のBMCにsshで入ってサーバーの電源オンオフをしていたので、これが出来なくなるととても困る。

直接IPv6でBMCにsshできるならいいのだけど、自分の持っているExpress5800に搭載のものはBMCのIPアドレスIPv4のみ指定可のものでした……。

Openswanを使えばRTX1200とLinuxとでIPv6VPNが張れるので、VPN経由でRTX1200にsshして、そこからBMCにsshすればいけるのだけど、iPhone 6の標準のL2TPクライアントではIPv6でのVPNができないし、そもそも外出先でIPv6アドレス貰える環境はほとんどないし……(IIJmioのSIMとIPv6対応のモバイルルーターNEC MR03LN)持ってるけど、モバイルルーターの電池が切れると詰む)。

悩んだ結果、固定IPv4IPv6アドレスを貰えるさくらのVPSを借りて、SoftEther VPN Server立てて解決することにしました。これについては別の記事に書きたいと思います。

*1:NTTのメンテナンス等で変わる場合があるとのこと。割り当てられるIPv6アドレスは固定ですか? | IIJmio

自宅鯖ネットワークをIPv6中心に再構築しました

自宅鯖ネットワークのバックボーンはフレッツ光ネクストファミリーハイスピードにIIJmio FiberAccess/NFで、IPv6接続時は通信速度が下りのみ概ね1Gbps出せる環境だったのですが、ルーターYAMAHA RTX1100でインターフェイスが全てFast Ethernetだったため、その恩恵が受けられない状況でした。

最近中古でGigabit Ethernetインターフェイスを持つYAMAHA RTX1200が手に入ったため、これを機に自宅鯖ネットワークをIPv6を中心に再構築することにしました。再構築方針は次のような感じです。

  • IPv4インターネット接続をプロバイダーのPPPoE経由にすると通信速度が200Mbpsに制限されてしまうため、PPPoEをやめて、IIJmio FiberAccess/NFで提供されている DS-Lite *1IPv4インターネット接続をする。
  • 今まで外出先から自宅鯖ネットワークへのアクセス方法は、PPPoEで固定IPv4アドレスを貰えるプロバイダーを使って、RTX1100に固定IPv4アドレス振って、L2TP over IPSecVPN接続していたが、PPPoEをやめる方針に従い、IPv4IPv6ともに固定IPを一つ貰えるさくらのVPSSoftEther VPN Serverを立てて、これをハブにVPN接続をすることにする。具体的にはRTX1200とSoftEther VPN Server間をIPv6でL2TPv3 over IPSecで接続し、ノートPC(Ubuntu 14.04LTS)やiPhoneからはSoftEther VPN ServerにIPv4VPN接続する。
  • ついでにもう一つさくらのVPSにzabbixとsyslogサーバーを立てて、さくらのVPSからVPN経由で24時間zabbixで自宅鯖ネットワークを監視し、ルーター他のログをVPN経由でさくらのVPSのsyslogサーバーに飛ばせるようにする。これは 妻からのプレッシャー 家庭の事情により24時間自宅鯖を起動させておけないため、自宅鯖側にzabbixやsyslogを立てておけないという事情のため。
  • さらについでにVPN経由で自宅鯖であるNEC Express5800のBMC *2 にアクセスして、sshで電源オンオフできるようにする。
  • さらにさらについでにKVMLinux仮想ホストを作るときに楽をするため、kickstartでベースを作った後knife soloで設定を流し込めるようにする。

この方針に沿って年末からちまちま作業をしていて、ようやく少し形になってきましたので、Cacooで図を書いてみました。

cacoo.com

これから備忘録的に何回かに分けて、今回の再構築でやった作業を書いていこうと思います。

実行中のKVMゲストをまとめてシャットダウンするシェルスクリプト

KVMホストサーバをshutdownする前にKVMゲストをshutdownしたい時、一ゲストごとにコマンド打つのはちょっと面倒になってきたので、一回のシェルスクリプト実行でKVMゲストを全部シャットダウンできるようにしてみました。

シェルスクリプトの内容は次の通りです。

#!/bin/bash
for var in `/usr/bin/virsh list --all | egrep 'running$|実行中$' | awk '{print $2}'`
do
  echo "virtual machine $var is going to shutdown..."
  /usr/bin/virsh shutdown $var
done

以下解説。

シェルスクリプトのfor構文は、コマンドの実行結果を変数に代入することができるので、virsh listコマンドの出力からKVMゲストのドメイン名のみ抽出して変数に渡す→変数と組み合わせてvirsh shutdownコマンドを完成させて実行、という内容です。

コマンドvirsh list --allを実行すると次の出力が返ります。

[hoge@kvm ~]$ sudo virsh list --all
 Id    Name                           State
----------------------------------------------------
 1     docker                         running
 2     proxy                          running
 3     router                         running
 -     www                            shut off

実行中のKVMゲストはState(状態)が「running(日本語環境だと「実行中」)」となるので、virsh list --allの出力からまずはegrepで行末が「running」か「実行中」になっている行を抽出し、パイプでawkへ渡します。2項目目がKVMゲストのドメイン名なので、awkで$2だけをprintします。結果、実行中のKVMゲストのドメイン名のみが出力されることになります。

後はfor構文に出力を渡せば、ここでは変数varにKVMゲストのドメイン名が代入されるので、変数varをvirsh shutdownコマンドの引数にするようにすれば、ループで全ての実行中のKVMゲストのvirsh shutdownコマンドが実行される仕組みです。

簡単な小ネタなので、例外処理とか一切考慮していません。

ちなみに、KVMゲストがCentOS6で、virsh shutdownコマンドでシャットダウンできない場合、acpidをyumでインストールすればシャットダウンできるようになります。