公開鍵と秘密鍵

serial for debian

前回はOpenBSDでシリアルコンソールを扱った。直交性を考慮したらLinuxでもやっておく必要が有るな。VMWareにdebianが入っているので、試してみるか。

gurbで設定する例が出て来るけど、それはboot時から接続したい場合。普通のシリアル端末で良い場合は、下記を実行しとくだけで十分。

$ sudo systemctl enable serial-getty@ttyS0.service
$ sudo systemctl start serial-getty@ttyS0.service

どうも、リナと言うかsystemdは慣れないなあ。(毎度、同じ事を言ってる気がするぞ)

ssh 公開鍵認証

今までsshでログインする場合、サーバー側のパスワードを入力してた。お手軽でいいんだけど、OpenBSD小僧を名乗るにはちと恥ずかしい。今更ながら、公開鍵認証をやってみる。

ssh-keygen

公開鍵認証には、公開鍵と秘密鍵が必要。それを作るコマンドがssh-keygenだ。普通は、クライアント側で、このペアを作成して、公開鍵のみをログインするサーバー側に送る。

サーバー側では、その公開鍵を所定のファイルに追加しておくって手順になる。

今回は、サーバー側のOpenBSDでペアを作ると言う、世間一般の斜め上な方法でやってみる。なんたって、最先端のsshだし、ソースが有りますからね。 参考にしたのは、ssh-keygenコマンドの使い方 だ。

ob$ ssh-keygen -t ed25519
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/sakae/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase): hogefuga
Enter same passphrase again: hogefuga
Your identification has been saved in /home/sakae/.ssh/id_ed25519
Your public key has been saved in /home/sakae/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:M7GlnZBEcJbhpI68jx4Cf6My96oMz9vJfW2loaVuA/A sakae@ob.localdomain
The key's randomart image is:
+--[ED25519 256]--+
|      .oBo       |
|       B..       |
|      . = .      |
|   ..o   B .     |
|.   oo. S o      |
| o   .E  oo .    |
|. o =  . = +     |
|=o.* B  * +      |
|.**=B o+.o       |
+----[SHA256]-----+

デフォだとRSAが選ばれるんだけど、今回は先端暗号である楕円曲線暗号を指定してみた。 これで、 id_ed25519 (秘密鍵)と id_ed25519.pub (公開鍵)が作成された。

setup for client

クライアントがWSL上のdebian機。両ファイルを .ssh内にscpで持って来ておく。本当に必要なのは、秘密鍵だけど、他のサーバーともsshしたい時に公開鍵が必要になるので、残しておく。両者とも、大事にする。

setup for server

サーバー側では、公開鍵のみ必要。この公開鍵を、 authorized_keys に追加する。

ob$ cat id_ed25519.pub  >> authorized_keys

登録さえ出来てしまえば、公開鍵(オイラーの場合は秘密鍵も)は不要なので、消してしまおう。余計なファイルがセキュリティーを弱める元となる。それから、 authorized_keys のパーミションは、600にして、他人から覗き見を禁止にしておく。

使ってみる。

クライアント側のdebian機から、OpenBSDに接続。

sakae@atom:~$ ob
Enter passphrase for key '/home/sakae/.ssh/id_ed25519':
 :
sakae@xxx.xxx.xxx.xxx's password:

公開鍵認証が優先されている。ここでパスフレーズ(例だとhogefuga)が受理されれば、ログイン出来る。3回目の失敗で、普通の方法を試すようになる。

サーバー側の /etc/ssh/sshd_config

#PubkeyAuthentication yes
#PasswordAuthentication yes

コメントになってるけど、両認証方式共、有効がデフォの設定。PasswordAuthenticationのコメントを外して、かつ no にしておくと良いだろう。

公開鍵アプリ

公開鍵のアプリで一番有名なのは、Webだ。httpsにあらずんばWebにあらずって世の中になっちまったからね。勿論、オイラーのWebも対応してる。

オレオレ証明書

色々なやり方が有るようだけど、超お手軽な方法が解説されてた。 オレオレ証明書をopensslで作る(詳細版)

$ openssl genrsa 2048 > server.key
$ openssl req -new -key server.key > server.csr
$ openssl x509 -days 365 -req -signkey server.key < server.csr > server.crt

秘密鍵 server.key を作成。そのキーに署名して貰うための要求書 server.csr を作成。最後に、その要求書自身を自分で作成した秘密鍵で署名。だからオレオレ証明書って言われるんだな。本来なら、相当の所に頼んで、権威ある証明書を発行して貰うんだけどね。

make key's

実際にやってみる。まずは秘密鍵だ。意識の高い人は鍵サイズを4096とかにして、解読が難しいやつを作るんだろうけど、今回は普通のやつ。

ob$ openssl genrsa 2048 > server.key
Generating RSA private key, 2048 bit long modulus
...+++++
......................+++++
e is 65537 (0x10001)

次は、申請書類の作成。役場で作る印鑑証明書申請だな。この時実印ならぬ秘密鍵から、印影ならぬ公開鍵が、自動抽出され、申請書に添付される。

