security」タグアーカイブ

Yubikey 4 にSSHの秘密鍵を格納する

 

Yubico社のYubikey4は単なるワンタイムパスワード生成器じゃなくて証明書を格納可能になった。SSHの秘密鍵をYubkikeyに入れて、sshでログインするときだけYubikeyをPCに挿せば、秘密鍵をあちこちのPCに保存しておく必要がなくなり安心である。Yubikey4は日本のAmazonでも販売されている(AA)

Yubikey自体に鍵生成機能があるので、そこで秘密鍵と公会議のペアを作っても良いのだが、あちこちのサーバの公開鍵を置き換えるのが面倒なのと、Yubikey内で生成した秘密鍵はセキュリティ上取り出すことができないので、既存の鍵を使いたい。当然鍵は取り出せないのが安全なのだが、万が一Yubikeyごと秘密鍵をなくしてしまったら二度とその鍵でログインできなくなるのが怖いのだ。ちなみに、既存の秘密鍵をYubkikeyに入れたものも取り出せないので、一通り設定が終わったら、あちこちのPCにある秘密鍵を消し去って、信頼できるところにだけ秘密鍵のコピーを持っておくつもり。なんなら秘密鍵を紙に印刷しておくのが一番安全かもしれない。

以上の理由で、既存の秘密鍵をYubikeyに入れるのだが、やり方が簡単ではなかったのでメモっておく。前提として、rsa 2048bitの秘密鍵 id_rsa を格納するとする。

 

鍵の変換

まずは既存の鍵の変換から。sshの鍵生成は普通ssh-keygenで行うと思うのだが、これで作られる秘密鍵と公開鍵はopensshの独自仕様のようなので、まずはPEM形式に変換する。PEMとかDERとかいうのは鍵のエンコーディング形式でPEMは鍵をBASE64でエンコーディングしてあり、DERはバイナリのようだ。opensshはBASE64なのだが、PEMとヘッダーとかが違うそうだ。

opensll rsa -in id_rsa -out ide_rsa.pem -outform pem

これでPEM形式に変換。

次に同じように公開鍵も作る

openssl rsa -in id_rsa.pem -pubout >id_rsa_pub.pem

 

Yubikey4のPINコード等の変更

次にyubico社からダウンロードしたyubico-piv-toolを使う。ただしサンプルのとおりにコマンドを打ってもエラーが出る(Windows)ので多少工夫が必要。まずは、yukbikeyをUSBに差し込んで、まずはPINコード、PUKコード(管理者用)、マネジメントキーを変更する。

まずマネジメントキーを登録する。

yubico-piv-tool -a set-mgm-key -n (16進数48文字)

すでにマネジメントキーが登録されている場合は、-kオプションのあとに既存のキーを書く。不思議なのは、-kオプションの後にスペースをおいてキーを指定してもうまく動かない。オプションの後のスペースはあってもなくてもいいのだが、kオプションだけはなぜかスペースがあるとうまく動かない。

yubico-piv-tool -a set-mgm-key -n (16進数48文字) -k(古いマネジメントキー)

次にPIN

yubico-piv-tool -a change-pin

デフォルトのPINは123456で、同じくデフォルトのPUKは12345678。

yubico-piv-tool -a change-puk

同じく変更する。

この辺のキーの変更はGUIツールのほうが使いやすい。(ただしGUIツールはなぜかPUKコードが変更できない。なんだか中途半端……)

あと、好みではあるが、リトライ回数を設定する。

yubico-piv-tool -a verify -P(PIN) -a pin-retries --pin-retries=15 --puk-retries=15 -k(mgm key)

秘密鍵の格納

