学習記録:12月4日(火):[sftp] ユーザーの作り方
これは 俺のインプットアウトプット記録 Advent Calendar 2018 の4日目のエントリーです。
以前、sftpユーザーを作って提供する機会があったのですが、意外と情報が少ないことに気づきました。
ファイル転送プロトコルであるsftpですが、Webサーバーへ様々なファイルをアップロードする際など、まだまだ利用されているのが実情だと思います。
また、sftpだけでなく、ftpを利用するシーンもあることですし、この情報は有用なのでは?と思い、手取り足取りsftpユーザーの作り方を解説してみます。
前提
- ubuntu16で実行
- Webサーバーへのコンテンツアップ目的
- アップロードできるディレクトリに制限を設ける
- sftpユーザー作成にまつわる作業は全てコンソール上から実施
設定の流れ
対象者
- 提供したサーバーに対し、直接ファイルアップロードのニーズがある方
- 古いシステムをメンテナンスしている方
- 鍵認証についてざっくり知りたい方
- コンソール怖いという方(コワクナイヨ
sftp設定
新規ユーザー作成
sample-sftp
というユーザーを作ります
$ sudo useradd sample-sftp $ sudo passwd sample-sftp 新しい UNIX パスワードを入力してください: 新しい UNIX パスワードを再入力してください: passwd: password updated successfully # ユーザー用のディレクトリを作成 $ sudo mkdir /home/sample-sftp
sftpユーザーのグループ指定
次にsftpユーザーの所属グループを設定します。 今回はnginxで動いているDocumentRootに対し、コンテンツをアップすることが目的なので、条件を以下とします。
- sftp接続後のディレクトリは変更しない
/home/sample-sftp
のまま- 理由は後述の
openssl(chroot)によるディレクトリ制限
のため
# DocumentRootの持ち主であるnginxユーザーをみる $ id nginx uid=112(nginx) gid=116(nginx) groups=116(nginx) # sftpユーザーをnginxのグループに追加する $ sudo usermod -g 116 sample-sftp # グループIDを確認する $ id sample-sftp uid=1001(sample-sftp) gid=116(nginx) groups=116(nginx)
無事にグループがnginxになりました。
SSH鍵作成
次にsftpで接続するための鍵を作ります。 その前に鍵を保存するディレクトリを作成します。
$ cd /home/sample-sftp $ pwd /home/sample-sftp $ sudo mkdir .ssh $ sudo chown sample-sftp:sample-sftp .ssh ubuntu@ip-172-31-47-139:/home/sample-sftp$ ls -la 合計 12 drwxr-xr-x 3 root root 4096 12月 4 22:37 . drwxr-xr-x 4 root root 4096 12月 4 22:35 .. drwxr-xr-x 2 sample-sftp sample-sftp 4096 12月 4 22:37 .ssh
次に実際にsftpするユーザーにチェンジし、鍵を作成します。 鍵のファイル名はデフォルト、パスワードは設定しません。
$ su sample-sftp パスワード: $ cd .ssh $ ssh-keygen -t rsa -b 4096 Generating public/private rsa key pair. Enter file in which to save the key (/home/sample-sftp/.ssh/id_rsa): [press enter] Enter passphrase (empty for no passphrase): [press enter] Enter same passphrase again: [press enter] Your identification has been saved in /home/sample-sftp/.ssh/id_rsa. Your public key has been saved in /home/sample-sftp/.ssh/id_rsa.pub. The key fingerprint is: SHA256:3YlPDtl7NZ0wX6DbGu5B5Z4+C39amQfQ3GcBg9XjGwk sample-sftp@ip-172-31-47-139 The key's randomart image is: +---[RSA 4096]----+ | o++. | | . E.=.| | oo* B| | . = B+==| | S = O ++=| | B = =+| | O +oo| | . *..o| | . == | +----[SHA256]-----+
生成された鍵ファイルを確認します。
$ ls -la 合計 20 drwxr-xr-x 2 sample-sftp sample-sftp 4096 12月 4 22:43 . drwxr-xr-x 3 root root 4096 12月 4 22:37 .. -rw------- 1 sample-sftp nginx 3247 12月 4 22:40 id_rsa -rw-r--r-- 1 sample-sftp nginx 754 12月 4 22:40 id_rsa.pub
次に、公開鍵(ドアノブの鍵穴みたいなもの)を authorized_keys
というファイルに転記します。
なお、適切な権限に設定しないと認証に失敗しますので、合わせて設定します。
$ chmod 600 authorized_keys $ chmod 700 ../.ssh $ pwd /home/sample-sftp/.ssh $ ls -la 合計 20 drwx------ 2 sample-sftp sample-sftp 4096 12月 4 22:43 . drwxr-xr-x 3 root root 4096 12月 4 22:37 .. -rw------- 1 sample-sftp nginx 754 12月 4 22:43 authorized_keys -rw------- 1 sample-sftp nginx 3247 12月 4 22:40 id_rsa -rw-r--r-- 1 sample-sftp nginx 754 12月 4 22:40 id_rsa.pub # suでチェンジしたユーザーからexit $ exit
sftpできるディレクトリを制限
sftpアカウントで接続した際、ルートからなんでも見れて更新できては何かと困ります。 ゆえに制限をかけていきます。
まずバックアップを作成します。
$ pwd /etc/ssh $ sudo cp -rp sshd_config sshd_org_config
ユーザーの制限事項を追加します。
# /etc/ssh/sshd_configを開く
$ sudo vim sshd_config
/etc/ssh/sshd_configにユーザー制限を追加します。 ファイルの末尾に追加しました。
Match User sample-sftp ChrootDirectory /home/sample-sftp ForceCommand internal-sftp
次にsshを再起動して設定を反映します。
$ sudo /etc/init.d/ssh restart [ ok ] Restarting ssh (via systemctl): ssh.service.
あと、僕は失敗した時のために、必ずすぐ戻すためのコマンドを先に用意してたりします。
mv sshd_config sshd_config_failed mv sshd_org_config sshd_config sudo /etc/init.d/ssh restart
DocumentRootの調整
DocumentRootで直接ファイルを操作されると何かと困(ry 以下の手順で sftpユーザーのhome配下のみ更新できる ように設定していきます。
/home/sample-sftp/htdocs
の配下にアップロードしてもらう/srv/www/www.mamy1326.jp/htdocs
を上記のシンボリックリンクにする- これをやることで、 sshd_configに設定したChrootDirectoryの制限を回避できる
/home/sample-sftp/htdocsを作成し、sftp接続で書き込み可能にします。
$ pwd /home/sample-sftp $ sudo mkdir htdocs $ sudo chown sample-sftp:sample-sftp htdocs $ sudo chmod 755 htdocs $ ls -la 合計 16 drwxr-xr-x 4 root root 4096 12月 4 22:57 . drwxr-xr-x 4 root root 4096 12月 4 22:35 .. drwx------ 2 sample-sftp sample-sftp 4096 12月 4 22:43 .ssh drwxr-xr-x 2 sample-sftp sample-sftp 4096 12月 4 22:57 htdocs
次に、実際のDocumentRootにシンボリックリンクを作成します。
$ pwd /srv/www/www.mamy1326.jp $ sudo ln -s /home/sample-sftp/htdocs public $ ls -la 合計 12 drwxr-xr-x 3 root root 4096 12月 4 23:01 . drwxr-xr-x 4 root root 4096 9月 7 02:37 .. lrwxrwxrwx 1 root root 24 12月 4 23:01 public -> /home/sample-sftp/htdocs
sftp実行
これで準備は整いましたので、実際に接続し、意図通りにファイル操作ができるかを確認します。手順は以下です。
- ローカルから接続
- 書き込みできることを確認
- 他のディレクトリに移動できないことを確認
- sftpのみ(sshできない)ことを確認
- コンテンツをアップして、DocumentRootにアップされていることを確認する
まずは先ほど作った秘密鍵をサーバーから取得します。 ファイルの設置や、適切な権限設定を実行しておいてください。
$ scp -i mamy1326.pem ubuntu@18.179.206.65://home/ubuntu/id_rsa id_rsa_sample-sftp id_rsa 100% 3247 54.4KB/s 00:00 $ sudo cp id_rsa_sample-sftp ~/.ssh $ sudo chmod 600 ~/.ssh/id_rsa_sample-sftp $ ls -la ~/.ssh/id_rsa_sample-sftp -rw------- 1 mamy1326 staff 3247 12 4 23:06 id_rsa_sample-sftp
準備は整ったので、実際に接続してみます。
$ sftp -i id_rsa_sample-sftp sample-sftp@18.179.206.65 Connected to sample-sftp@18.179.206.65. sftp>
無事に接続できたので、色々コマンドを実行してみましょう。
# /home/sample-sftp直下にはアップロードできない(root:rootなので) # 一覧をみる sftp> ls -la drwxr-xr-x 4 0 0 4096 Dec 4 13:57 . drwxr-xr-x 4 0 0 4096 Dec 4 13:57 .. drwx------ 2 1001 1001 4096 Dec 4 13:43 .ssh drwxr-xr-x 2 1001 1001 4096 Dec 4 13:57 htdocs # 場所を確認する。sftpユーザーからみてルートであることがわかる sftp> pwd Remote working directory: / # 権限が与えられていない場所にputすると権限がなくて失敗する sftp> put sample.pdf Uploading sample.pdf to /sample.pdf remote open("/sample.pdf"): Permission denied sftp>
次に、権限が与えられているディレクトリに移動し、ファイルをputしてみます。
# htdocs配下にはアップできる sftp> cd htdocs sftp> put sample.pdf Uploading sample.pdf to /htdocs/sample.pdf sample.pdf 100% 4007 54.2KB/s 00:00 sftp> ls -la drwxr-xr-x 2 1001 1001 4096 Dec 4 14:17 . drwxr-xr-x 4 0 0 4096 Dec 4 13:57 .. -rw-r--r-- 1 1001 116 614935 Dec 4 14:17 sample.pdf sftp> pwd Remote working directory: /htdocs sftp>
最後に、実際にDocumentRootにファイルが設置されているか確認します。
$ ls -la /srv/www/www.mamy1326.jp/public/ 合計 12 drwxr-xr-x 2 sample-sftp sample-sftp 4096 12月 4 23:17 . drwxr-xr-x 4 root root 4096 12月 4 22:57 .. -rw-r--r-- 1 sample-sftp nginx 614935 12月 4 23:17 sample.pdf
無事にアップされていますね。 これでめでたく、外部の人に制限されたアクセス状態で、DocumentRootを更新 できるようになりました。
Webブラウザから確認
DocumentRootにアップしたので、Webブラウザから見れることを確認しておきます。 そのうちインスタンスを停止しますが、現在こんな感じですね。
連絡報告
あとはクライアントに、接続情報、鍵ファイル、制限事項などを連絡報告および共有します。 その結果として、クライアントが無事に接続でき、目的を達成できたことを確認して、クライアント向けの作業が完了、となるかと思います。
課題
ブラウザから確認
せっかくWebサーバー立てて、ドメイン名をとったので、ブラウザから確認できるようにエントリーに追記します。- やりました!
CyberDuck確認
おそらくクライアントは何かしらツールを使うと思うので、設定手順があると便利よね。
ドキュメント整備
実際の業務だと、作って終わりというわけではないと思います。 各種情報や鍵ファイルなどは適切な権限と場所に管理しておきましょう。
- GoogleDriveにsftp用の鍵を置く
- 同じくアカウント情報を置く
- 情報(sftp)
- IPアドレス
- ユーザー名
- 鍵のファイル名
- 接続方法
- コンテンツアップ先(フルパス)
- 情報(sftp)
やってみて
以上、実際にEC2インスタンスを立て、Webサーバー(nginx)を起動し、実行した結果です。
実際の業務では、単一の作業だけではなく、お客さんへのリリースや連絡、社内でのドキュメント整備など、付随する作業があると思います。
また、なぜそう設定するのか。 理由も含めて手順として残しておけたらいいですよね。
というわけで、僕の個人メモをもう一度再現し、実際に動いた結果といて公開してみました。
もう一度やれと言われたら暗記してる自信は皆無だし、未来の自分が今の自分に必ず感謝すると思うので、積極的に残していきたいですね。