クラウドで開発するとき、持ち込み可、持ち出し不可の環境を作りたくありませんか?

#0. 序文
　はい、ボスに今半年度2件記事を投稿せよとのお達しを頂きました。1件はショボイ記事を投稿済みで、今回も内容自体はショボイですが発想自体は時代の潮流で必要になってきています。
　最近、クラウドなる用語が拡散されるのと並行してプロジェクトの開始と同時に開発者の端末環境が整備されないまま開発に突き進む事例が増えています。で、『クラウドなら環境コピって同じもの作れるだろ！』と安易な発想で突き進んでしまいます。だがしかし、良く考えてください、セキュリティ視点で見ると構築した環境にファイルの持ち込みはしたい、でも持ち出しはさせたくないなんて言う贅沢な要望が出てくるわけです。持ち出し禁止にしたいのであれば、グループポリシーを使わずともWindowsのRDゲートウェイ(※ボスはオープンソースの記事を書けと言っているので、RDGの機能は誰か他の人の記事を見てください)でポリシー設定をしてファイルコピーの禁止は可能ですが、これをしてしまうとファイルの持ち込みもできなくなります。そこで、前回のautofsに引き続き今更感のvsftpdの登場です。
　環境的にはこんな感じですね、図が雑すぎてスミマセン、最近画像の権利関係がうるさいので、権利発生し無さそうな人(本人)のお絵かきです。