ob$ openssl req -new -key server.key > server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) []:edo
Organization Name (eg, company) []:Yama
Organizational Unit Name (eg, section) []:devel
Common Name (eg, fully qualified host name) []:ob.local.jp
Email Address []:hoge@openbsd.org

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:

申請は虚偽っぽいけど、練習だからね。そして、いよいよ証明書の発行。自分でやるから、権威は無い。

ob$ openssl x509 -days 365 -req -signkey server.key < server.csr > server.crt
Signature ok
subject=/C=JP/ST=Tokyo/L=edo/O=Yama/OU=devel/CN=ob.local.jp/emailAddress=hoge@openbsd.org
Getting Private key

公開鍵が添付された、証明書が出来上がった(はず)。

ob$ file server.key
server.key: PEM RSA private key
ob$ file server.csr
server.csr: PEM certificate request
ob$ file server.crt
server.crt: PEM certificate

今回の書類の種類を、一応確認しとく。

https

上のオレオレ証明書を使って、httpsなサーバーを自前で立ててみたい。そして、あわよくば、wiresharkで、httpsのパケットを復号化してみたい。

httpdなら、昔OpenBSDで試した事が有るぞ。httpd 2018-10-10の記録が有るな。

OpenBSDがhttpdを提供してるなら、世間に向けても、それで動かしているに違いない。

ob$ w3m -dump_head https://www.openbsd.org/
HTTP/1.0 200 OK
Connection: close
Content-Length: 3992
Content-Type: text/html
Date: Sun, 07 Jun 2020 07:23:02 GMT
Last-Modified: Wed, 20 May 2020 22:07:53 GMT
Server: OpenBSD httpd

ちゃんとhttps対応してた。www.jp.openbsd.orgの方は、apacheが使われていたぞ。まあ、それでもいいんだけど。

httpd setup

上で作った鍵を組み込み、http,httpsに応答を返してくれるWebサーバーを作る。 何は無くとも、/etc/httpd.conf だな。

ob$ cat /etc/httpd.conf
ext_ip = "127.0.0.1"

server "default" {
    listen on $ext_ip port 80
    listen on $ext_ip tls port 443

    root "/htdocs/local.jp"

    tls {
        certificate "/etc/ssl/server.crt"
        key "/etc/ssl/private/server.key"
    }
}

types {
    include "/usr/share/misc/mime.types"
}

http用に80番ポートを開く。https用に443番ポートを開く。こちらは認証付。リスンするのは、ローカルIP限定。

htdocsは、/var/www/htdocs内に設けたlocal.jpってdirの中。これがデフォルトのアクセス先だ。

次のtlsディレクティブの中は、サーバー証明書の在処と名前。そして、秘密鍵の在処と名前だ。最後のtypesは、mimeの設定ファイルの取り込みだ。

access by https

コンテンツが無いと、始まらないので、htdocs/local.jp/index.htmlに適当に書いておく。 そして、サーバーを起動。

rcctl -f start httpd

早速、OpenBSD 6.7 のportsに入ってた firefox 76.0 で、https://localhost/ してみる。

例によって、オレオレ証明書が検出されたけど、どうするよ? 撤退するか、勇気を振り絞って先に進むか決断せいと迫られる。勿論勇気有りで指示通り先に進むと、ちゃんとコンテンツが見られた。

但し、鍵のアイコンは注意マークになってる。鍵アイコンをクリックすると、証明書を閲覧できる(downloadも)。 ob-local-jp-chain.pem ob-local-jp.pem がDL出来たので、確認する。

ob$ openssl x509 -text < ob-local-jp.pem
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            d8:ff:4d:d0:71:14:46:1d
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=edo, O=Yama, OU=devel, CN=ob.local.jp/emailAddress=hoge@openbsd.org
        Validity
            Not Before: Jun  8 00:01:17 2020 GMT
            Not After : Jun  8 00:01:17 2021 GMT
        Subject: C=JP, ST=Tokyo, L=edo, O=Yama, OU=devel, CN=ob.local.jp/emailAddress=hoge@openbsd.org
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:bd:e5:33:bf:d0:48:8c:54:1e:bf:18:4b:4d:c4:
                         :

依頼者と発行者が同一の、オレオレ証明書だ。

ob$ w3m https://localhost/
     :
self signed certificate: accept? (y/n)y
     :
Bad cert ident ob.local.jp from localhost: accept? (y/n)y

w3mも、オレオレ証明書を検出して、注意してきた。いまだに、オレオレ詐欺が横行してるんで、これらの注意をジジババに喚起するような電話機作れよ。

年寄り仕様の携帯。この電話は、オレオレ詐欺の可能性があります。キャッシュカードを交換します、暗証番号を教えてくださいってのに反応して、勝手に電話切ってくれ。

view https packet by wireshark

wireshark 3.2.4 が入っているんだけど、以前見かけた方法では、デコード出来なかった。

WiresharkでSSLセッションの中身を見れるようにする

Transport Layer Security (TLS)

こういう方法が有るのか。

export SSLKEYLOGFILE=~/sslkey.log