PEM形式に変換した秘密鍵をyubikeyに格納する。yubico-piv-toolのマニュアル( https://www.yubico.com/wp-content/uploads/2016/05/Yubico_PIV_Tool_Command_Line_Guide_en.pdf )によるとyubikeyの証明書を保存する領域は9a,9c,9d,9eと4つあるようで、9aがPIV Authentication、9cがDigital Signature、9dがKey Management、9eが- Card Authenticationらしい。今回は9aに格納する。

yubico-piv-tool -a import-key -s 9a -i id_rsa.pem -K PEM -k(マネジメントキー)

公開鍵の自己署名証明書作成と格納

次に公開鍵を自己署名する。自分で作った秘密鍵の正当性をどのように担保するかについて、第三者にお墨付きをつけてもらう方法もあるが、今回の目的は他人に自分の秘密鍵の正当性を主張したいわけではないので、自分の秘密鍵の正当性は自分で担保する。これをwebでやるといわゆるオレオレ証明書になるやつだ。今回、yubkikeyはOSから見るとスマートカードとして見えるので、SSHの秘密鍵の対になる公開鍵を自己署名して、自己署名証明書を作り鍵ペアをyubikey内部においておく。まずは公開鍵の自己署名証明書から。

この操作は指定されたスロットに秘密鍵が入っていることが前提。秘密鍵を入れずにやってもエラーになる。

yubico-piv-tool -a verify-pin -a selfsign-certificate -s 9a -S "/CN=SSH/" -i id_rsa_pub.pem -o 9a-cert.pem --valid-days=(日数)

この操作にはPINコードが必要になる。Sオプションはx.509証明書の記述だ。最低限CN(Common Name)さえ入っておけば大丈夫だと思う。OSの証明書選択画面などで使われる名前だ。–valid-daysは証明書の有効期限で、指定しないとでおフォルトで365日となる。試しに1日で作ったのだが、2日経っても期限切れの証明書が使えた。本当に意味あるのか不安。

次に、この証明書をyubikeyに格納する。

yubico-piv-tool -a import-certificate -s 9a -i 9a-cert.pem -K PEM -k(マネジメントキー)

以上でyubikeyに対する操作は終了

yubico-piv-tool -a status

で証明書の状態を確認できる。

CHUIDの作成

普通は必要ないと思うが、実験などでハードウェアリセットをかけてしまうとCHUIDがなくなってしまう。ランダムでCHUIDを発行する必要がある。

yubico-piv-tool -a set-chuid -s 9a

その他

同じ手順で、ECDSA384bit鍵の登録を試みた。同じ鍵を複数鍵を登録することは不可能なので、スロット82に格納してみたいが、Windowsからだと証明書の一覧にECDSAの鍵が出てこない。スロット82だとダメなのかと思って、9aに入れてみたが、やっぱり出てこない。

iptables,ip6tablesの設定

これもすぐに設定の仕方を忘れるので覚書。

まずは、iptables-persistentをインストールしておく。設定ファイルは、/etc/iptables/rules.v4と/etc/iptables/rules.v6。もちろん環境に合わせて書き換える。私の場合はipv4が

# Generated by iptables-save v1.4.21 on Fri Feb 12 17:18:19 2016
*nat
:PREROUTING ACCEPT [2:104]
:INPUT ACCEPT [1:64]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:DOCKER - [0:0]
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER -i docker0 -j RETURN
COMMIT
# Completed on Fri Feb 12 17:18:19 2016
# Generated by iptables-save v1.4.21 on Fri Feb 12 17:18:19 2016
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [3:349]
-A INPUT -p icmp -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport hogehoge -j ACCEPT
-A INPUT -p tcp -m tcp --dport hogehoge -j ACCEPT
-A INPUT -p udp --dport 500 -j ACCEPT
-A INPUT -p udp --dport 4500 -j ACCEPT
-A INPUT -i lo -j ACCEPT
COMMIT
# Completed on Fri Feb 12 17:18:19 2016

ipv6が

# Generated by ip6tables-save v1.4.21 on Fri Feb 12 17:18:19 2016
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -p ipv6-icmp -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p udp -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport hogehoge -j ACCEPT
-A INPUT -p tcp -m tcp --dport hogehoge -j ACCEPT
COMMIT
# Completed on Fri Feb 12 17:18:19 2016

こんな感じ。

あとは、以下のコマンドです。

netfilter-persistent reload

Let’s Encryptの本格運用

Let’s Encryptのベータが始まった時にも投稿したのだけれど、証明書の有効期限が迫ってきたので、本格運用に移らないといけない。
ベータの時から情報も増えて手探り感はなくなりました。新規に始める人は公式サイトを見るのが良いかと思います。
今回はベータからの上書きになるので心配でしたがそこら辺もサポートされているようです。

クライアントのインストール

公式通り

$ git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt
$ ./letsencrypt-auto --help

ただし、今回からcronで自動更新させるつもりなので、rootで行うようにしました。また、letsencrypのディレクトリもユーザホームではなく、/usr/localでやり直しました。

手動での証明書インストール

案の定というか、DebianでApacheを使っている時の動作がおかしかったようで、公式でもDebianだけやり方が違う旨の記述がありました。

./letsencrypt-auto --apache

これでインタラクティブに質問に答えていくと、証明書の発行からインストール、apacheのreloadまでやってくれました。
ベータの証明書が入っていたけど、そのへんもうまい具合に解決してくれました。

証明書の自動更新

証明書の有効期限は90日なので、毎回上のコマンドを叩いてもいいのですが、crontabに対話式でないコマンドを書いておくと自動更新してくれます。

40 23 02 * * /usr/local/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www -d beth.mirahouse.jp --renew-by-default && /usr/sbin/service apache2 reload

ここでハマったんですが、http(80)のDocumentRootとhttps(443)のDocumentRootが違うと、認証に失敗します。DocumentRootに.well-knownというディレクトリを作って、認証の鍵を置くんですが、これの確認にhttpを使うみたいで、httpsのDocumentRootを指定しておくと見に行ってくれないようです。逆にhttpのDocumentRootを書いてもダメでした。
いまいち納得いきませんが、httpとhttpsのDocumentRootを一致させることで解決しましたが、なんとかならないものでしょうか。

Let’s Encrypt のベータ開始

Let’s Encrypt は誰でもTLS(SSL)を無料で使えるようにしようと言うプロジェクト。個人でもhttpsで簡単に暗号化できるようになります。詳しいことは、プロジェクトのページを見てください。https://letsencrypt.org/

正式公開の前にベータテストが開始されましたので試してみました。

続きを読む

Google Authenticator を複数端末で使う方法

最近セキュリティの事故が多くなり2段階認証が流行りのようですが、Google Authenticator のアプリをiPhoneなりAndroidに入れて使うと、2台目の端末には入れらないので困った、みたいな話を聞くので誤解ですということでブログに残しておく。

2段階認証プロセスページ(https://www.google.com/accounts/SmsAuthConfig)でiPhoneなりAndroidなりBlackberry(持ってないので試したことはない)のデバイスを追加するときに、2次元バーコードが出て読み取らせると思うけど、この時に複数端末を同時に登録すればいいだけ。30秒毎に変わるワンタイムパスワードが、複数端末で同じものを示すと思う。1台登録して、後ほど2次元バーコードを再度出すとダメ。同時に登録というのがミソ。もうすでにデバイスを登録している場合は、そのデバイスから一旦アカウントを削除してから、新たに2次元バーコードを表示させて2台同時に登録しましょう。

くれぐれも、紙でバックアップコードを残しておくことを忘れないようにしましょう。上記の作業中も間違ってログアウトしようものなら二度とログインできなくなります。(考えただけでも恐ろしい)

ちなみに公式のマニュアルにも書いてあるので、ご参照ください。(https://support.google.com/accounts/answer/1066447?hl=ja