![cscd01.png](https://qiita-image-store.s3.amazonaws.com/0/319682/0ff4c1fc-eb93-3cc2-806b-1ccd688271ba.png)

#1. 設定の流れ
今回は以下の通り設定を行います。

- [ ] vsftpdの構築
- [ ] vsftpdの設定
- [ ] rsyncの構築
- [ ] rsyncの設定
- [ ] お試し方法

　環境はCentOS7 2ノードを利用しています。Windowsは図の開発環境LinuxへWindowsからアクセス可能であれば不要ですので、構築していません。(ここは前回ご紹介したautofs等の設定を利用してください)
　また、OSの環境差異の少ない構成ですが、ご承知おきください。(スミマセン、低予算対応のため、クラウドすら利用できないのです)

#2. vsftpdの構築
#2.1. アカウントの作成
#2.1.1. FTP用ユーザの作成
今回FTP側は共用アカウント1ユーザのみの運用想定でいます。ログイン禁止でFTP用のユーザを作成します。
※複数ユーザで運用する場合考慮点が多いのですが、今回と同じ設定の流れで良いのであればFTP用のユーザを同じグループに入れるのが楽です

```bash
sudo useradd -s /sbin/nologin ftpuser01
```

作成したユーザのパスワードを設定します、パスワードを要求されるので、何か設定してください。

```bash
sudo passwd ftpuser01
```

#2.1.2. rsync用ユーザの作成
FTP-PUTしたファイルを開発環境へ飛ばすためのアカウントをログイン禁止で作成します。
※このユーザはcronとrsyncの権限関係に利用するだけなので、パスワードは設定しません

```bash
sudo useradd -s /sbin/nologin rsyncuser01
```

#2.1.3. rsync用ユーザをFTP用のグループに追加
ftpuser01とrsyncuser01を同じグループとして設定します、以下のコマンドを実行してください。

```bash
sudo usermod -aG ftpuser01 rsyncuser01
```

-aG : セカンダリグループを追加する(※a,Gは異なるオプションですが、このセットでセカンダリグループを追加と思ってください) 

#2.2. vsftpdのインストール
#2.2.1. vsftpdのインストール
vsftpdのインストールを行います、今回はyumで入れてしまします。

```bash
sudo yum install vsftpd
```

#2.2.2. vsftpdのサービス自動起動設定
vsftpdの自動起動設定をします。

```bash
sudo systemctl enable vsftpd
```

#2.3. 共用FTPフォルダの作成
#2.3.1. FTP PUT用フォルダの作成
FTP ファイルPUT用のフォルダを作成します、今回はお試しなので何も考えずに/mnt以下に作ってしまいます。

```bash
sudo mkdir /mnt/upload
```

#2.3.2. FTP PUT用フォルダのオーナー変更
オーナーをftpuser01にします。

```bash
sudo chown ftpuser01:ftpuser01 /mnt/upload
```

#2.3.3. FTP PUT用フォルダのパーミッション変更
権限を rwxr-x--- で設定します、以下のコマンドを実行してください。

```bash
sudo chmod 750 /mnt/upload
```

#2.4. FTPS用秘密鍵の作成
サーバの秘密鍵を作成します、以下のフォルダに移動します。

```bash
cd /etc/pki/tls/certs/
```

以下のコマンドを実行すると、サーバの秘密鍵が作成できます。

```bash
sudo make vsftpd.pem
```

色々聞かれるので、以下はあくまでも例です、環境に合わせて設定してください。

```vim
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Kanagawa
Locality Name (eg, city) [Default City]:Yokohama
Organization Name (eg, company) [Default Company Ltd]:MyCompany
Organizational Unit Name (eg, section) []:MySection
Common Name (eg, your name or your server's hostname) []:letyouput
Email Address []:TEKiita@tekiitayo.local
```

#3. vsftpdの設定
vsftpdの設定ファイルを編集します、以下のコマンドを実行してください。
※今回はデフォルト設定ファイルの内、関係ありそうなエントリーだけ載せているので、これだけ設定すれば最低限動くわけではないです、変更対象でないデフォルトの設定は残しておいてください。ですので要件に応じてデフォルト設定を追加/変更してください。

```bash
sudo vi /etc/vsftpd/vsftpd.conf
```

#3.1. vsftpd.confの設定
以下の通り設定します。

```vim
anonymous_enable=NO
```

匿名ログインは禁止にします

```vim
local_enable=YES
```

Linuxのローカルユーザのログイン許可の可否、今回はローカルユーザを利用します。

```vim
write_enable=NO
```

一応、指定フォルダへファイルの配置しかできないようにします。YESにするとアクセス権限変更とかフォルダ作成とかが可能になります。

```vim
local_umask=022
```

umask"022"ならば、パーミッションが"777"でファイルを作っても"022"分引かれ"755"になり、"rwxr-xr-x"の権限設定になります。

```vim
anon_upload_enable=NO
```

匿名ログイン時にファイルをアップロードさせるかの設定です、NOにしておきます。

```vim
dirmessage_enable=NO
```

ディレクトリごとにメッセージファイルを使用するかの設定です、メッセージファイルを作るのも面倒だし、NOです。

```vim
xferlog_enable=YES
```

一応、今回はお試し設定なので、詳細ログ出力にします。

```vim
connect_from_port_20=YES
```

後でTLSを有効にするので20番ポートのアクセス許可しても問題ありません。

```vim
xferlog_file=/var/log/vsftpd.log
```

ログの出力先です、デフォルトのログ名称(xferlog)は何のログか分からないので、とりあえず書き変えてしまいます。

```vim
xferlog_std_format=YES
```

予め設定されているログフォーマットを今回は使います、YESで設定しましょう。

```vim
idle_session_timeout=300
```

制御側が無通信状態時のアイドルタイムアウト設定、今回はお試しなので何秒でも良いですが、とりあえず5分に設定してみます。

```vim
data_connection_timeout=120
```

データ転送側の無通信(データ転送されているがピクリともデータが来ない)のタイムアウト設定、今回はお試しなので何秒でも良いですが、とりあえず2分にしてみます。
※idle_session_timeoutより短くしておいてください

```vim
ascii_upload_enable=YES
```

ASCII モードでのデータ転送設定です、許可にします。

```vim
ascii_download_enable=NO
```

今回は持ち出し禁止を想定しているのでダウンロードは使えないようにします、NOで設定します。

```vim
ftpd_banner=Welcome to blah FTP service.
```

FTPサーバへ接続した時に表示するメッセージです、何でも良いです。

```vim
chroot_local_user=YES
```

YESの場合、ローカルユーザのchrootを許可します。

```vim
chroot_list_enable=YES
```

"chroot_local_user=YES"の場合は、chrootをさせないユーザリストを使うか使わないかの設定になります、YESで設定します。

```vim
chroot_list_file=/etc/vsftpd/chroot_list
```

chrootをさせないユーザリストファイルのパスを指定します、例えば以下の通り"ftpuser02"を追記すると、追記したユーザはchrootで指定されたディレクトリ以外のディレクトリへ移動できます。
※今回はあえて設定する必要はありません

```vim
sudo  echo ftpuser02 >> /etc/vsftpd/chroot_list
```

```vim
allow_writeable_chroot=YES
```

この設定がNOだとchrootした先に書き込み権限があるとエラーとなります。chroot先にファイルを書き込むので、YESで設定します。

```vim
pam_service_name=vsftpd
```

PAMについては別記事を参照してください、yumでインストール時にPAMに既にvsftpdの設定ファイルが撒かれているのでこのままvsftpdとしています。

```vim
userlist_enable=NO
```

今回FTPが利用可能なユーザリストファイルは使用しません、NOで設定します。

```vim
userlist_deny=YES
```

"userlist_enable=NO"なので機能していないのですが、一応YESにしておきます。

```vim
tcp_wrappers=NO
```

今回TCP Wrapperは使いません、クラウド前提の記事なので、FWとかのルールでアクセス制御してください。

```vim
local_root=/mnt/upload
```

FTPサーバへ接続後に移動するディレクトリを指定します。今回は上の方で作ったパスを指定します。

```vim
use_localtime=YES
```

FTPアクセス時にサーバのタイムゾーンの時間を使用する場合、YESで設定します。

```vim
ssl_enable=YES
```

秘密鍵を作ったのでSSL通信を許可します。

```vim
ssl_tlsv1_2=YES
```

SSLと言いながら、昨今は事情によりTLSを使います、TLS1.2利用想定でYESとします。

```vim
rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem
```

上の方で作成した秘密鍵のパスを指定します。

```vim
force_local_logins_ssl=YES
```

ローカルユーザのログインについてSSLを強要するかの設定です、持ち出し禁止にしたいくらいなので、持ち込みも盗聴防止でYESにしましょう。

```vim
force_local_data_ssl=YES
```

データコネクションについてSSLを強要するかの設定です、持ち出し禁止とか言っているので、持ち込みも盗聴防止でYESにしましょう。

```vim
allow_anon_ssl=NO
```

匿名ユーザ接続時のSSL強要の設定です、匿名接続切っているので関係ないですが、NOで設定しておきましょう。

```vim
download_enable=NO
```

ファイルダウンロードの禁止設定です、持ち出し禁止なので当然NOで設定します。

以下からはFTPのパッシブモードの設定です、環境依存で書き変える場所が多いので、参考程度としてください。
※今回はFTPパッシブモードでの検証はしていませんが、業務利用だと大半がパッシブモードになると思います。

```vim
pasv_addr_resolve=YES
```

pasv_addr_resolveをYESに設定すると、pasv_addressをホスト名で名前解決できます。この辺りは環境依存なので、設定が変わってくると思います。

```vim
pasv_address=letyouput
```

一応pasv_addr_resolveがYESなので、pasv_addressはホスト名を書きます。※記載のホスト名は例です、IPアドレスの記載も可能です

```vim
pasv_min_port=60000
```

パッシブモード時のデータ接続用ポートの開始ポート番号、ここも環境依存です。

```vim
pasv_max_port=60100
```

パッシブモード時のデータ接続用ポートの終了ポート番号、ここも環境依存です。

#3.2. サービス再起動
設定が完了したのでvsftpdを再起動します。

```vim
systemctl restart vsftpd
```

#3.3. Firewallルールの変更
TCP/21番ポートの接続許可をします、以下のコマンドを実行してください。※zoneはpublicにしていますが、ここも環境に合わせてください、また、クラウド想定なのでFWは前段に居るはずなのでIP制限かけていませんが、何かしらの方法でIP制限はしておくべきです

```vim
firewall-cmd --add-port=21/tcp --zone=public --permanent
```

#4. rsyncの構築
rsyncで定期的に開発環境のLinuxへファイル転送を行います。
#4.1. rsyncのインストール
#4.1.1. FTPサーバへインストール
まず、FTPサーバ側へrsyncをインストールします。

```bash
sudo yum install rsync
```

#4.1.2. 開発サーバへインストール
続いて開発サーバ(Linux)側へrsyncをインストールします。

```bash
sudo yum install rsync
```

#4.2. rsync用キーペアの作成
FTPサーバ側で秘密鍵と公開鍵を作成し、rsync実行時にパスワード入力を回避します。
#4.2.1. キーペア保存ディレクトリの作成
以下のディレクトリが無ければ作成してください。

```bash
sudo mkdir /home/rsyncuser01/.ssh
```

#4.2.2. キーペアの作成
以下のコマンドを実行してください。
色々聞かれるので、以下の通り設定してください。

```bash
sudo ssh-keygen -t rsa
```

```bash
Enter file in which to save the key (/home/\<user\>/.ssh/id_rsa):
```

鍵の保存場所の指定です、以下の通り設定してください。※鍵のファイル名は後で設定値として使用するので、変更する場合は以降の設定も変更してください

```bash
/home/rsyncuser01/.ssh/rsync
```

```bash
Enter passphrase (empty for no passphrase):
```

パスワードは設定せずエンターキーを叩いてください。

```bash
Enter same passphrase again:
```
パスワードは設定せずもう一回エンターキーを叩いてください。

#4.2.3. 鍵の確認
実行後、lsを実行すると以下のファイルが作成されていることが分かります。

```bash
ls -atrl /home/rsyncuser01/.ssh/
rsync.pub
rsync
```

#4.2.4. 秘密鍵のパーミッションの変更
#4.2.4.1. 秘密鍵保存フォルダのパーミッションの変更
鍵を保存するフォルダの権限を変更します、今後他の鍵も置くかもしれないのでフォルダは rwx------ で設定してください。

```bash
sudo chmod 700 /home/rsyncuser01/.ssh
```

#4.2.4.2. 秘密鍵のパーミッションの変更
作成した鍵は編集することは無いはずですが、 rw------- でとりあえず設定しましょう。(権限を700より拡大するとSSHの鍵として利用できません、と思ったらCentOS7はデフォだと777でもアクセスできるようです)

```bash
sudo chmod 600 /home/rsyncuser01/.ssh/rsync
```

#4.2.5. 公開鍵の移送
rsync.pubを開発環境(Linux)の/tmpにscp等の何かしらの方法で移送してください。
※scpの場合、以下のコマンドになります

```bash
sudo scp /home/rsyncuser01/.ssh/rsync.pub "接続可能なユーザー"@開発環境サーバのIPアドレス:/tmp
```

#4.3. rsync用ユーザの作成
開発環境(Linux)側にユーザを作成します
※rsyncするだけならパスワードは要らないのでパスワードは設定しません

```bash
sudo useradd rsyncuser01
```

#4.4. known_hostsファイル作成
#4.4.1. アクセス確認  & known_hostsファイル作成
FTPサーバから開発環境へSSHで接続し、known_hostsファイルを作成します。

```bash
sudo ssh -i /home/rsyncuser01/.ssh/rsync rsyncuser01@"開発サーバのIPアドレス"
```

以下のメッセージが表示されるので"yes"を選択してください。

```bash
The authenticity of host '開発サーバのホスト名(開発サーバのIPアドレス)' can't be established.
ECDSA key fingerprint is SHA256:長い文字列.
ECDSA key fingerprint is MD5:長い文字列.
Are you sure you want to continue connecting (yes/no)?
```

#4.4.2. known_hostsファイルのコピー
rsyncuser01用known_hostsを作成します、今回はrootでFTPサーバにアクセスしたので、rootからコピーしてますが、ここは使ったユーザの環境に合わせてください。

```bash
sudo cp /root/.ssh/known_hosts /home/rsyncuser01/.ssh
```

#4.4.3. known_hostsファイルのオーナー変更
known_hostsファイルのオーナーをrsyncuser01に変更します、以下のコマンドを実行してください。

```bash
sudo chown rsyncuser01:rsyncuser01 /home/rsyncuser01/.ssh/known_hosts
```

#4.5. 開発サーバのsshアクセス許可設定
以下の設定は、開発サーバで実施します。
#4.5.1. 公開鍵保存用フォルダの作成
以下のコマンドを実行し、フォルダを作成します。

```bash
sudo mkdir /home/rsyncuser01/.ssh
```

#4.5.2. authorized_keysの追加
転送した公開鍵をauthorized_keysとして登録します、以下のコマンドを実行してください。

```bash
sudo cat /tmp/rsync.pub >> /home/rsyncuser01/.ssh/authorized_keys
```

#4.5.3. オーナー変更
authorized_keysのオーナー変更をします。

```bash
sudo chown rsyncuser01:rsyncuser01 authorized_keys
```

#4.5.4. authorized_keysのパーミッション変更
authorized_keysを rw------- に権限を変更します、以下のコマンドを実行してください。

```bash
sudo chmod 600 /home/rsyncuser01/.ssh/authorized_keys
```

#4.6. rsyncの設定
以下の設定は、開発サーバで実施します。
#4.6.1. rsync転送先フォルダの作成
rsyncの転送先フォルダを作成します、以下のコマンドを実行してください。

```bash
sudo mkdir /mnt/ftpserver
```

#4.6.2. フォルダのオーナー変更
フォルダのオーナーを変更します、以下のコマンドを実行してください。

```bash
sudo chown rsyncuser01:rsyncuser01 /mnt/ftpserver
```

#4.6.3. フォルダのパーミッション変更
フォルダのパーミッションを rwxrwx-r-x に権限を変更します、以下のコマンドを実行してください。

```bash
chmod 775 /mnt/ftpserver
```

#4.7. rsyncの疎通確認
FTPサーバからrsyncで疎通できるか確認します、以下のコマンドを実行してください。

```bash
rsync -av --no-p -P --delete -e "ssh -l rsyncuser01 -i /home/rsyncuser01/.ssh/rsync" /mnt/upload/ rsyncuser01@開発サーバのIPアドレス:/mnt/ftpserver/
```

-a : 転送元ファイルのパーミッション、権限などを保持したまま転送する
-v : 転送中のファイル名を表示する、今回ログ取得の設定はしませんが、ログ取る場合に活用してください
--no : --no-[オプション]の[オプション]に指定したオプションを無効にする、今回は-aで活性化するパーミッション保持の"-p"を無効化します
--delete : 同期元にないファイルを同期先から削除します。FTPでファイルの削除はできるので、FTPでファイルを削除すると同期先の開発サーバのファイルも消せます
-e : 転送先サーバのシェルを指定します、今回は以下の通りシェルを指定します
ssh : sshを使用
-l : sshで使用するログインユーザ名を指定
-i : sshで使用する秘密鍵を指定
後は、転送元のパスと転送先のパスを指定しています
#4.8. cronの設定
#4.8.1. cron設定用のエディタ起動
cronで定期的にrsyncを実行します、FTPサーバで以下の通り設定してください。

```bash
sudo crontab -u rsyncuser01 -e
```

-u : cronの実行ユーザを指定します
-e : cronの設定エディタを開きます
#4.8.2. cronの設定
今回1分毎にcronを実行します。※お使いの環境に合わせて実行頻度は指定してください

```vim
*/1 * * * * /usr/bin/rsync -av --no-p -P --delete -e "ssh -l rsyncuser01 -i /home/rsyncuser01/.ssh/rsync" /mnt/upload/ rsyncuser01@開発サーバのIPアドレス:/mnt/ftpserver/
```

*/1 : 1分ごとにcronを実行(分 時 日 月 曜日は未指定)
コマンドは先ほどrsyncで実行したコマンドをそのまま使用

#5. 動作確認
#5.1. FTPSでファイルを転送
まず、FTPSでファイルを複数PUTしてください、FFFTPとかはFTPS対応しています。(オープンソースだから詳しく書けって???スミマセン、なんか記事がやたらと長くなってきたので割愛です)
#5.2. 開発サーバへの転送確認
開発サーバの"/mnt/ftpserver/"へFTPでPUTしたファイルが同期されていることを確認してください。
#5.3. FTPクライアントからファイルのダウンロード実施
FTPクライアントからファイルをダウンロードしてみてください、出来ないはずです。
#5.4. FTPクライアントからファイルの削除を実施
FTPクライアントからPUTしたファイルをいくつか削除してみてください。
#5.5. 開発サーバの同期済みファイルの削除確認
FTPクライアントで削除したファイルが同期先フォルダから削除されているはずです、確認してください。

*****

以上でクラウドへファイルは持ち込みしたいけど持ち出し不可にしたい環境の構築方法は終了です、毎回ニッチな投稿ですが、お付き合い有難うございました。