2013-02-27

RHEL6: ssh-keygen: Permission denied

SSH 鍵を作ろうとすると、「Permission denied」と言われる。

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# ls -dl ~/.ssh
drwx------. 2 root root 4096 Feb 27 09:04 /root/.ssh

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
open /root/.ssh/id_rsa failed: Permission denied.
Saving the key failed: /root/.ssh/id_rsa.

パーミッションに抜かりなどある訳がない。失礼な。こういう時、真っ先に疑うべきは SELinux。

/var/log/audit/audit.log:

type=AVC msg=audit(1361923639.970:20915): avc:  denied  { create } for  pid=1932 comm="ssh-keygen" name="id_rsa" scontext=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1361923639.970:20915): arch=c000003e syscall=2 success=no exit=-13 a0=7f6f3282cb80 a1=241 a2=180 a3=fffffff7 items=0 ppid=1875 pid=1932 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts3 ses=2 comm="ssh-keygen" exe="/usr/bin/ssh-keygen" subj=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 key=(null)

案の定、何か文句を言っている。~/.ssh のコンテキストを確認すると、

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:admin_home_t:s0 /root/.ssh

何処が気に入らないのかは良く分からないが、ともかく restorecon してみる。

[rhel62]# restorecon ~/.ssh

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 /root/.ssh

何か修正されたっぽいので、リトライ。

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
a7:14:6f:f0:8a:72:64:20:01:55:2b:24:4c:aa:a7:30 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|=++..            |
|.+ . .           |
|. o o   o        |
|.  o .   =       |
|E .   o S =      |
|.+   o o =       |
|.   . o o        |
|     o           |
|                 |
+-----------------+

動いた。ちなみに ~/.ssh を作るのを ssh-keygen に任せると、何もしなくても上手くいく。

[rhel62]# rm -fr ~/.ssh

[rhel62]# ls -dl ~/.ssh
ls: cannot access /root/.ssh: No such file or directory

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
e6:83:f6:38:dc:fc:eb:6a:45:f1:39:05:34:7d:ad:68 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|           .+o  .|
|          .  .o o|
|           o + o |
|          . E .  |
|        S. . .   |
|       +  .      |
|     .ooo.       |
|     .oo+.       |
|      .oo++.     |
+-----------------+

これは理屈としては理解できるが、非常に分かり辛い動作だと思う。

この理屈に従うと、作ったファイル・ディレクトリが SELinux のポリシーに沿っているかどうか、逐一確認しなければならくなってしまう。そういうことを平気で要求する SELinux の気が知れない。だから「SELinux 氏ね」とか言われるんだよ。:-p

ところでコンテキストの修正は restorecon で行えるが、現在のコンテキストが正しいかどうかはどうやって確認すれば良いのか。

matchpathcon を使え、と。

[rhel62]# rm -fr ~/.ssh

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh has context unconfined_u:object_r:admin_home_t:s0, should be system_u:object_r:ssh_home_t:s0
1

[rhel62]# restorecon ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh verified.
0

注意点として、matchpathcon には絶対パスを渡す必要がある。でないと判定に失敗する。

[rhel62]# ls -dZ .ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 .ssh

[rhel62]# matchpathcon -V .ssh ; echo $?
.ssh has context unconfined_u:object_r:ssh_home_t:s0, should be <<none>>
1

これも理解できる動作ではあるが、やはり分かり辛い。もう少しマシなメッセージは出せないのかと文句を言いたい。

と、いうようなことを実は 1 年以上前にやっていたのだが、最近になって RHEL6.3 では本現象が起こらないことに気が付いた。調べてみると、この辺か。

「理解できる」と言っておいてアレだが、どうやら仕様ではなかったらしい。