カテゴリー別アーカイブ: セキュリティ

Google認証システムに端末を追加した

最近新しいスマートフォンを購入しました。モバイル回線としてIIJmioのファミリーシェアプランを契約しているので、SIMは3枚あります。USBドングル用に使っているSIMをとりあえず差し替えて使ってみることにしました。

自分のスマートフォン利用の一つにGoogle Authenticator(Google認証システム)があります。これは外部のWebサービス(github等)での2要素認証に利用できます。RFC 6238に準拠しているサービスであれば何でも利用できるようです。

自分のスマホ運用は基本2台(音声通話用・データ通信用)なのですが、この機会に2台でGoogle Authenticatorを使いたいため、別途端末を追加する方法を探したのですが、「あとからの追加」というのはできないようです。新規登録であれば同時に複数台登録は可能なようなので、以下の手順をとりました。

  • github側の2段階認証停止
    • personal settings ->security
    • 念の為recovery codesを記録しておく
    • Two-factor authenticationをOffにする
  • 旧端末側がらgithubの認証情報を削除
  • github上で再度2段階認証を有効化する
  • 画面に表示されたQRコードを新旧端末で確認、登録
  • 同程度のタイミングで両端末にgithub上の認証コードを入力
    • 時間切れに注意。切れそうになったら次のコードが出るまで待つ
  • 完了

基本的に常に身に着けているデバイスではありますが、これ以外にも重要なデータ(Chromeのパスワードマネージャー情報など)が入っているものですから紛失などには気をつけましょう。

なお、新しく購入したデバイスはnextbitのrobinです。+Styleで購入しました。

Rowhammer問題私的まとめ

確認できた範囲の情報を記録しておこうと思います。

Rowhammer問題

PC Watchの記事「DRAMスケーリングの課題と打開策」にて解説がなされています。以下当該記事より引用:

Row Hammer問題は、DRAM技術が微細化したことで深刻になり始めたメモリセル間の干渉によって発生するエラーの問題だ。 DRAMメモリセルの同じRow(行)に対する連続したアクセスが、隣接したRowのセルのデータを不安定し、エラーを生じさせる。この問題は2012年頃から話題になり始めた。Intelはメモリ制御に関する特許(Row hammer condition monitoring, US 20140006704 A1など)の中で言及した。そして、今年(2014年)6月のコンピュータアーキテクチャ学会「ISCA (International Symposium on Computer Architecture)」でRow Hammerに関する論文が発表されたことで、コンピュータ業界で広く知られるようになった。

ハードウェアについてあまり詳しくないのですが、高密度化、高速化したメモリで、特定のセル(row)に高い頻度でアクセスすると隣接するrowのメモリ内容が化ける、という現象のようです(Rowhammerの論文PDF)。

攻撃への応用

Googleのセキュリティ対策チーム”Project Zero”が、この現象を応用して攻撃に利用する、という記事を公開しました(“Exploiting the DRAM rowhammer bug to gain kernel privileges“)。応用例として、ChromeのNaClサンドボックス上で本来実行できないはずの命令を実行させたり、カーネルの権限上昇を行う手法が解説されています。

確認手段

