Haskellの型推論でハマった話
久しぶりにHaskellで遊んでたらハマったのでメモ。
100の階乗 100!=1*2*...*100
の桁数を求めるプログラムを書いた。
main = print $ kaijo 100 kaijo n = length $ show $ product [1..n] -- 158が表示される。
上記のプログラムは正しい値(158)を返すが、下記のように型を明示すると、誤った値(0)を返す。
main = print $ kaijo 100 kaijo :: Int -> Int kaijo n = length $ show $ product [1..n] -- 0が表示される。なんでや!!
ちなみに100ではなく10の階乗なら、どちらのプログラムも正しい結果を返す。
この不条理の原因は、Intを明示するとproduct
関数の計算がIntで実行されて、
100の階乗という大きな値が桁溢れを起こすせいだと思われる。
Intを明示しなければ、自動で多倍長計算してくれる。
「100を158にする関数」なのに、Int -> Int
とするとバグっちゃう。こわいこわい。
zshのプロンプトを256色にする方法
zshから256色を使う詳細については、以下のサイトの情熱がものすごい。 http://misc.flogisoft.com/bash/tip_colors_and_formatting
しかし肝心のプロンプトの設定方法が載ってなかったので、ここにメモしておこう。
~/.zshrc
で以下のように記述する。
# 例1 # 注意! ^[ は特殊文字。Vim上で Ctrl+Vした後にESCを押せば入力できる。 # 赤(001番)文字+デフォルト背景 PROMPT="%{^[[38;5;001m%}RED%{^[[0m%}"
# 例2 # デフォルト文字色+緑(082番)背景 PROMPT="%{^[[30;48;5;082m%}Green Background%{^[[0m%}"
# 例3 # 赤(001番)文字+緑(082番)背景 PROMPT="%{^[[30;48;5;082m%}%{^[[38;5;001m%}Red on Green Background%{^[[0m%}"
# 例4 # 以下のように文字色を定義しておくと便利 COLOR_FG="%{^[[38;5;001m%}" # 表を赤に COLOR_BG="%{^[[30;48;5;082m%}" # 背景を緑に COLOR_END="%{^[[0m%}" # 色を元に戻す PROMPT="${COLOR_BG}${COLOR_FG}Red on Green Backgroun${COLOR_END}"
ちなみに zshのプロンプトカラーを設定を変更してみた - HAM MEDIA MEMO に書いてある形式
PROMPT=$'%{\e[38;5;46m%}%m%(!.#.$)%{\e[m%} '
ではうまくいかなかった。
シェルスクリプトの平文パスワードをセキュアにする方法(続き)
この記事は、一年前に書いた シェルスクリプトの平文パスワードをセキュアにする方法 という記事の続きです。 なぜか今頃になって大量のはてブが付き、戦慄している次第です。 ブックマーカーのコメントには
といった指摘が並んでいました。せっかくなので、少し補足します。
chmod 700 の平文パスワードファイルを読み込むのと大差なくね。
確かにその通りですね。 暗号化したパスワードファイルが盗まれる状況では、sshの秘密鍵も一緒に盗まれそうです。 そう考えると、平文のパスワードを外部ファイルに保存してパーミションを700に設定するのと、本質的に同程度のセキュリティしか担保されていません。
この問題を解決するのは簡単です。
ssh-keygen
で秘密鍵を作成する際にパスワードを設定すればよろしい*1。
こうしておけば、もし秘密鍵と暗号化したパスワードファイルの両方が盗まれたとしても、秘密鍵のパスワードが破られない限り複合できません。
もう少し具体的に書くと、まず
$ ssh-keygen -f pasu_tuki_rsa Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): # パスワードを入力 Enter same passphrase again: # パスワードを再入力 Your identification has been saved in pasu_tuki_rsa. Your public key has been saved in pasu_tuki_rsa.pub. The key fingerprint is: ...
としてpasu_tuki_rsa
というパスワード付きの秘密鍵を作成します。
後は前回の記事に書いたのと同じ手順で暗号化や複合が可能ですが、その時にpasu_tuki_rsa
のパスワードを問われます*2。
秘密鍵を使う方法は環境固定なのがイヤ。
この問題については、パスワードファイル専用のssh秘密鍵を作ることで解決します。
パスワードファイルと(パスワード付きの)ssh秘密鍵をペアで管理する訳ですが、このペアは環境に依存しないので、各環境に配布することが可能です。
便利な使い方としては、例えばcron
とrsync
でパスワードファイルを各環境に同期すれば、Dropbox + KeePassのコマンドライン版を手軽に実装できます*3。
GitHub でシェルスクリプト共有するときに便利そう。
まさにそういう目的で前回の記事を執筆しました。 他人とシェルスクリプトを共有する際、スクリプトに自分専用の平文パスワードをべた書きするのは論外です。 対策として、パスワードを外部に保存してスクリプトから読みこめば、スクリプトを共有できると考えました。 しかし外部に平文のパスワードファイルを置くのも気持ち悪いと思い至り、前回記事の着想を得ました。
まとめ
要点は以下に集約されます。
- opensslを使うことで、パスワードファイルのセキュリティコストをsshの秘密鍵に負わせることが可能。
- sshの秘密鍵にはパスワードが設定できる。
- opensslは大抵の環境に入っているので、ソフトのインストールが制限されている環境でも使用可能。
こういう特性をうまく使って、各人にあった運用方法を探してね~
UNIXの設定ファイル中の平文パスワードを暗号化してセキュアにする方法
UNIX系の設定ファイルの中にパスワードを書くのは、あまりにインセキュアで躊躇われる。
たとえばCUIメーラーの雄 mutt で Gmail を使う場合、~/.muttrc
に
# ~/.muttrc for Gmail set imap_user = "YOUR.EMAIL@gmail.com" set imap_pass = "パスワード" set smtp_url = "smtp://YOUR.EMAIL@smtp.gmail.com:587/" set smtp_pass = "パスワード"
といった具合にパスワードを書く必要がある。
参考:
brew - mutt + Gmailを使ってCUIでのメール環境を作る - Qiita
いくらなんでもセキュリティ的にアレすぎるので、平文のパスワードを暗号化してセキュアにしよう。
大抵のUNIXの設定ファイルには、外部ファイルを読み込む source
コマンドが実装されている (source
できない設定ファイルはクソすぎる)。従って
- 設定ファイルのパスワード部分を、外部ファイルの
plain.txt
に分離 plain.txt
を暗号化してpass.rsa
にする- アプリケーションの起動時に
pass.rsa
を復号化しつつ、元の設定ファイルにsource
する
という手続きを踏むことになる。
.muttrc
を例に順番に説明しよう。
1. パスワード部分を plain.txt
に分離
set imap_pass = "パスワード" set smtp_pass = "パスワード"
を外部のplain.txt
に保存する。
2. plain.txt
を暗号化して pass.rsa
にする
次に plain.txt
を暗号化する。
こういう場合には openssl
を使うのが便利だ。
その辺の詳しい事情は以前の記事にまとめてある。
暗号化のやり方だけを抜粋すると、コマンドラインで以下のコマンドを叩けばよい。
# plain.txt というテキストファイルを暗号化して pass.rsa に書き込むコマンド $ openssl rsautl -encrypt -inkey ~/.ssh/id_rsa -in plain.txt > pass.rsa
これでpass.rsa
が作成されるはずだ。
もしエラーが出た場合には、ssh-keygen
すれば多分解決する。
詳しい話はシェルスクリプトの平文パスワードをセキュアにする方法 - 余白の書きなぐりを参照。
3 pass.rsa
を復号化しつつ、元の設定ファイルにsource
する
最後に pass.rsa
を復号化して、.muttrc
に読み込む作業が残っている。
これは .muttrc
を以下のように書き換えることで実現できる。
# ~/.muttrc for Gmail set imap_user = "YOUR.EMAIL@gmail.com" set smtp_url = "smtp://YOUR.EMAIL@smtp.gmail.com:587/" source "openssl rsautl -decrypt -inkey ~/.ssh/id_rsa -in pass.rsa |"
source
の使用は設定ファイルによってマチマチなので個別に対応せねばならないが、
多くの場合は上記のように source "openssl ... |"
で正しく動くと思う。
さくらVPSのUbuntu14.04LTS にRLogin でX11ログインする方法
ローカルのWindows7にXmingをインストール
フリーのWindows用Xサーバー「Xming」のインストールと基本設定、使い方 や XmingによるX Window利用 に書かれているのと同じようにインストールする。 Putty をインストールする必要はない。
ローカルのWindows7でXmingを起動
C:\Program Files (x86)\Xming\Xming.exe
で起動する。設定は
C:\Program Files (x86)\Xming\XLaunch.exe
で変更可能。
画面サイズは XLaunch.exe の Additional Parameters for Xming
に -screen 0 1366 1024
などと設定する。
さくらVPSのUbuntuにX11をインストール
$ sudo su
# apt-get install xinit
#
さくらVPSのUbuntuでX11を起動
# startx & # exit $
RLogin のX11ポートフォワードの設定
サーバ---プロトコル---ポートフォワード(P) をクリックして、以下のように設定する。
これで接続すると、X11が使用可能。xev
等のコマンドで使用可能か確認できる。
gnuplotに関する蛇足
さくらVPSのubuntu14.04LTS-server の場合、aptでインストールできるgnuplotはnoxバージョンなので、Xmingで使用するためには
$ sudo apt-get install gnuplot-x11
とする。
RLogin のフォント設定まとめ
RLogin はWindows環境における便利な端末エミュレータだ。 ただ残念なことに、デフォルトのフォントがキモいという問題がある。 そのうえフォントサイズの変更方法がわかりにくいので、まとめておこう。
フォントの種類の変更
半角アルファベットと記号のフォントを変更する場合は以下のようにする。
まず ファイル
-サーバーの接続
-新規or編集
をクリックし、
フォント
タブを選択する。
ここで ASCII(ANSI X3.4-19...
をダブルクリックして
Font Parameter
ウィンドウを開けて、
Font
ボタンをクリックする。
Font
ボタンをクリックすれば、好きなフォントを指定できるが、
注意点として、この画面ではフォントサイズが変更できない!!
フォントのサイズの変更は スクリーン
タブで行う。
フォントのサイズの変更
ファイル
-サーバーの接続
-新規or編集
をクリックし、
スクリーン
タブを選択する。
フォントサイズから一行あたりの文字数を決定
を選択し、その隣の数値 (上の画像では 20) を変えれば
フォントサイズが変更される。20以上の値も入力可能。
参考サイト:
RLogin 端末の16色カラーがキモいのを直す方法
Windows で ssh サーバーにログインしたい時には、 Putty や TeraTerm といった 端末エミュレータを用いるのが一般的だが、 僕は RLogin という端末を常用している。 RLogin は Sixel が使えるなど様々な点で先進的で使いやすいのだが、使用者をあまり見かけないのはなぜだろうか。
そんなハッピーな RLogin の抱える問題点として デフォルトの16色カラーがキモい ことが挙げられる。 なんというか視認性が悪い気がする。 他にも初期設定のフォントやフォントサイズが不満であるものの、 とりあえず今回は色設定を見直そう。
色設定を変更するには、
ファイル
-サーバーの接続
-新規or編集
をクリックし、カラー
タブを選択する。
端末を黒背景 + 白文字にするには、
- 文字カラーの文字色を 15
- 文字カラーの背景色を 0
にすればよい。
メジャーな端末の色を再現する
やや趣味的な話題だが、RLoginでメジャーな端末の色を再現してみる。
一例として軽量端末の urxvt の色を真似しよう。
やり方は、まず先ほどのカラータブ上部の四角い色見本(黒、赤、緑、、、)
を順にクリックして 色の作成
を選ぶ。
そして以下のように RGB の数値を指定すればよい。
urxvt 以外にもメジャーな端末はたくさんある。色設定をまとめておく。
urxvt
上の画像中に記載した urxvt のデフォルトの色設定を再掲する。 urxvtは Unix-like な環境の端末の中で最も軽い(と思う)のでおすすめ。
一段目 ---: R G B 0 : 0 0 0 1 : 205 0 0 2 : 0 205 0 3 : 205 205 0 4 : 0 0 205 5 : 205 0 205 6 : 0 205 205 7 : 250 235 215 ニ段目 ---: R G B 8 : 64 64 64 9 : 255 0 0 10 : 0 255 0 11 : 255 255 0 12 : 0 0 255 13 : 255 0 255 14 : 0 255 255 15 : 255 255 255
Gnome Terminal
Linux Mint や Ubuntu の標準的端末。 色は urxvt とほぼ同じ。
一段目 ---: R G B 0 : 0 0 0 1 : 170 0 0 2 : 0 170 0 3 : 170 85 0 4 : 0 0 170 5 : 170 0 170 6 : 0 170 170 7 : 170 170 170 ニ段目 ---: R G B 8 : 85 85 85 9 : 255 85 85 10 : 85 255 85 11 : 255 255 85 12 : 85 85 255 13 : 255 85 255 14 : 85 255 255 15 : 255 255 255
xterm
一段目 ---: R G B 0 : 46 52 54 1 : 204 0 0 2 : 78 154 6 3 : 196 160 0 4 : 52 101 164 5 : 117 80 123 6 : 6 152 154 7 : 211 215 207 ニ段目 ---: R G B 8 : 85 87 83 9 : 239 41 41 10 : 138 226 52 11 : 252 233 79 12 : 114 159 207 13 : 173 127 168 14 : 52 226 226 15 : 238 238 236
KDE Konsole
一段目 ---: R G B 0 : 0 0 0 1 : 178 24 24 2 : 24 178 24 3 : 178 104 24 4 : 24 24 178 5 : 178 24 178 6 : 24 178 178 7 : 178 178 178 ニ段目 ---: R G B 8 : 104 104 104 9 : 255 84 84 10 : 84 255 84 11 : 255 255 84 12 : 84 84 255 13 : 255 84 255 14 : 84 255 255 15 : 255 255 255