NAMELIST IOを利用したパラメータ入力の例文
諸般の事情により、共同研究者がFortranで開発してくれた計算プログラムを用いて研究をしています。計算パラメータがソースファイルに直書きだったので、Fortranの入出力をいろいろ調べていました。どうやら、Fortran2003でようやく標準化された入出力が準備されたようで、試したところ、少なくともgfortran 4.4とIntel Fortran Compiler for Linux 11.0では、namelistの内部read文以外は動くようでした。サンプルプログラムはそれなりに見つかったのですが、iostatusまでまじめに考慮したサンプルが見つからなかったので、とりあえず書いてみました。エラーが負だったり正だったりと、過去の遺産からかばらばらなのが、面倒です。
このサンプルでは、コマンドラインに複数のパラメータファイルを指定して、それぞれ読み込んで、値を出力するようにしています。
program main implicit none integer :: a,b,c integer :: clcount character(len=256) :: arg integer :: arglen,argerr integer :: ioerr integer :: i namelist /param/ a,b,c a=1 b=2 c=2 clcount=command_argument_count() if (clcount == 0) then stop "*** no input file specified ***" endif do i=1,clcount call get_command_argument(i,arg,arglen,ioerr) if (ioerr > 0) then stop "*** input file name retrieval fails ***" elseif (ioerr == -1) then stop "*** input file name too long ***" endif open(unit=100,file=arg,iostat=ioerr) if (ioerr > 0) then stop "*** Cannot open input file ***" endif 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) enddo end program main
OpenSSHでVPNを構築する(tap編)
sshさえ通ればなんでもできる、とはよく言われることです。勤務先などで、ネットワークの制限が厳しくて、困っている方もいるのではないでしょうか。
最近のOpenSSHは、OSのtun/tapデバイスを利用して、VPNを構築することができます。tunを利用したVPNは解説がいくつかあったのですが、tapを利用してVPNを構築する方法(特に日本語)の解説がみつからなかったので、自分で行った設定をまとめてみます。前提条件は、以下の通りです。
- クライアント/サーバの双方がUNIX系である
- クライアント/サーバの双方にrootでアクセスできる
- サーバ側でiptablesの設定が可能
- サーバ側のネットワークへのアクセスが必要でないなら不要
- ブリッジネットワークの設定が可能な人なら不要
さて、tapでは仮想ネットワークが構成されます。ここでは、次のようなネットワーク設定を用いることにします。また、クライアントからサーバを経由してのネットワーク接続ができるような設定にもします。
マシン | インターフェース名 | IPアドレス | ネットマスク |
---|---|---|---|
server | tap0 | 192.168.100.1 | 255.255.255.0 |
client | tap0 | 192.168.100.2 | 255.255.255.0 |
さて、実際にVPN接続の設定に移ります。特権アカウントでの手動ネットワーク設定がかかわるところなので、Debian系列とRedHat系列で設定ファイルが異なります。以下はすべてDebian GNU/Linux (squeeze以降)を仮定します。
rootでのssh接続を可能にする
サーバ側の/etc/ssh/sshd_configの設定変更
最低セキュリティを次の設定まで緩めないといけません。tapだけでなく、tunなVPNも利用する予定があるならPermitTunnelをyesにしましょう。
PermitRootLogin forced-commands-only PermitTunnel ethernet
サーバ側の/root/.ssh/authorized_keysへ公開鍵の登録
さすがにrootでのパスワード認証を常にOKするのはまずいので、クライアント側でVPN用の鍵を作ります。この鍵は、VPN構築専用で、自動化するためにパスフレーズを空にします。なお、パスフレーズが空でも、秘密鍵さえちゃんと安全に管理しておけば、パスワード認証よりも安全です。今回の事例では、tapvpnという名前にします。
client$ sudo -H ssh-keygen -t rsa -f tapvpn Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/tapvpn): Enter file in which to save the key (/root/.ssh/tapvpn): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/tapvpn. Your public key has been saved in /root/.ssh/tapvpn.pub. The key fingerprint is: dc:f1:54:b9:1c:21:9d:3a:70:59:b2:50:55:ad:3f:ec root@client The key's randomart image is: +--[ RSA 2048]----+ | ..+===o| | ..o== .| | .ooo + | | . . +o + | | S . .... | | o.| | . .| | E | | | +-----------------+
公開鍵の内容を一般ユーザ環境にコピーして、tapデバイスの設定と制限を行います。
client$ sudo cp /root/.ssh/tapvpn.pub . ... client$ cat tapvpn.pub no-X11-forwarding,no-agent-forwarding,no-pty,tunnel="0",command="/sbin/ifdown tap0; /sbin/ifup tap0" ssh-rsa AAAA....== root@client
次に、上記のように作ったVPN用の公開鍵(/root/.ssh/tapvpn.pub)をサーバにコピーします。一般ユーザならssh-copy-idコマンドで一発なのですが、サーバにrootで直にログインすることはできないですし、一般ユーザでserverにログインします。なお、server上のアカウントではsudoでなんでもできることを仮定します。
client$ scp tapvpn.pub server: client$ ssh server server$ echo tapvpn.pub | sudo tee -a /root/.ssh/authorized_keys
なお、authorized_keysにオプションを指定するのもよいでしょう。この段階で、クライアントからrootで認証が成功するかどうかを試しておきましょう。シェルのコンソールはでなくとも、認証が通っていれば成功です。Ctrl-Cで終了してください。
client$ sudo -H ssh -v -i /root/.ssh/tapvpn server
クライアント側での/root/.ssh/configの編集
tapの設定をコマンドラインで行うのは面倒なので、一発接続ができるように設定を行います。/root/.ssh/configを編集します。
client$ sudo cat /root/.ssh/config ... Host server-vpn HostName server IdentityFile %d/.ssh/tapvpn Tunnel ethernet TunnelDevice 0
サーバ側でのネットワーク設定の編集
ここまでで、仮想ネットワークデバイスの準備はできているのですが、IPなどの設定が一切していません。今回は、クライアントからはサーバ側のネットワークにサーバマシンによるiptablesによるNATを使って接続する設定にします。変更するのは/etc/network/interfacesです。
server$ cat /etc/network/interfaces ... auto eth0 iface eth0 inet static address XXX.XXX.XXX.XXX netmask YYY.YYY.YYY.YYY pre-up echo 1 > /proc/sys/net/ipv4/ip_forward pre-up iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -j MASQUERADE ... iface tap0 inet static address 192.168.100.1 netmask 255.255.255.0
クライアント側のネットワーク設定
今回は、ドラスティックに、クライアントマシンからの通信は、すべてサーバ側を経由するようにします。なお、autosshパッケージを利用します。また、やはり/etc/network/interfacesを編集します。サーバの実IPアドレスがXXX.XXX.XXX.XXX、クライアントの(VPN接続前の)ゲートウェイのアドレスをZZZ.ZZZ.ZZZ.ZZZとします。
client$ cat /etc/network/interfaces ... iface tap0 inet static pre-up autossh -f server-vpn pre-up sleep 5 address 192.168.100.2 netmask 255.255.255.0 up route add XXX.XXX.XXX.XXX gw ZZZ.ZZZ.ZZZ.ZZZ eth0 up route add default gw 192.168.100.1 tap0 up route del default gw ZZZ.ZZZ.ZZZ.ZZZ eth0 down route add default gw ZZZ.ZZZ.ZZZ.ZZZ eth0 down route del default gw 192.168.100.1 tap0 down route del XXX.XXX.XXX.XXX gw ZZZ.ZZZ.ZZZ.ZZZ eth0 post-down killall autossh
zshの設定ファイル読み込み順番に関するメモ
- login shell のとき
- /etc/zshenv -> $ZDOTDIR/.zshenv -> /etc/zprofile -> $ZDOTDIR/.zprofile -> /etc/zshrc -> $ZDOTDIR/.zshrc -> /etc/zlogin -> $ZDOTDIR/.zlogin
- login shell ではないが、対話的な shell のとき
- /etc/zshenv -> $ZDOTDIR/.zshenv -> /etc/zshrc -> $ZDOTDIR/.zshrc
- 非対話的な shell のとき
- /etc/zshenv -> $ZDOTDIR/.zshenv
- $ZDOTDIR/.zshenv は非対話的に呼びだされたときも読み込まれるので、画面表示を入れてはいけない
Boost.Randomで適当な分布関数を用いる
Boost.Randomの利点は、generator(乱数生成器)とdistribution(分布関数)を分離できるところです。d:id:faith_and_brave:20090629:1246263401であげられている、「80%の確率で0, 20%の確率で1」といった事例は、まさにBernoulli Distributionそのものなので、次のように書いたほうが分布関数の意味がわかりやすいと思います。
#include <iostream> #include <ctime> #include <boost/random.hpp> using namespace boost; int main(int, char**) { mt19937 gen(static_cast<unsigned long>(std::time(0))); bernoulli_distribution<> dst(0.2);// 0.2の確率でtrue variate_generator<mt19937, bernoulli_distribution<> > rand(gen, dst); for (int i = 0; i < 10; i++) { std::cout << rand() << std::endl; } }
POP3サーバからIMAP4サーバにメールを移動する
現在、ネットワークアクセス制限がきついところに出入りしているのですが、外部からメールを送受信するのも大変なので、IMAP4が使えるGMailにメールをすべて移動することにしました。Pythonの勉強を兼ねて、Python クックブック 第2版を参考にしてPOP3サーバからIMAP4サーバへメールを移動させる自作してみました。エラー処理が微妙に足りない気がします。今後daemon化を考えるときには、もう少しエラー処理やクラス化を考えないとなぁと思います。
import getpass import poplib import imaplib import email from email.Utils import parsedate POPHOST = "popserver" POPUSER = "username1" POPPASS = "" IMAPHOST = "imapserver" IMAPUSER = "username2" IMAPPASS = "" try: pop = poplib.POP3_SSL(POPHOST) pop.user(POPUSER) if not POPPASS or POPPASS=='=': POPPASS = getpass.getpass("Password for %s@%s (POP3):" % (POPUSER, POPHOST)) pop.pass_(POPPASS) msgCount, _ = pop.stat() print "Logged in to POP3 server as %s@%s." % (POPUSER, POPHOST) print "Status: %d message(s)" % msgCount imap = imaplib.IMAP4_SSL(IMAPHOST) if not IMAPPASS or IMAPPASS=='=': IMAPPASS = getpass.getpass("Password for %s@%s (IMAP4):" % (IMAPUSER, IMAPHOST)) imap.login(IMAPUSER, IMAPPASS) imap.select() print "Logged in to IMAP4 server as %s@%s." % (IMAPUSER, IMAPHOST) for msgNum in range(1, msgCount+1): _, message, _ = pop.retr(msgNum) msg = email.message_from_string('\n'.join(message)) datetime = parsedate(msg.get('Date')) imap.append('INBOX', [], datetime, str(msg)) pop.dele(msgNum) print "Closing POP3 session" pop.quit() print "Closing IMAP4 session" imap.close() imap.logout() except poplib.error_proto, detail: print "POP3 Protocol Error:", detail except imap.error, detail: print "IMAP4 Protocol Error:", detail
- 作者: Alex Martelli,Anna Martelli Ravenscroft,David Ascher,鴨澤眞夫,當山仁健,吉田聡,吉宗貞紀
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2007/06/26
- メディア: 大型本
- 購入: 11人 クリック: 423回
- この商品を含むブログ (85件) を見る
Sun X4100 ServerのシリアルコンソールをDebian GNU/Linuxから使う
研究室でSun X4100 Serverを運用しているのですが、管理の都合でDebian GNU/Linux (lenny)を導入しました。この機種には標準オプションとしてサービスプロセッサ(ILOM)が付属しており、リモートからの電源On/Off、グラフィカルコンソールの転送まで行うことができます。グラフィカルコンソールの転送は便利なのですが、sshdが起動していない状態の管理のみを行えばよい、という単純な状況では、オーバースペックすぎます。そこで、ILOMのもうひとつの機能である、シリアルコンソールを利用できるようにします。キャラクタベースなので、ネットワークの負荷も軽く、Java等の追加ソフトウェアも必要ありません。Solarisを導入した際には、シリアルポートを認識すると、そのポート上のコンソールが自動で有効になりましたが、Debian GNU/Linux (lenny)ではやってくれないため、いくつか手動での設定が必要になります。
なお、すばらしいことに、Sun X4100 ServerのILOMでは、このシリアルポートからBIOSの情報、SAS RAIDの設定すらできるようになっています。
ログインするための設定
まず、OS上からILOMのシリアルポートが認識されているかどうかを確かめます。次のようにポートがあることを確認できればOKです。
shell $ dmesg | grep ttyS [ 1.117705] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A [ 1.117705] 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A
次に、/etc/inittabファイルを編集して、シリアルポートからログインできるようにします。Debian GNU/Linux (lenny)では、設定例はすでに記載されており、コメントアウトされているだけなので、簡単です。
#T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
上のような設定例の行があるので、ttySの後の数字がdmesgの出力と同じものをみつけて、行頭の#をはずします。多くの場合ttyS0になっていると思います。
T0:23:respawn:/sbin/getty -L ttyS0 9600 vt100
これで設定完了です。再起動は必要なく、次のコマンドを打ったら、すぐに使えるようになっているはずです。
shell # init q
ブートローダの設定
上までの設定が完了すると、BIOSはいじれますし、ログインすることもできるのですが、ブートローダがシリアルコンソールに出てきませんし、起動させるkernelの変更や、kernelに与えるオプションもいじることができません。起動時のログもシリアルコンソールに表示されません。トラブルシューティングができない片手落ちの状態です。ここでは、私がこれまで慣れているDebian GNU/Linux特有の方法を用いたGRUB Legacy(0.9x)の設定を行います。
まず、/boot/grub/menu.lst (またはインストール方法によっては/boot/boot/grub/menu.lst)ファイルを開いて5行目に、次の行を挿入します。
## serial console serial --unit=0 --speed=9600 --word=8 --parity=no --stop=1 terminal --timeout=10 serial console
この2行で、通常の端末tty0とシリアルコンソールttyS0の両方からGRUBメニューにアクセスできるようになります。次に、起動時のカーネルログをシリアルコンソールにも表示する設定を行います。/boot/grub/menu.lstを再度開いて、次のkoptで始まる行を探します。
# kopt=root=/dev/sda1 ro
この行の最後に、次のように設定を付け加えます。このとき、行頭の#を削除してはいけません。consoleで始まる設定が2つともあるのが正しい設定です。Debianでは、この行を設定することで、カーネルのアップデートの際にも自動的にオプションを付与してくれるようになります。
# kopt=root=/dev/sda1 ro console=tty0 console=ttyS0,9600
あとは、この設定ファイルを反映させるだけです。インストールするべきMBRの位置は、/boot/grub/device.mapを見て決めます。今回X4100では、/dev/sdbになっていました。
shell # update-grub shell # cat /boot/grub/device.map (hd0) /dev/sdb shell # grub-install /dev/sdb
上のようにインストールすると、GRUB Legacyの設定が完了します。
Mac mini初期設定
研究室で新たなクライアントマシンとしてMac miniを購入しました。初MacOSX(Tiger)になります。
クライアント兼計算マシンとして利用する予定です。設定とソフトウェアについてまとめてみます。Beginning OS Xを参考にしました。
- X11の導入
- Xcodeの導入
- Carbon Emacsの導入
- MacPortsの導入
あとはmigemoがほしいですね。
Terminal.appの設定
Debianにログインした際にBack Spaceが効かなくなりました。まあよくあることです。ググってみると、Back Spaceキーで'^H'を送出させた上で
$ stty erase '^H'
で解決する、というのが多かったです。しかしながら、screenのセッションを切り替える中で'^H'と'^?'を切り替えるのは難しいです。そもそも、Terminal.app自体はBSで'^?'を出しています。どうやらTERM=xterm-colorがTerminal.appとはあっていないということのようなので、TERMをいじることで解決することにしました。
$ echo "export TERM=xterm" >> $HOME/.bash_profile