userlandで試験を行うツールがgithubで公開されています(“https://github.com/google/rowhammer-test“)。また、memtest86 6.0.0 Free editionにもRowhammerテスト機能が追加されているようです。 rowhammer_testを実行して、実際にエラーが起きると以下のような出力をして停止します。

Iteration 11 (after 16.41s)
  32.448 nanosec per iteration: 1.40176 sec for 43200000 iterations
check
error at 0x7f032bcde188: got 0xffffffffffdfffff
  (check took 0.122344s)
** exited with status 256 (0x100)

自分はデスクトップ(non-ECC)x2、ノート(non-ECC)x1、サーバー(ECC)x1に対して実施してみましたが、以前から挙動が若干怪しげなデスクトップマシン1台でのみ検出されました。 Google Groupsにてある程度報告が上がってきていますが、発生するときは数十~数百程度の試行回数で発生するようです(上記自分の例では11回目で発生)。自分の他のマシンでは1万以上行っても問題が出ませんでした。 自分はVirtualBox環境下でこのテストに引っかかったのですが、GroupsではXen guest上でエラーを検出できたという報告もありました。Cygwinでも確認できるよそうです。

対処方法

2ちゃんねるソフトウェア板のMemtest86スレッドにてメモリアクセスに関するパラメータを試行錯誤している様子があります。

>スケーリングによってDRAMが直面する問題として
>「Refresh」、「Write Recovery Time (tWR)」、「Variable Retention Time (VRT)」の3つを挙げている。

tREFIとtREFIx9, tRFCだけでなくtWRも関係してくるわけか・・・

BIOS等でこれらのパラメータを変える、特にリフレッシュ時間(tREFI)を短くすることで改善が見込めるようです。

ところで、ちょうど今日のタイミングで2chのdatアクセスが閉じられてしまいました(窓の杜の記事:「2ちゃんねる”の配信仕様が本日より変更。専用ブラウザーの更新・乗り換えを」)。そのままでは、Debianパッケージにもなっているnavi2chJDなどが利用できない状態です。Memtest86スレッドのような貴重な情報を得られる場だけに残念です。

追記(2015/3/16)

マシンを再起動する機会があったので、tREFIを設定してみました。設定可能な最小値として800(usec?)に設定したところ、iteratin 3000を超えて問題なくテストが進んでいます(当該マシンのデフォルト値は1700ぐらい)。前回は11回でエラーが発生したことを考えると、かなり改善されているようです。割と思い処理(動画エンコード)を差せているのですが、それほど目立った性能低下も感じられません。

CVE-2008-0166の爪痕

偶然にも500万個のSSH公開鍵を手に入れた俺たちはという資料が公開されました。GitHubから公開鍵を大量に集めて調査してみたという内容なのですが、なかなか衝撃的だったので英語blogで内容をかいつまんで紹介してみました。

500万個のssh公開鍵のうち、Debian/Ubuntuで作成されたブラックリスト入りの鍵が208件あったそうです。割合として考えてみればそれほど多くはないのですが、まだ爪痕が残っていることを実感します。

SSLv3の脆弱性(POODLE)対応

SSL 3.0に、プロトコル自体の脆弱性がGoogleによって発見されました。”Paddning Oracle On Downgrade Legacy Encryption”略してPOODLEと呼ばれています。

検証サイト https://www.poodletest.com/ が立ち上がっており、脆弱性の詳細に関する元ソースへのリンクもあります。

今回の脆弱性はサーバー、クライアントともに対策が必要になります。とり急ぎ自分の周りにあるSSL/TLSを使うサービスに対策を施しました。

Apache+mod_ssl

SSL_Engine onとしているセクション内で、以下の設定をしました。

SSLProtocol all -SSLv2 -SSLv3
SSLHonorCipherOrder on
SSLCipherSuite "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"

SSL 2.0, 3.0を無効にし、利用可能な暗号からMD5,  3DES等を外しています(参考: httpsだからというだけで安全?調べたら怖くなってきたSSLの話!?)。

Postfix

smtpd_use_tls=yes
smtpd_tls_mandatory_protocols = !SSLv3, !SSLv2
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5, RC4

参考: Postfix TLS Support

Courier-imapd

##NAME: TLS_PROTOCOL:0
#
# TLS_PROTOCOL sets the protocol version.  The possible versions are:
#
# OpenSSL:
#
# SSL3 - SSLv3
# SSL23 - either SSLv2 or SSLv3 (also TLS1, it seems)
# TLS1 - TLS1
#
# Note that this setting, with OpenSSL, is modified by the TLS_CIPHER_LIST
# setting, below.
#
# GnuTLS:
#
# SSL3   - SSLv3
# TLS1   - TLS 1.0
# TLS1_1 - TLS 1.1
#
# When compiled against GnuTLS, multiple protocols can be selected as follows:
#
# TLS_PROTOCOL="TLS1_1:TLS1:SSL3"
#
# DEFAULT VALUES:
#
# SSL23 (OpenSSL), or "TLS_1:TLS1:SSL3" (GnuTLS)
TLS_PROTOCOL="TLS1"

Debianのcourier-imapdはOpenSSLをリンクしているのでTLS1のみ設定しています。

確認方法

OpenSSLのs_clientを利用することで、任意のバージョンのSSL/TLSを使った接続を試すことができます。

$ openssl s_client -connect target.server.example.jp:443 -ssl3
(略)
SSL handshake has read 2844 bytes and written 289 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-AES256-SHA
(略)
$ openssl s_client -connect example.jp:443 -ssl3 -cipher `openssl ciphers RC4`
(略)
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-RC4-SHA

上記サンプルでは、1回目はSSLv3, AESでの接続、2回目はSSLv3, RC4での接続ができています(参考: 私が愛した openssl (SSL/TLS 編))。設定が正しくできれば、以下のような結果となりネゴシエーションに失敗します。

SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : SSLv3
    Cipher    : 0000

STARTTLSを使う場合は-starttlsオプションが利用できます。

$ openssl s_client -connect example.jp:587 -ssl3 -cipher `openssl ciphers RC4` -starttls smtp
(略)
SSL handshake has read 2128 bytes and written 264 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: zlib compression
Expansion: zlib compression
SSL-Session:
    Protocol  : SSLv3
    Cipher    : ECDHE-RSA-RC4-SHA

Debianでの対応状況(2014/10/16朝頃)

caffから受け取った署名を自分の鍵へ取り込む(gpg import)

ずいぶん間が開いてしまいましたが、GnuPG key signの作業をする(signing-party/caff)の続きです。前回は自分が相手に対して署名を行い、その結果を送るための手続きについて説明しました。今回はその逆、自分が受け取った相手からの署名を自分の鍵に追加する方法について説明します。

メールをファイルに保存

相手がcaffを使っている場合、pgp鍵のおそらくは各IDごとに1通のメールが届きます。

pub   4096R/9C0C1404 2009-09-11
                 指紋 = 9945 2B4D D28B EEAC 8AB5  C931 B066 62EC 9C0C 1404
uid                  NOKUBI Takatsugu <knok@daionet.gr.jp>
uid                  NOKUBI Takatsugu <knok@debian.org>
uid                  NOKUBI Takatsugu <knok@namazu.org>
uid                  NOKUBI Takatsugu <knok@fsij.org>
sub   4096R/07098680 2009-09-11
sub   2048R/861243E1 2012-08-23

私の鍵の場合だと、IDとしているメールアドレスは4つあるので、一人当たり4通メールが送られてきます。それらを1つづつファイルとして保存します。

メールの内容は、それぞれのIDに対応する、自身の公開鍵で暗号化されたpgp asciiメッセージです。

Subject: Your signed PGP key 0xB06662EC9C0C1404
Content-Transfer-Encoding: 7bit
Content-Type: multipart/encrypted;
 protocol="application/pgp-encrypted";
 boundary="----------=_1409005317-7907-1"
User-Agent: caff 0.0.0.638 - http://pgp-tools.alioth.debian.org/
To: knok@daionet.gr.jp
From: "Sender" <user@example.jp>
X-Mailer: MIME-tools 5.505 (Entity 5.505)
MIME-Version: 1.0
Message-Id: <20140825222158.8DAC3399@example.jp>
Date: Tue, 26 Aug 2014 07:21:58 +0900 (JST)

This is a multi-part message in MIME format...

------------=_1409005317-7907-1
Content-Type: application/pgp-encrypted; name="signedkey.msg"
Content-Disposition: attachment; filename="signedkey.msg"
Content-Transfer-Encoding: 7bit

Version: 1

------------=_1409005317-7907-1
Content-Type: application/octet-stream; name="msg.asc"
Content-Disposition: inline; filename="msg.asc"
Content-Transfer-Encoding: 7bit

-----BEGIN PGP MESSAGE-----
Version: GnuPG v1

hQIMA8hTZXMHCYaAAQ//XfTpsTvsdKaLNZ2TkYf/lDRtHo9DRjtSiFSYT4lWcFwF
9yxFzX8TL/L+7o2xZTZ7nXTOHAIMkgxi5KXnIDY5O8iNvrN9pqh3VmKDhB2GWHRD
yJGIBiQZ+bPavFWgiscWhy7FqhWfGi7XHBEbEIhfn9FBrziwgvLwkkC24ufUtnOM
/u39RDXrJKpi0GT0rMW+Ykg9vs6QNSdyDeBQRRS16KTRyljSGmRX/Q3y57WVw09v
(以下略)

メールの復号化

このメールをpgpコマンドで復号化します。

$ gpg -o msg mail.eml

次のユーザーの秘密鍵のロックを解除するには
パスフレーズがいります:“NOKUBI Takatsugu <knok@daionet.gr.jp>”
4096ビットRSA鍵, ID 07098680作成日付は2009-09-11 (主鍵ID 9C0C1404)
gpg: このセッションでgpg-agentは無効です
パスフレーズを入力:

gpg: 4096-ビットRSA鍵, ID xxxxxxx, 日付2009-06-19に暗号化されました
      “Sender <sender@example.jp>”
gpg: 4096-ビットRSA鍵, ID 07098680, 日付2009-09-11に暗号化されました
      “NOKUBI Takatsugu <knok@daionet.gr.jp>”

上記コマンド例では、入力されたファイルをmsgというファイル名で復号化しています。復号化した内容は、caffの標準テンプレートであれば以下のようになります。

MIME-Version: 1.0
X-Mailer: MIME-tools 5.505 (Entity 5.505)
Content-Type: multipart/mixed; boundary="----------=_1409005317-7907-0"

This is a multi-part message in MIME format...

------------=_1409005317-7907-0
Content-Type: text/plain; charset="utf-8"
Content-Disposition: inline
Content-Transfer-Encoding: binary

Hi,

please find attached the user id
        NOKUBI Takatsugu <knok@daionet.gr.jp>
of your key B06662EC9C0C1404 signed by me.

If you have multiple user ids, I sent the signature for each user id
separately to that user id's associated email address. You can import
the signatures by running each through `gpg --import`.

Note that I did not upload your key to any keyservers. If you want this
new signature to be available to others, please upload it yourself.
Note that I did not upload your key to any keyservers. If you want this
new signature to be available to others, please upload it yourself.
With GnuPG this can be done using
        gpg --keyserver subkeys.pgp.net --send-key B06662EC9C0C1404

If you have any questions, don't hesitate to ask.

Regards,
Sender

------------=_1409005317-7907-0
Content-Type: application/pgp-keys;
 name="0xB06662EC9C0C1404.1.signed-by-0x2E8162547E37CE41.asc"
Content-Disposition: attachment;
 filename="0xB06662EC9C0C1404.1.signed-by-0x2E8162547E37CE41.asc"
Content-Transfer-Encoding: 7bit
Content-Description: PGP Key 0xB06662EC9C0C1404, uid NOKUBI Takatsugu
 <knok@daionet.gr.jp> (1), signed by 0x2E8162547E37CE41

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1

mQINBEqq3iEBEAC2u1/t+pm5FSK//w9Qp/KxHW17rM+tOxqBNqVAZbFpOFu9Sa1i
U/C85ujEHKRIuLyESfzLg3gQmeojTritYPzG04s+bP+bbjujMkZZGhbrl4VjWA0L
DLO7uxwS/4scnBrlOONPaeRfP43T8a1hK2E0+8uIGhJIUt5fyW0o7Cs1MvL6T7UZ
YEwUW9lqciFhYEXr2zC6JYuofLytG1nUUFY4gcLWX/XSi1NUutL7Z5uJK3Ct8nlc
2AxFmPWkTYOcU6HpePQLlB7YGdldS8+41QkeDJm+w+ljqfI1vrVFT+SIHza8RiuW
(以下略)

署名の取り込み

この復号化されたファイルには、添付ファイルとして鍵への署名があります。本文中にも説明がありますが、gpg –importコマンドを実行することで署名を自分の鍵に取り込むことができます。

$  gpg --import msg
gpg: 鍵9C0C1404:“NOKUBI Takatsugu <knok@daionet.gr.jp>”新しい署名を1個
gpg:     処理数の合計: 1
gpg:       新しい署名: 1
gpg: 最小の「ある程度の信用」3、最小の「全面的信用」1、classic信用モデル
gpg: 深さ: 0  有効性:   3  署名: 127  信用: 0-, 0q, 0n, 0m, 0f, 3u
gpg: 深さ: 1  有効性: 127  署名:  33  信用: 126-, 0q, 0n, 0m, 1f, 0u
gpg: 次回の信用データベース検査は、2016-07-04です

これを、届いたメールの数だけ実施します。さすがに毎回passphreaseを入力するのはしんどいので、gpg-agent等を使うと楽になります。gpg-agentはバージョン2系からついてきます。1.4系にはありません。エージェントの使い方はssh-agentとよく似ているので、そちらに慣れている人であれば楽に使えるでしょう。

私は以下のようなワンライナーで一括処理をするようにしています。

for i in *.eml; do gpg --yes -o msg $i ; gpg --import msg; done

公開キーサーバー上の鍵の更新

最後に、公開キーサーバーへ新しい(電子署名の増えた)鍵を送信して更新します。これは普段から公開キーサーバーに鍵を登録している人だけがすればよい作業なので、運用によっては不要な作業です。

$ gpg --keyserver pgp.nic.ad.jp --send-keys 9C0C1404
gpg: 鍵9C0C1404をhkpサーバーpgp.nic.ad.jpへ送信
$ gpg --keyserver keyring.debian.org --send-keys 9C0C1404
gpg: 鍵9C0C1404をhkpサーバーkeyring.debian.orgへ送信

以上で作業は終わりです。

GnuPG key signの作業をする(signing-party/caff)

先日JNUGの総会へ行ってきて、OpenPGPの鍵の本人確認をしてきました。その後にやるべき作業を、忘備録として記しておきます。

key signの作業を楽にするためのツールはいろいろありますが、今回はsigning-partyパッケージに含まれるcaffを使います。

Package: signing-party
Version: 1.1.4-1
Maintainer: Thijs Kinkhorst 
Description-ja: 各種 OpenPGP 関連ツール
 signing-party はあらゆる種類の PGP/GnuPG 関連ツール集で、キーサイン、
 キーリングの分析、キーサインパーティの準備用ツールを含んでいます。
 .
  * caff: "CA - Fire and Forget" 鍵にサインしてメールを送信します
  * pgp-clean: 自己署名以外の全署名を鍵から削除します
  * pgp-fixkey: 鍵から破損したパケットを除去します
  * gpg-mailkeys: サイン済みの鍵をその所有者へ単純にメール送信します
  * gpg-key2ps: 指紋を短冊にした PostScript ファイルを生成します
  * gpgdir: 再帰的にディレクトリを暗号化するツールです
  * gpglist: あなたの UID にサインした人を表示します
  * gpgsigs: GnuPG 鍵の一覧に対してサイン済みの鍵に注釈を付けます
  * gpgparticipants: パーティ参加者の一覧を主催者向けに作成します
  * gpgwrap: パスフレーズ用ラッパーです
  * keyanalyze: キーリングの minimum signing distance (MSD) を分析します
  * keylookup: gpg --search の ncurses ラッパーです
  * sig2dot: GnuPG 署名の一覧を .dot ファイルに変換します
  * springgraph: .dot ファイルからグラフを作成します
Homepage: http://pgp-tools.alioth.debian.org/

pkgsrcにはcaff単独でsecurity/caffがあるので、そちらを使いましょう(実際にはsigning-partyのtar ballを取得します)。

まず、ID確認の完了したユーザーの公開鍵を入手します。公開キーサーバーに登録されていることもありますし、人によっては公開していない場合もあります。後者の場合はメールなどで直接受け取ってください。キーサーバーから取得する方法は以下のようになります。

$ gpg --keyserver pgp.nic.ad.jp --recv-keys "keyid"
gpg: 鍵xxxxxxxxをhkpからサーバーpgp.nic.ad.jpに要求
gpg: 鍵xxxxxxxx: 公開鍵“User Name <user@example.com>"を読み込みました
gpg: 最小の「ある程度の信用」3、最小の「全面的信用」1、classic信用モデル
gpg: 深さ: 0  有効性:   3  署名: 127  信用: 0-, 0q, 0n, 0m, 0f, 3u
gpg: 深さ: 1  有効性: 127  署名:  33  信用: 126-, 0q, 0n, 0m, 1f, 0u
gpg: 次回の信用データベース検査は、2016-07-04です
gpg:     処理数の合計: 1
gpg:           読込み: 1  (RSA: 1)

今回はpgp.nic.ad.jpを使いましたが、他のキーサーバー(pgp.mit.edu)等にあることもあります。

公開鍵を入手したら、手元にあるはずの指紋(fingerprint)と、取得した公開鍵の指紋が一致するか確認しましょう。

$ gpg --fingerprint 9C0C1404
pub   4096R/9C0C1404 2009-09-11
                 指紋 = 9945 2B4D D28B EEAC 8AB5  C931 B066 62EC 9C0C 1404
uid                  NOKUBI Takatsugu <knok@daionet.gr.jp>
uid                  NOKUBI Takatsugu <knok@debian.org>
uid                  NOKUBI Takatsugu <knok@namazu.org>
uid                  NOKUBI Takatsugu <knok@fsij.org>
sub   4096R/07098680 2009-09-11
sub   2048R/861243E1 2012-08-23

これを、ID確認したユーザーの数だけ実施します。確認ができたら、ようやくcaffの出番です。

$HOME/.caffrc を作成します。caff –help等を実行すれば、現在の環境を見てとりえあずデフォルトの値を埋めたものが自動生成されます。作成されたものを自分の環境に合わせて修正してください。以下は私の設定例です。

# .caffrc -- vim:ft=perl:
# This file is in perl(1) format - see caff(1) for details.

$ENV{'MAILADDRESS'} = 'knok@daionet.gr.jp';
$CONFIG{'owner'} = 'NOKUBI Takatsugu';
$CONFIG{'email'} = 'knok@daionet.gr.jp';
#$CONFIG{'reply-to'} = 'foo@bla.org';
$CONFIG{'bcc'} = 'nokubi+caff@example.com';

# You can get your long keyid from
#   gpg --with-colons --list-key 
#
# If you have a v4 key, it will simply be the last 16 digits of
# your fingerprint.
#
# Example:
#   $CONFIG{'keyid'} = [ qw{FEDCBA9876543210} ];
#  or, if you have more than one key:
#   $CONFIG{'keyid'} = [ qw{0123456789ABCDEF 89ABCDEF76543210} ];
$CONFIG{'keyid'} = [ qw{B06662EC9C0C1404 ];
# Select this/these keys to sign with
#$CONFIG{'local-user'} = [ qw{2BA82602C2CE8099 ACCBC06B6A2171ED B06662EC9C0C1404} ];

# Additionally encrypt messages for these keyids
#$CONFIG{'also-encrypt-to'} = [ qw{2BA82602C2CE8099 ACCBC06B6A2171ED B06662EC9C0C1404} ];

# Mail template to use for the encrypted part
#$CONFIG{'mail-template'} = << 'EOM';
#Hi,
#
#please find attached the user id{(scalar @uids >= 2 ? 's' : '')}
#{foreach $uid (@uids) {
#    $OUT .= "\t".$uid."\n";
#};}of your key {$key} signed by me.
#
#If you have multiple user ids, I sent the signature for each user id
#separately to that user id's associated email address. You can import
#the signatures by running each through `gpg --import`.
#
#Note that I did not upload your key to any keyservers. If you want this
#new signature to be available to others, please upload it yourself.
#With GnuPG this can be done using
#       gpg --keyserver pool.sks-keyservers.net --send-key {$key}
#
#If you have any questions, don't hesitate to ask.
#
#Regards,
#{$owner}
#EOM
$CONFIG{'mailer-send'} =  [ 'smtp', Server => 'localhost', Port => 10025 ,
        Envelope => 'knok@daionet.gr.jp', Debug => 1 ];

自分はカスタマイズしたsmtp設定をしています。mailer-sendについてはcaff(1)に解説がありますが、PerlのMail::Mailerが受け付けるパラメータを記述します。man Mail::Mailerに詳細がありますが、smtpの代わりにtestfileを指定すれば、メールを送信する代わりにファイルに保存するので、活用して動作確認をするとよいでしょう。

準備ができたら、caffを起動します。私は以下のようなスクリプトを使っています。

#!/bin/sh
caff -m yes -u B06662EC9C0C1404 `cat $1`

B06662EC9C0C1404 は私のlong key idです。出力させるにはgpg –with-colons –fingerprint shortid 等とします。

caffを起動すると、作業ディレクトリを作成した上で指定した公開鍵に署名をしてゆきます。署名の作業にはパスフレーズが必要です。何度も入力することになるので、gpg-agentを使うことをお勧めします。

一通り署名が完了すると、実際のkeyringに結果をコピーした上で、公開鍵のメールアドレス(id)あてに1通づつメールを送信します。同じように、相手もこちらに署名した公開鍵を送ってくるのを待ちましょう

以上が相手の鍵に署名をしてメールで送信する方法です。その結果をキーサーバーに送ることもできますが、相手が常にキーサーバーに後悔しているとは限らないので、その点注意しましょう(既知の公開鍵は誰でもキーサーバーに送信して公開できてしまう)。

逆に、相手から受け取った署名付き鍵の取り込みをする方法はまた別途記事として書く予定です。

NAT(masquerade)のログをとる

最近の社会情勢を鑑みて、知らないうちにマシンや回線が乗っ取られて悪事に使われた時の対策として、NATのログをとるようにしてみました。

自分はDebianマシンをルーターにしているので、iptablesでルールを一つ追加するだけで済みます。

# iptables -I FORWARD -m state --state NEW -j LOG --log-prefix " [>] NEW FORWARD "

FORWARDチェインにstateがNEWなもののみ記録をします。わかりやすいようにprefixを付けています。

しかしこれで十分かというとそうでもないですね。利用しているマシンの裏で悪さされたら通常利用と区別がつかないわけで…ルーター自体が乗っ取られてもアウトです。もうちょっといい方法がないか考えたいところです。

 

Android 2.x向けにL2TP/IPSecサーバ(openswan+xl2tpd)を設定する

前々から設定しかけてはうまくいかなかった、Android向けL2TP/IPSecがようやく動くようになったので、どんな設定をしたかをまとめてみます。対象はDebian squeezeです。

パッケージとして必要になるのは、openswanとxl2tpdです。これらをapt-get installします。

まずopenswanの設定をします。これはIPSecの実装の一つです。もともとFreeS/Wanというプロジェクトがあったのですが、その開発が止まったためforkしてできたのがOpenswanです。ほかにStrongswanという実装もあるようですが、ここでは触れません。

/etc/ipsec.confというファイルが存在しているので、それを編集します。冗長なコメントは消しています。

# /etc/ipsec.conf - Openswan IPsec configuration file
version 2.0     # conforms to second version of ipsec.conf specification

# basic configuration
config setup
        # NAT-TRAVERSAL support, see README.NAT-Traversal
        # exclude networks used on server side by adding %v4:!a.b.c.0/24
        virtual_private=%v4:10.0.0.0/8,%v4:192.168.0.0/16,%v4:172.16.0.0/12
        # OE is now off by default. Uncomment and change to on, to enable.
        oe=off
        # which IPsec stack to use. auto will try netkey, then klips then mast
        #protostack=auto
        protostack=netkey
        nhelpers=0

# Add connections here
include /etc/ipsec.d/*.conf

次に、L2TP向けの設定ファイル/etc/ipsec.d/l2tp-psk.confを新規に作成します。

conn L2TP-PSK-NAT
        rightsubnet=0.0.0.0/0
        also=L2TP-PSK-noNAT

conn L2TP-PSK-noNAT
        authby=secret
        pfs=no
        auto=add
        keyingtries=3
        rekey=no
        ikelifetime=8h
        keylife=1h
        type=transport
        left=%defaultroute
        leftprotoport=17/1701
        right=%any
        rightprotoport=17/%any

次に、/etc/ipsec.secretsを編集します。ハイライトされた行を追加します。your-passwordを自分が設定したいパスワードにしてください。このパスワードがIPSec事前共有鍵になります。

# RCSID $Id: ipsec.secrets.proto,v 1.3.6.1 2005/09/28 13:59:14 paul Exp $
# This file holds shared secrets or RSA private keys for inter-Pluto
# authentication.  See ipsec_pluto(8) manpage, and HTML documentation.

# RSA private key for this host, authenticating it to any other host
# which knows the public part.  Suitable public keys, for ipsec.conf, DNS,
# or configuration of other implementations, can be extracted conveniently
# with "ipsec showhostkey".

#: PSK "1234567890"
: PSK "your-password"

# this file is managed with debconf and will contain the automatically created RSA keys
include /var/lib/openswan/ipsec.secrets.inc

次に、sysctl関連の設定をします。/etc/sysctl.d/for-ipsec.confファイルを作成し、以下のように設定します。自分はすべてのインターフェースに{accept,send}_redirectsを設定しています。各自のインターフェース名に合わせて設定してください。

# forward
net.ipv4.ip_forward=1
# redirect
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.ppp0.accept_redirects = 0
net.ipv4.conf.br0.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.ppp0.send_redirects = 0
net.ipv4.conf.br0.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0

ファイルを作成したら、sysctl -p /etc/sysctl.d/for-ipsec.confを実行してこのsysctl設定を有効化します。リブート時には/etc/init.d/procpsの中でこのファイルが自動的に読まれます。

ここで、一度ipsecを起動してみます。/etc/init.d/ipsec startして、ipsec verifyを実行してみてください。問題なければ以下のような出力が出ます。[NG]という出力があれば、何か設定に失敗していることになります。

Checking your system to see if IPsec got installed and started correctly:
Version check and ipsec on-path                                 [OK]
Linux Openswan U2.6.28/K2.6.38-bpo.2-686-bigmem (netkey)
Checking for IPsec support in kernel                            [OK]
NETKEY detected, testing for disabled ICMP send_redirects       [OK]
NETKEY detected, testing for disabled ICMP accept_redirects     [OK]
Checking that pluto is running                                  [OK]
Pluto listening for IKE on udp 500                              [OK]
Pluto listening for NAT-T on udp 4500                           [OK]
Two or more interfaces found, checking IP forwarding            [OK]
Checking NAT and MASQUERADEing
Checking for 'ip' command                                       [OK]
Checking for 'iptables' command                                 [OK]
Opportunistic Encryption Support                                [DISABLED]

ipsecはデフォルトでは自動起動になっていないので、insserv ipsecを実行して自動起動するようにしてください。

最後は、xl2tpdの設定です。/etc/xl2tp.confを以下のように設定します。

[global] ; Global parameters:
auth file = /etc/xl2tpd/l2tp-secrets ; access control = no
;debug avp = yes
;debug network = yes
;debug packet = yes
;debug state = yes
;debug tunnel = yes
[lns default] ; Our fallthrough LNS definition
name = l2tpd
ip range = 192.168.126.1-192.168.126.20
local ip = 192.168.126.2
require chap = yes  ; * Require CHAP auth. by peer
refuse pap = yes    ; * Refuse PAP authentication
require authentication = yes ; * Require peer to authenticate
ppp debug = yes     ; * Turn on PPP debugging
pppoptfile = /etc/ppp/options.l2tpd.lns ; * ppp options file
length bit = yes

2行目で、ppp認証用のユーザー、パスワードを記述したファイル名を指定します。10,11行目でVPNに振るアドレスを指定します。各自にあったIPアドレスレンジを使ってください。16行目では、xl2tpdが起動するpppdの設定ファイル名を指定しています。うまく動かないときは、各種デバッグオプションを有効にしてみてください。

/etc/xl2tpd/l2tp-secretsは以下のように書きます。user, passwdは適切なものにしてください。

# Secrets for authenticating l2tp tunnels
# us    them    secret
user    *       passwd

/etc/ppp/options.l2tpd.lnsの設定例は以下になります。

ipcp-accept-local
ipcp-accept-remote
require-mschap-v2
noccp
nodefaultroute
auth
#crtscts
idle 1800
mtu 1280
mru 1280
debug
lock
proxyarp
connect-delay 5000
#nobsdcomp
ms-dns 192.168.3.4
netmask 255.255.255.0
logfile /var/log/xl2tpd.log

最初、MTU/MRUのサイズを指定しないで動かしていたら外部との通信がうまくいかなかったので、かなり小さめ(1280)にしています。16行目のネームサーバは適切なものに変更してください。

あとは/etc/init.d/xl2tpd restartを実行して、Android側の設定をしてゆきます。VPNのタイプはL2TP/IPSec PSK、VPNサーバ名とIPSec事前共有鍵(ipsec.secretsの値)を設定します。L2TPセキュリティ保護は無効にします。

あとは接続を実行し、l2tp-secretsに書いたユーザー名、パスワードを入力すれば接続できるはずです。設定がおかしいと、一瞬pppセッションが確立したあとすぐ切られる、というような状況が起きることがあるので気を付けてください。

知人から、これらに関していくつか助言をいただいています。

@ 蛇足情報だけどopenswan ICSで繋がらないとかあるよ http://t.co/TXmfvEKC
@northeye
にゃーすあい

ICSとOpenswanの組み合わせでは動かないことがあるようです。

新しいkernelにはopenl2tpというin-kernel l2tpモジュールがあるそうです。ただし、まだuserlandはDebianパッケージが(sidにも)ありません。

参考:

追記(2012/8/24):

MS-CHAP-v2の脆弱性と攻撃ツールの流通が報告されていますが、pppの設定を見ての通り、L2TP/IPSecでもMS-CHAP-v2を使っています。暗号化されたトンネルの下でpppを確立するため、直ちに危険というわけではありませんが、PSK共有鍵方式だと安全とはいえないようです。

証明書ベースの接続(CRT VPN)の設定を今後は調べてみようと思います。

denyhostsからfail2banへ

sshdに対する攻撃を防ぐ手段として、denyhostsがあります。これは同じIPから連続してアクセスを試み、一定回数失敗するとtcpwrapperの/etc/hosts.denyに対象IPを記述してアクセスできないようにしてくれます。

ただ、今回いくつか環境を変更したので、もっといろいろなアプリケーションに対応させるため、同じようなソフトであるfail2banを利用することにしました。denyhostsはtcpwrapperしか対応できないのに対して、fail2banはそれ以外にも複数(iptables, ipfw等)を利用することができます。新たなルールを追加する事も容易でおすすめです。

今回は、http://blog.somsip.com/2012/02/using-fail2ban-to-protect-wordpress/ を参考にしてWordpressや(使ってないけど)phpMyAdminの対応も入れてみました。

これでしばらく様子を見てみます。