PHPで公開鍵認証によるscp

CakePHP2のシェルからXMLファイルを鍵認証でscpする際にハマったのでメモ。

# コード

```php:php
/**
 * 公開用のリモートサーバーにファイル転送を行う
 * @throws Exception
 */
private function send()
{
    $this->log('-------------------------------------', 'info');
    $this->log('XML転送処理開始', 'info');
    try {
        $settings = Configure::read('Settings.Feed.Foobar');
        foreach ($settings['Destinations'] as $dest) {
            // ssh接続取得
            $this->log('転送先 -> '.$dest.':'.$settings['RemoteDir'], 'info');
            $conn = ssh2_connect($dest);
            if (!$conn) {
                throw new Exception('XML転送先の接続に失敗しました');
            }
            // 認証
            $this->log('認証情報:user -> '."user:{$settings['User']}", 'info');
            $this->log('認証情報:pubKey -> '."pubKey:{$settings['PubKey']}", 'info');
            $this->log('認証情報:prvKey -> '."prvKey:{$settings['PrvKey']}", 'info');
            if (!ssh2_auth_pubkey_file(
                $conn,
                $settings['User'],
                $settings['PubKey'],
                $settings['PrvKey']
            )) {
                throw new Exception('XML転送先の認証に失敗しました');
            }
            // 転送
            if (!ssh2_scp_send(
                $conn,
                $settings['LocalTmpDir'].DS.$settings['FileName'],
                $settings['RemoteDir'].DS.$settings['FileName'],
                0644
            )) {
                throw new Exception('XMLファイルの転送に失敗しました');
            }
            ssh2_exec($conn, "exit");
        }
        $this->log('XML転送処理終了', 'info');
    } catch (Exception $e) {
        $this->log('XML転送処理でエラーが発生しました', 'alert');
        throw $e;
    }
}
```

# 認証失敗でエラー

```sh:console
Warning Error: ssh2_auth_pubkey_file(): Authentication failed for mimizq using public key: Username/PublicKey combination invalid in [/home/mimizq/foo/apps/front/Console/Command/Bar.php, line 269]

2018-12-06 11:42:28 Alert: XML転送処理でエラーが発生しました
2018-12-06 11:42:28 Alert: exception 'Exception' with message 'XML転送先の認証に失敗しました' in /home/mimizq/foo/apps/front/Console/Command/Bar.php:270
Stack trace:
#0 /home/mimizq/foo/apps/front/Console/Command/Bar.php(45): Bar->send()
#1 /home/mimizq/foo/Vendor/cakephp/cakephp/lib/Cake/Console/Shell.php(437): Bar->main()
#2 /home/mimizq/foo/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(207): Shell->runCommand('main', Array)
#3 /home/mimizq/foo/Vendor/cakephp/cakephp/lib/Cake/Console/ShellDispatcher.php(66): ShellDispatcher->dispatch()
#4 /home/mimizq/foo/apps/front/Console/cake.php(40): ShellDispatcher::run(Array)
#5 {main}
```

コードは問題なさそうに見える。
libssh2を使用しているのでバグ情報など調べてみるが解決せず。 
手動で`ssh -i`はできるのになんだろう？🤔

# 原因は？

しばらく悩んでリモートのログを見てみる。

```sh:/var/log/secure
Dec  6 11:58:20 rmt sudo: pam_unix(sudo:auth): authentication failure; logname=mimizq uid=12119 euid=0 tty=/dev/pts/5 ruser=mimizq rhost=  user=mimizq
Dec  6 11:58:32 rmt sudo: mimizq : TTY=pts/5 ; PWD=/home ; USER=root ; COMMAND=/bin/cat /var/log/secure
Dec  6 11:58:56 rmt sshd[18044]: Authentication refused: bad ownership or modes for directory /home/mimizq
Dec  6 11:58:56 rmt sshd[18045]: Received disconnect from xxx.xx.xx.xxx: 11: PECL/ssh2 (http://pecl.php.net/packages/ssh2)
```

> bad ownership or modes for directory /home/mimizq

なんか出てる。

# `bad ownership or modes` ?

確認してみる。

```sh:local
$ ll /home | grep mimizq
drwxr-xr-x 25 mimizq    foobar      4096 12月  5 19:15 2018 mimizq

$ ll -a ~ | grep .ssh
drwx------   2 mimizq foobar  4096 12月  4 18:53 2018 .ssh

$ ll ~/.ssh
-rw------- 1 mimizq foobar 1675 12月  5 14:16 2018 id_rsa
-rw-r--r-- 1 mimizq foobar  415 12月  5 14:16 2018 id_rsa.pub
```

ローカルは大丈夫そう。

# リモートは？

```sh:remote
$ ll /home | grep mimizq
drwxrwx---  6 mimizq    foobar      4096 12月  5 18:24 2018 mimizq
# ここがおかしい

$ ll -a ~ | grep .ssh
drwx------   2 mimizq foobar  4096 12月  5 18:24 2018 .ssh

$ ll ~/.ssh
-rw------- 1 mimizq foobar 1248 12月  5 10:57 2018 authorized_keys
```

ユーザーホームのパーミッションが変だ。

# 権限を変更して再実行

```sh:remote
$ sudo chmod 755 /home/mimizq

$ ll /home | grep mimizq
drwxr-xr-x  6 mimizq    domain users      4096 12月  5 18:24 2018 mimizq
```

# 成功

```sh
2018-12-06 16:40:18 Info: -------------------------------------
2018-12-06 16:40:18 Info: XML転送処理開始
2018-12-06 16:40:18 Info: 転送先 -> remote:/home/mimizq/test
2018-12-06 16:40:18 Info: 認証情報:user -> user:mimizq
2018-12-06 16:40:18 Info: 認証情報:pubKey -> pubKey:/home/mimizq/.ssh/id_rsa.pub
2018-12-06 16:40:18 Info: 認証情報:prvKey -> prvKey:/home/mimizq/.ssh/id_rsa
2018-12-06 16:40:18 Info: XML転送処理終了
2018-12-06 16:40:18 Info: -------------------------------------
```

送信元だけじゃなく送信先の権限設定にも気をつけようというお話でした。
おしまい。