余白の書きなぐり

aueweのブログ

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 の平文パスワードファイルを読み込むのと大差なくね。
  • 秘密鍵を使う方法は環境固定なのがイヤ。
  • GitHubシェルスクリプト共有するときに便利そう。

といった指摘が並んでいました。せっかくなので、少し補足します。

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秘密鍵をペアで管理する訳ですが、このペアは環境に依存しないので、各環境に配布することが可能です。 便利な使い方としては、例えばcronrsyncでパスワードファイルを各環境に同期すれば、Dropbox + KeePassのコマンドライン版を手軽に実装できます*3

GitHubシェルスクリプト共有するときに便利そう。

まさにそういう目的で前回の記事を執筆しました。 他人とシェルスクリプトを共有する際、スクリプトに自分専用の平文パスワードをべた書きするのは論外です。 対策として、パスワードを外部に保存してスクリプトから読みこめば、スクリプトを共有できると考えました。 しかし外部に平文のパスワードファイルを置くのも気持ち悪いと思い至り、前回記事の着想を得ました。

まとめ

要点は以下に集約されます。

  • opensslを使うことで、パスワードファイルのセキュリティコストをssh秘密鍵に負わせることが可能。
  • ssh秘密鍵にはパスワードが設定できる。
  • opensslは大抵の環境に入っているので、ソフトのインストールが制限されている環境でも使用可能。

こういう特性をうまく使って、各人にあった運用方法を探してね~

*1:そもそもsshログイン用の秘密鍵にパスワードを設定しないのは、かなり危険だと思う。もし秘密鍵が漏れた場合、その公開鍵が登録されてる全環境にログインされるので、二次被害が半端ない

*2:パスワードを保存したファイルを開くために、また別のパスワードが必要なのはナンセンスでは?という質問については、「パスワード管理ソフト」でググるのが教育的だと思う

*3:こういう秘密鍵の使い方は、公開鍵暗号システムの本質から外れていると思う。もっと良い方法がないものか

UNIXの設定ファイル中の平文パスワードを暗号化してセキュアにする方法

UNIX系の設定ファイルの中にパスワードを書くのは、あまりにインセキュアで躊躇われる。 たとえばCUIメーラーの雄 muttGmail を使う場合、~/.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 できない設定ファイルはクソすぎる)。従って

  1. 設定ファイルのパスワード部分を、外部ファイルの plain.txt に分離
  2. plain.txt を暗号化して pass.rsa にする
  3. アプリケーションの起動時に 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ログインする方法

ローカルのWindows7Xmingをインストール

フリーのWindows用Xサーバー「Xming」のインストールと基本設定、使い方XmingによるX Window利用 に書かれているのと同じようにインストールする。 Putty をインストールする必要はない。

ローカルのWindows7Xmingを起動

C:\Program Files (x86)\Xming\Xming.exe で起動する。設定は C:\Program Files (x86)\Xming\XLaunch.exe で変更可能。 画面サイズは XLaunch.exe の Additional Parameters for Xming-screen 0 1366 1024 などと設定する。

さくらVPSUbuntuX11をインストール

$ sudo su
# apt-get install xinit

#

さくらVPSUbuntuX11を起動

# startx &
# exit
$

RLogin のX11ポートフォワードの設定

サーバ---プロトコル---ポートフォワード(P) をクリックして、以下のように設定する。

f:id:auewe:20141128230249p:plain

f:id:auewe:20141128222217p:plain

f:id:auewe:20141128222229p:plain

これで接続すると、X11が使用可能。xev 等のコマンドで使用可能か確認できる。

gnuplotに関する蛇足

さくらVPSのubuntu14.04LTS-server の場合、aptでインストールできるgnuplotはnoxバージョンなので、Xmingで使用するためには

$ sudo apt-get install gnuplot-x11

とする。

RLogin のフォント設定まとめ

RLoginWindows環境における便利な端末エミュレータだ。 ただ残念なことに、デフォルトのフォントがキモいという問題がある。 そのうえフォントサイズの変更方法がわかりにくいので、まとめておこう。

フォントの種類の変更

半角アルファベットと記号のフォントを変更する場合は以下のようにする。 まず ファイル-サーバーの接続-新規or編集 をクリックし、 フォントタブを選択する。

f:id:auewe:20140530142920p:plain

ここで ASCII(ANSI X3.4-19... をダブルクリックして Font Parameter ウィンドウを開けて、 Font ボタンをクリックする。

f:id:auewe:20140530143303p:plain

Font ボタンをクリックすれば、好きなフォントを指定できるが、 注意点として、この画面ではフォントサイズが変更できない!! フォントのサイズの変更は スクリーン タブで行う。

フォントのサイズの変更

ファイル-サーバーの接続-新規or編集 をクリックし、 スクリーンタブを選択する。

f:id:auewe:20140530144500p:plain

フォントサイズから一行あたりの文字数を決定 を選択し、その隣の数値 (上の画像では 20) を変えれば フォントサイズが変更される。20以上の値も入力可能。


参考サイト:

RLogin 端末の16色カラーがキモいのを直す方法

Windowsssh サーバーにログインしたい時には、 PuttyTeraTerm といった 端末エミュレータを用いるのが一般的だが、 僕は RLogin という端末を常用している。 RLogin は Sixel が使えるなど様々な点で先進的で使いやすいのだが、使用者をあまり見かけないのはなぜだろうか。

そんなハッピーな RLogin の抱える問題点として デフォルトの16色カラーがキモい ことが挙げられる。 なんというか視認性が悪い気がする。 他にも初期設定のフォントやフォントサイズが不満であるものの、 とりあえず今回は色設定を見直そう。

色設定を変更するには、 ファイル-サーバーの接続-新規or編集 をクリックし、カラー タブを選択する。

f:id:auewe:20140530033532p:plain

端末を黒背景 + 白文字にするには、

  • 文字カラーの文字色を 15
  • 文字カラーの背景色を 0

にすればよい。

メジャーな端末の色を再現する

やや趣味的な話題だが、RLoginでメジャーな端末の色を再現してみる。 一例として軽量端末の urxvt の色を真似しよう。 やり方は、まず先ほどのカラータブ上部の四角い色見本(黒、赤、緑、、、) を順にクリックして 色の作成 を選ぶ。 そして以下のように RGB の数値を指定すればよい。

f:id:auewe:20140530033818p:plain

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 MintUbuntu の標準的端末。 色は 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