こうしておいて、firefoxを起動。Webのコンテンツは長めの方が良いので、下記のようにして、間に合わせでmanの原稿をhtmlに変換しといた。

ob$ cat /usr/share/man/man1/ls.1 | \
mandoc -T html -O style=/usr/share/misc/mandoc.css >ls.html

これで、firefoxを起動し、終了させると、

ob$ cat sslkey.log
CLIENT_RANDOM 6B7F4326F7C1B04A4E24E5EA4803216AB1D04ED418F598E4EEE75117AEFA16D0 686F21053C54304E2635CC036474B161957E56B4142C2A025E4D3FED645B89923224FFB8D57CB73195C5378FA626C467

こんなログが出て来た。 でも、これを指定しても、デコード出来ないなあ。何でかな? まあ、難しいって事が良く分かったよ。

acme-client

httpsなOpenBSDサイトの証明書がどうなってるか、興味津々で確認。

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            04:3f:c1:39:85:a4:bf:af:ba:bc:39:78:85:58:23:b3:d5:bb
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3
        Validity
            Not Before: May  5 21:32:34 2020 GMT
            Not After : Aug  3 21:32:34 2020 GMT
        Subject: CN=www.openbsd.org
          :

Let's Encryptのお世話になってるんですねぇ。

/var/wwwの所にacmeなんてdirが有り、これは何? 状態だった。調べてみると

DESCRIPTION
     acme-client is an Automatic Certificate Management Environment (ACME)
     client: it looks in its configuration for a domain section corresponding
     to the domain given as command line argument and uses that configuration
     to retrieve an X.509 certificate which can be used to provide domain name
     validation (i.e. prove that the domain is who it says it is).  The
     certificates are typically used to provide HTTPS for web servers, but can
     be used in any situation where domain name validation is required (such
     as mail servers).

認証一般を広く扱う機構みたいだ。上に認証書は、有効期限が3月。うっかりしてると、直ぐに認証切れになって、恥ずかしい思いをする。

だったら、そんなのcronに任せて、期限内に自動更新すればいいじゃん。このアプリは正しくそれを行う為に開発された。

To generate a certificate for example.com and use it to provide HTTPS,
create acme-client.conf and httpd.conf and run:

      # acme-client -v example.com && rcctl reload httpd

A cron(8) job can renew the certificate as necessary.  On renewal,
httpd(8) is reloaded:

      ~       *       *       *       *       acme-client example.com && \
              rcctl reload httpd

例に、こんな運用方法まで載ってたぞ。すんばらしい。

ssh-keygen

ob$ openssl
OpenSSL> version
LibreSSL 3.1.1

今までお世話になったopensslの実体は、OpenBSDの人達が業を煮やして独自に開発した、LibreSSLだったりする。参考に見て行ってもいいんだけど、それを下敷きにした、ssh-keygenと対面してみる事にする。

sshディレクトリの中には、各アプリ毎にdirが用意され、それぞれにMakefileだけが置いてある。そこで今回のターゲットである、ssh-keygen/Makefileを下記のように修正(追加)。

CFLAGS= -g -O0

これでmakeすると、moduli.cのコンパイルで名前解決出来ないエラーになる。いきなりは駄目だと悟った。ssh直下には、Makefile,Makefile.incが置かれている。細かい事はMakefile.incに任せているようである。

Makefileの方を修正した。

# SUBDIR=       ssh sshd ssh-add ssh-keygen ssh-agent scp sftp-server \
#       ssh-keysign ssh-keyscan sftp ssh-pkcs11-helper ssh-sk-helper
SUBDIR= ssh-keygen

難の事は無い。ターゲットを絞りに絞っただけ。これでコンパイルしたら、ssh-keygenの中にバイナリーが出来上がった。

(gdb) b main
Breakpoint 1 at 0x32340: file ../ssh-keygen.c, line 3056.
(gdb) r
Starting program: /tmp/ssh/ssh-keygen/a.out

Breakpoint 1, main (argc=0, argv=0x0) at ../ssh-keygen.c:3056
3056    {
 :
3609            if ((r = sshkey_save_private(private, identity_file, passphra\se,

こんな所まで来て、やっと鍵を作っているよ。

Generating public/private rsa key pair.
Enter file in which to save the key (/home/sakae/.ssh/id_rsa): ./AAAAA
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./AAAAA
Your public key has been saved in ./AAAAA.pub
The key fingerprint is:
SHA256:J0Bdqhm+QKEJvZhqcptSNe+zyh6CJ68IquRXuApMm8A sakae@ob.localhost.jp
The key's randomart image is:
+---[RSA 3072]----+
|..  . .. ..      |
| ..o o  ..       |
| oo.. o .        |
|+ ..o. =         |
|oE .oo+ S .      |
|*o=. o.. o       |
|BBoo+..          |
|O+o= .o          |
|*=+.+..o         |
+----[SHA256]-----+

何も指定しないと、3027BitのRSA暗号キーが作成されるのね。 時代の進歩と共に、暗号界もどんどん変わっているね。さりげなくユーザー名とホスト名が埋め込まれているな。


This year's Index

Home