おうちサーバー構築報告：公開鍵の送付手段・専用ユーザーでsftp

## 能書き

[おうちサーバー構築報告：予告](https://qiita.com/katz_engineer/items/471408eda1d09507c451)からのおうちサーバー構築の続きです。

オレオレ認証局を構築し、それで認証した証明書も作成できるようになりました。今回はその鍵の送付手段です。[以前](https://qiita.com/katz_engineer/items/fc02e92d1315d6a51a7c)もやりましたが、今回はシェルスクリプトにまとめてみました。

### 目標

- 公開鍵をsftpで運搬できるようにする
    - sftp用のユーザーを用意
    - ディレクトリなどを用意し、手順を確立
- ユーザーやディレクトリの用意をシェルスクリプトにまとめる

### 参考文献

- [私的サーバー構築日誌：公開鍵の送付専用ユーザー - Qiita](https://qiita.com/katz_engineer/items/fc02e92d1315d6a51a7c)

## サーバー設定

ユーザーについては下記の条件を満たすように設定します。

- ユーザー名は`transporter`
- ホームディレクトリ無し
- ログイン禁止

送付用ディレクトリは下記にします。

- ディレクトリは`/srv/transport/publickey`
- `/srv/transport`は`root`の所有とする

```console:サーバー172.16.1.101:ユーザーroot
cd
cat <<"___" >buildTransporter.sh
#!/bin/bash
USERNAME=$1
DIRPATH=$2
PUBLICDIR=$3

useradd -s /usr/sbin/nologin -M $USERNAME
passwd $USERNAME
mkdir -p $DIRPATH/$PUBLICDIR
chgrp $USERNAME $DIRPATH/$PUBLICDIR
chmod g+w $DIRPATH/$PUBLICDIR

cat >/etc/ssh/sshd_config.d/$USERNAME.conf <<___A
Match User $USERNAME
  X11Forwarding no
  AllowTcpForwarding no
  PermitTTY no
  PasswordAuthentication yes
  ForceCommand internal-sftp
  ChrootDirectory $DIRPATH
___A
systemctl restart sshd
___
chmod 755 buildTransporter.sh
```

```console:サーバー172.16.1.101:ユーザーroot
./buildTransporter.sh transporter /srv/transport publickey
```

## 確認

### 接続と転送

実験用に、公開鍵ではないテキストファイルを置きます。

```console:サーバー172.16.1.101:ユーザーroot
cd /srv/transport
echo hello,world >hello.txt
```

別マシンからサーバーへtransporterユーザーでssh接続します。私はWin10マシンで実行しました。[172.16.1.101が今回のサーバーマシンです](https://qiita.com/katz_engineer/items/d46b60e6606563e75859#%E3%82%BF%E3%83%BC%E3%82%B2%E3%83%83%E3%83%88%E3%83%8E%E3%83%BC%E3%83%89%E3%81%A8%E3%81%97%E3%81%A6%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A3%E5%8F%B0)。

下記のように、これは失敗します。

```console:クライアントWindows
>ssh transporter@172.16.1.101
The authenticity of host '172.16.1.101 (172.16.1.101)' can't be established.
ED25519 key fingerprint is SHA256:nqgBLKW5g6KIa1wWE1fXVtWeT4P/4pErkSH+iyNRxHc.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '172.16.1.101' (ED25519) to the list of known hosts.
transporter@172.16.1.101's password:
PTY allocation request failed on channel 0
This service allows sftp connections only.
Connection to 172.16.1.101 closed.
```

scpは成功しました。[前回まで](https://qiita.com/katz_engineer/items/fc02e92d1315d6a51a7c#%E6%8E%A5%E7%B6%9A%E3%81%A8%E8%BB%A2%E9%80%81)は失敗していたんですが…何でしょうね。

```console:クライアントWindows
>scp transporter@172.16.1.101:/hello.txt .
transporter@172.16.1.101's password:
hello.txt                                                                             100%   12     0.8KB/s   00:00
```

sftpも成功しますが、画面表示が[前回](https://qiita.com/katz_engineer/items/fc02e92d1315d6a51a7c#%E6%8E%A5%E7%B6%9A%E3%81%A8%E8%BB%A2%E9%80%81)と微妙に違います。仕様が少し変わったのかな。

```console:クライアントWindows
>sftp transporter@172.16.1.101
transporter@172.16.1.101's password:
Connected to 172.16.1.101.
sftp> pwd
Remote working directory: /
sftp> ls -l
-rw-******    ? root     root           12 Dec 29 17:15 hello.txt
drwx******    ? root     1001            2 Dec 29 17:07 publickey
sftp> get hello.txt
Fetching /hello.txt to hello.txt
hello.txt                                                                             100%   12     0.8KB/s   00:00
sftp> cd publickey
sftp> put hello.txt
Uploading hello.txt to /publickey/hello.txt
hello.txt                                                                             100%   12     2.9KB/s   00:00
sftp> ls -l
-rw-******    ? 1001     1001           12 Dec 29 17:21 hello.txt
sftp> pwd
Remote working directory: /publickey
sftp> exit
```

`put`した`hello.txt`を確認。

```console:サーバー172.16.1.101:ユーザーroot
cd /srv/transport/publickey/
ls -l
cat hello.txt
```

```hello.txt```が存在する事を確認します。

```console:サーバー172.16.1.101:ユーザーroot
# cd /srv/transport/publickey/
# ls -l
total 1
-rw-rw-r-- 1 transporter transporter 12 Dec 29 08:21 hello.txt
# cat hello.txt
hello,world
```

動作確認が終了したら、不要なファイルは削除しましょう。

```console:クライアントWindows
del hello.txt
```

```console:サーバー172.16.1.101:ユーザーroot
cd /srv/transport
rm hello.txt
cd publickey
rm hello.txt
```

# 仕舞い

動作確認できたら`/etc`をSubversion登録しましょう。

```console:サーバー172.16.1.101:ユーザーroot
svn st /etc | grep "^?" | cut -b9- | sudo xargs -I{} find {} -type f -or -type d -or -type l | sudo xargs -t svn add
svn ci /etc -m"add user 'transporter'"
```

これで、サーバーマシンとクライアントマシンの間で公開鍵を送付する手段を確保できました。