事前共有鍵(PSK)を用いた単純なOpenVPNの設定
さくらVPSをOpenVPNサーバにしました。サーバ環境はDebian(sid)(d:id:rigarash:20101010#1286695769)です。クライアントは最大で1台のみの接続(私のノートPCからのみ)であり、OpenSSLのCA運用に自信がないので、事前共有鍵(Pre-Shared Key, PSK)を利用しました。これは、出張の時などに安全な通信を行うためのもので、クライアント(DebianかWindows)からの通信がすべてさくらVPS経由になるようにします。
サーバ側の設定
まず、openvpnをインストールします。
$ sudo -H aptitude install openvpn
次に、事前共有鍵(/etc/openvpn/winclient.key)を生成します。
$ sudo -H openvpn --genkey --secrett /etc/openvpn/winclient.key
作成したサーバ設定ファイル(/etc/openvpn/winclient.conf)は以下の通りです。一応権限をnobody/nogroupに落としています。オプションの説明は、openvpn(8)に書いてあります。
$ cat /etc/openvpn/winclient.conf port 1194 proto udp dev tun ifconfig 192.168.200.1 192.168.200.2 user nobody group nogroup persist-key persist-tun secret /etc/openvpn/winclient.key status /etc/openvpn/winclient.log
OpenVPNをifup/ifdownできるようにします。ip_forwardの設定と、NATの設定が必要になります。
$ cat /etc/network/interfaces ... ## OpenVPN(winclient) auto tun_winclient iface tun_winclient inet manual pre-up iptables -t nat -A POSTROUTING -s 192.168.200.2/32 -j MASQUERADE openvpn winclient post-down iptables -t nat -D POSTROUTING -s 192.168.200.2/32 -j MASQUERADE
$ cat /etc/default/openvpn ... AUTOSTART="none" ...
$ cat /etc/sysctl.conf ... net.ipv4.ip_forward=1 ...
クライアント(Windows Vista (x64))の設定
私がWindows Vista (x64)ユーザのため、他の環境でテストしてませんが、Windows XP以降ならあまり変わらないはずです。UACがあるので少し面倒でした。
まず、OpenVPNのサイト(Community Downloads | OpenVPN)から、"OpenVPN Community Software Windows Client Download"をダウンロードして、インストールします。
次に、メモ帳を管理者権限で起動して、以下の内容をC:\Program Files (x86)\OpenVPN\config\winclient.ovpnとして保存します。
remote XXX.XXX.XXX.XXX port 1194 proto udp dev tun ifconfig 192.168.200.2 192.168.200.1 redirect-gateway bypass-dhcp bypass-dns def1 persist-key persist-tun secret winclient.key status winclient.log
同様にC:\Program Files (x86)\OpenVPN\config\winclient.keyをサーバから持ってきます。鍵ファイルの改行コードはCR+LFに変換しておきました。(しないと動かないかどうかは未検証)
最後に、OpenVPN GUIを管理者権限で起動して、右クリック->"Connect"が成功すればOK。
クライアント(Debian)の設定
まず、openvpnをインストールします。
$ sudo -H aptitude install openvpn
クライアント側の設定ファイル(/etc/openvpn/winclient.conf)を作成します。redirect-gatewayが肝で、サーバ側に通信を振ってくれます。なお、私はローカルにunbound(DNSキャッシュサーバ)を立てているので必要ないのですが、一般的には、DNSの設定(/etc/resolv.confの処理等)が必要になります(未検証)。
$ cat /etc/openvpn/winclient.conf remote XXX.XXX.XXX.XXX port 1194 proto udp dev tun ifconfig 192.168.200.2 192.168.200.1 redirect-gateway def1 secret /etc/openvpn/winclient.key status /etc/openvpn/winclient.log
次に、サーバ側で作成した/etc/openvpn/winclient.keyをローカルに準備(コピー)します。パーミッションは0600に合わせましょう。
$ ls -lAFi /etc/openvpn ... 269219 -rw-r--r-- 1 root root 432 2010-10-12 11:12 winclient.conf 269145 -rw------- 1 root root 636 2010-10-12 06:12 winclient.key ...
クライアント側でもifup/ifdownを利用することにします。クライアント側ではiptablesの設定は必要ないため、単純です。
$ cat /etc/network/interfaces ... ## OpenVPN(winclient) auto tun_winclient iface tun_winclient inet manual openvpn winclient
$ cat /etc/default/openvpn ... AUTOSTART="none" ...
さくらVPSの設定
Debianのインストール
メモのみ。すぐにsidにしてしまいます。
- 5.05(amd64)を選択
- エキスパートモード
- ディスク設定
- primary
- ext3
- reserved 1%
- bootパーティションは100MBでそのまま
- bootable on
- /は8GB
- /homeは残り(13.4GB)
- 200MBほど隠れて利用されている空間があるみたい
- スワップに関して突っ込まれるけど続行(swapfileにする)
- no root login
- パッケージはインストールしない
- GRUB2
- 再起動
- /etc/apt/sources.listをsidに変更
- hardenの設定のみしてアップグレード
- カーネルのアップグレード
- 再起動
- ntp
- swapfile(2GB)
$ sudo -H dd if=/dev/zero of=/home/swapfile bs=1024 count=2097152 $ sudo -H swapon /home/swapfile $ sudo -H sh -c "echo '/home/swapfile swap swap defaults 0 0' >> /etc/fstab"
TODO
- root mailの設定
VirtualBox設定備忘録
メインマシン(ThinkPad X61 Tablet)のSSDをIntel X25-M Mainstream SATA SSD (80GB)から IO-DATA SSDN-ST256Bに交換しました*1。
I-O DATA Serial ATA対応内蔵2.5インチSSD 256GB SSDN-ST256B
- 出版社/メーカー: アイ・オー・データ
- 発売日: 2009/11/27
- メディア: Personal Computers
- クリック: 26回
- この商品を含むブログ (2件) を見る
そこで必要となるのは仮想マシン環境でして、以前から、VMware Workstation, coLinux, VMware Player, VMware Server, そして今回のVirtualBoxと一通り利用してきました。これまでは、64bitホストでも動き、さらにゲストをホストと同期して起動/シャットダウンするために、仮想マシンをWindowsのサービスとして設定できるVMware Serverをずっと使用してきました。しかし、VMware Serverには、いくつか解決されそうにない問題があります。
VMware ServerをノートPCで運用する、というのは想定外の利用法であるとはわかっているので、理解できますが,結構ストレスが溜まっていました。
VMware Serverの売りである、Web AccessやVMware Server Consoleを利用することで、リモートホストからもゲストの管理ができるという点は、ノートPCで運用するにあたっては不要でした。
VirtualBoxの情報も増えてきたので調べてみると、VirtualBoxはコマンドラインからほとんどすべての設定・操作をすることができるため*7、簡単に自動起動/自動シャットダウンスクリプトを書くことができます。そのため、SSDの入れ替えを機に乗り換えてみました。また、VirtualBoxだとWindows 7ホストにも対応していますし、定期的にアップデートもされています*8。
インストールしたのは、リモートデスクトップ接続が使えるPUELなVirtualBox 3.2.6です。ネットワークをどうするかは迷いましたが,ホストのネットワーク接続の頻繁な変更への対応と、ホストからゲストへのアクセスを共存することを目的として、結局以下のように2つ接続を考えることにしました。
- ネットワークアダプタ1(eth0)-NAT
- ネットワークアダプタ2(eth1)-ホストオンリーネットワーク
なお、VirtualBoxのNATではDNS変換もしてくれるのですが、とても遅いので、ゲストではGoogleのDNS(8.8.8.8)を利用することにしました*9。平均的にはこちらが早いです。ゲストにDNSキャッシュサーバとしてunboundを立てるのも選択肢にのぼるかと思います。
自動起動スクリプトと自動シャットダウンスクリプト
バッチファイルやVBScriptのサンプルはいろいろありますが、コマンドプロンプトを出さないようにしたい、という希望と、JavaScriptの時代がきていると勝手に思っているため、JScriptで書きました。これらをWeb上の他の多くのスクリプトと異なり、エスケープをきちんと行ってLong File Nameを使っています。
自動起動スクリプトは次のとおりです。Runの最後の引数にfalseを与えることで、waitせずにホストに制御を戻しています。このスクリプト仮想マシン名はDebianにしています。
var WshShell = new ActiveXObject("WScript.Shell"); WshShell.Run("\"C:\\Program Files\\Oracle\\VirtualBox\\VBoxHeadless.exe\" --startvm \"Debian\"", 0, false); WshShell = null;
自動シャットダウンスクリプトは次のとおりです。ゲストがACPIによる自動シャットダウン可能にしておく必要があります。Runの最後の引数をtrueにすることで、シャットダウン終了までスクリプト終了をwaitさせることができます。
var WshShell = new ActiveXObject("WScript.Shell"); WshShell.Run("\"C:\\Program Files\\Oracle\\VirtualBox\\VBoxManage.exe\" controlvm \"Debian\" acpipowerbutton", 0, true); WshShell = null;
ファイル共有
Windows側にはPUELなVirtualBoxをインストールしたのですが、ゲスト側のモジュール群は、アップデートが面倒なため、Debianオフィシャルに存在するvirtualbox-ose-guest-dkmsを入れました。だいたいの操作に問題はなかったのですが、ファイル共有を利用しようとしたところ、ゲスト側でmountした瞬間にカーネルパニックでゲストが落ちました。詳しく追うのは面倒なので、ファイルはいつもどおりsambaで共有しています。
細かな点
- VirtualBoxのGUIを開いたときにHeadlessなゲストが電源OFF状態と誤認されることがある
- PuTTYかリモートデスクトップで作業する上では無問題
- 電源Onボタンは機能しない(のでやはり無問題)
JabRefからResearchmapのCSV形式を出力するExportFilter
d:id:next49:20100316:p3にあるように、JabRefの文献リストをResearchmapに取り込むには、CSV形式をいじらないといけません。そこで、ExportFilterを書いてみました。
次の内容を1行にして、拡張子をlayoutにしたファイルを作ります。JabRefのメニューからOptions->Manage Custom Exportsを選んで登録すると、Researchmap向けのExportが使えるようになります。ファイル本体は、launchpadにもおいてあります。
"\format[FormatChars]{\title}","\format[FormatChars]{\author}", "\journal","\volume","\number","\format[FirstPage]{\pages}", "\format[LastPage]{\pages}","\format[]{\year}00", "null","null","null","null","null", "\doi","null","null","\url","\format[FormatChars]{\abstract}"
いくつか未実装点もあります。
- 出版月(英語<->数字の変換が現状簡単にはできない)
- PubMed(物理の人間は利用しないため、データがない)
また、論文のデータによってはうまくいかないこともあります。
なお、一般的なJabRefのExportFilterの書き方は、ドキュメントがhttp://jabref.sourceforge.net/help/CustomExports.phpにあります。
Debian GNU/Linux (sid)での日本語TeX環境(20100211版)
私が利用しているDebian GNU/Linux (sid)環境では、TeXの環境が2009年末にTeX Live 2009にアップデートされました。アップデート当時はptex(platex)が使えなくなったり(#561427)しましたが、現在では安定して利用できています。ただ、現在のところ、一部手動設定が必要なところがあるため、まとめてみます。
なお、私の現在のワークフローでは、dvipdfmxを利用してjsarticleを利用したPDFを作成できれば十分です。
CMapをTeX Liveから認識させる
jsarticleだけでなく、jarticleだけであってもCMapのインストールは必要です。CMapが以前non-freeだったという歴史上の事情により、現状CMapのファイルはいろいろなパッケージに散らばっています。明朝とゴシックの2書体だけの最低限の設定には、cmap-adobe-japan1をインストールすればよいです*1。残念ながらインストールしただけではTeX Liveからはまだ利用できないので、手動でリンクを貼る必要があります。
$ sudo ln -s /usr/share/fonts/cmap/adobe-japan1 /usr/share/texmf-texlive/fonts/cmap
JISフォントメトリックをdvipdfmxで利用する方法(フォントを埋めこまない)
ptex-jisfontsの自動設定は現状うまくいかないようです(最近手動設定しかしてなくて未調査)。
$ sudo echo "f jis-cjk.map" >> /etc/texmf/dvipdfmx/dvipdfmx.cfg
として、dvipdfmxの設定ファイルに1行加えるか、
$ dvipdfmx -f jis-cjk.map XXX.dvi
として、mapファイルをコマンドラインから指定すればよいです。
JISフォントメトリックをdvipdfmxで利用する(IPAフォントの埋め込み)
mainにotf-ipafontパッケージが入ったので、mainだけでIPAフォントを埋め込んだPDFファイルを作成できます。mainに入っているIPAフォントはTrueTypeなOpenTypeです。TexLive 2009に含まれているdvipdfmxは、OpenTypeなフォントとしては、PostScriptなOpenTypeフォントしか認識しません(バグ報告します)。そのため、TeXシステムにTrueTypeフォントとして認識させる必要があります。
$ sudo ln -s /usr/share/fonts/opentype /usr/share/texmf-texlive/fonts/truetype
とすると、認識されます(バグ報告します)。
また、/etc/texmf/dvipdfmx/jisembed.map*2などのファイルを作成して、
rml-jis H :0:ipam.otf gbm-jis H :0:ipag.otf
として、mktexlsrとupdate-updmap*3すると、
$ dvipdfmx -f jisembed.map XXX.dvi
としてmapファイルをコマンドラインから指定すれば、IPAゴシックとIPA明朝が埋め込まれたPDFを作成できます。もし、埋め込むのをデフォルトにしたいなら、
$ sudo echo "f jisembed.map" >> /etc/texmf/dvipdfmx/dvipdfmx.cfg
とすればいいです。
商用SSHにOpenSSHクライアントから公開鍵認証する方法
これは、7年ほど前に研究室でAlphaの計算機を購入したときに書いた資料ですが、あまりにマイナーな場所にファイルを放置していたので、blogに載せておきます。なお、HP Tru64 UNIXとしか書いてないのは、商用SSH(現SSH Tectia Server/Client)がインストールされているマシンが、手元にはTru64しかなかったからです。商用SSHがインストールされている他のUNIX上でも、手順は同じと思われます。
sshを用いれば、毎回passwordを打ちこんだとしても、passwordを盗まれる危険性は低いです。しかし、たとえ暗号化されているとしても、passwordを打ち込まない公開鍵認証(public key authentication)は、便利で、かつより安全です。
ところで、世の中にはOpenSSHサーバ<->OpenSSHクライアント間での認証の説明はたくさんあるのですが、商用SSH<->OpenSSH間の相互運用についての日本語の説明はあまりありません。そこで、今回は、研究室で新たに購入したHP Tru UNIX 5.1B (Alpha)に付属する商用 SSHサーバ(Version 3.2.0)に、 OpenSSHクライアント (Version 3.6.1p2 (Debian sid 2004/01/04))から公開鍵認証で接続する方法を調べました。
なお、ここでは、OpenSSH相互、また商用SSH相互の接続では公開鍵認証ができていることを前提とします。
MPIを用いたプログラムでパラメータを外部ファイルから入力するためのサンプルプログラム
Fortranプログラムにおいて、d:id:rigarash:20100201:1264984235で書いたように、namelistからの入力は強力なのですが、MPI並列化のプログラムでは、コマンドラインなどにアクセスできるのは1ノードだけだったりするので、ポータブルに読み込むにはもう少し注意が必要です。少なくともIntel Fortran 11.0 + Intel MPI 3.1.0 と gfortran 4.4.3 + OpenMPI 1.3.3 (Debian GNU/Linux (sid))でうまく動き、できるだけ標準(Fortran2003含む)に準拠したサンプルを書いてみました。
program main implicit none include "mpif.h" integer :: a,b,c integer :: res integer, dimension(:), allocatable :: resv integer :: clcount character(len=256) :: arg integer :: arglen integer :: ioerr,mpierr integer :: i,j integer :: rank,np namelist /param/ a,b,c a=1 b=2 c=3 call MPI_Init(mpierr) call MPI_Comm_rank(MPI_COMM_WORLD,rank,mpierr) call MPI_Comm_size(MPI_COMM_WORLD,np,mpierr) if (rank == 0) then clcount=command_argument_count() endif call MPI_Bcast(clcount,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) if (clcount == 0) then call stop_program(rank,np,"*** no input file specified. ***") endif if (rank == 0) then allocate(resv(np),stat=ioerr) endif call MPI_Bcast(ioerr,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) if (ioerr > 0) then call stop_program(rank,np,"*** result vector allocation fails ***") endif do i=1,clcount if (rank == 0) then call get_command_argument(i,arg,arglen,ioerr) endif call MPI_Bcast(ioerr,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) if (ioerr > 0) then call stop_program(rank,np,"*** input file name retrieval fails ***") elseif (ioerr == -1) then call stop_program(rank,np,"*** input file name too long ***") endif if (rank == 0) then open(unit=100,file=arg,iostat=ioerr) endif call MPI_Bcast(ioerr,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) if (ioerr > 0) then call stop_program(rank,np,"*** Cannot open input file ***") endif if (rank == 0) then read(unit=100,nml=param,iostat=ioerr) if (ioerr < 0) then print*,"*** parameter reading FAILED. Use default value instead ***" endif close(unit=100) write(unit=6,nml=param) endif call MPI_Bcast(a,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) call MPI_Bcast(b,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) call MPI_Bcast(c,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) res = a + b + c call MPI_gather(res,1,MPI_INTEGER,resv,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpierr) if (rank == 0) then do j=1,np write(6,*), j,resv(j) enddo endif deallocate(resv,stat=ioerr) enddo call stop_program(rank,np,"") end program main subroutine stop_program(rank,np,text) implicit none include "mpif.h" integer :: rank,np integer :: mpierr character(*) :: text if (rank == 0) then write(6,*), trim(text) endif call MPI_finalize(mpierr) stop end subroutine stop_program