[lv4] ft_services (5/6) ftps実装
<- 前(4/6): wordpress実装
-> 次(6/6): grafana実装
9. ftps作る
(10. ftpsを永続ボリューム化)
11. grafanaの起動
12. influxdb -> grafana連携
13. telegraf -> influxDB連携
14. grafanaカスタマイズ
Q. ftpsとは?
A. File Transfer Protocol over SSL/TLSなるもの。
暗号化したファイルをサーバに転送するプロトコルです。送信側が暗号化し、受け取った側が復元しています。
Q. ゴールは?
A. FTPSサーバを立て、VMローカルにある適当なファイルをサーバに送ったり、そのファイルをローカルに戻せたりしたらよさそうです。
FTPSサーバを立てます。
後半戦に必要なツールを、まとめてインストールします。
/srcs/basecamp/Dockerfile
------------apk add install群を追加----------
RUN set -ex; \
apk update; \
apk add nginx openssl wget curl; \
mkdir -p /run/nginx; \
# php-mysql (no such package): alpineに入らない
apk add mysql mysql-client; \
apk add php7-phar php7-fpm php7-common php7-session php7-iconv php7-json php7-gd php7-curl php7-xml php7-mysqli php7-imap php7-cgi fcgi php7-pdo php7-pdo_mysql php7-soap php7-xmlrpc php7-posix php7-mcrypt php7-gettext php7-ldap php7-ctype php7-dom; \
# php7-pharはwp-cliで必須
# openrc: rc-service mandoc+man-pages: man
apk add openrc mandoc man-pages; \
apk add vsftpd; \
# grafana-server
apk add libc6-compat; \
apk add influxdb telegraf
------------apk add install群 ここまで-------
------------wget 群追加------------------
# wget 追加
# grafana
# ref: https://zenn.dev/tkomatsu/scraps/42e6cd3f96f4e5
RUN set -ex; \
wget https://dl.grafana.com/oss/release/grafana-7.4.5.linux-amd64.tar.gz; \
tar -zxvf grafana-7.4.5.linux-amd64.tar.gz; \
rm grafana-7.4.5.linux-amd64.tar.gz; \
mv grafana-7.4.5 grafana; \
mv grafana/ /
------------wget 群ここまで------------------
nginx.yamlをコピーして設定を変更させます。
/srcs/ftps/ftps.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: ftps
name: ftps
spec: # podの概要
replicas: 1
selector:
matchLabels:
app: ftps
template:
metadata:
labels:
app: ftps
spec:
containers:
- image: myftps
imagePullPolicy: Never
name: ftps
ports:
- containerPort: 20
name: ftps-datapath
- containerPort: 21
name: ftps
- containerPort: 60000
---
apiVersion: v1
kind: Service
metadata:
name: ftps
annotations:
metallb.universe.tf/allow-shared-ip: "ft_services"
spec:
type: LoadBalancer
selector: # DeploymentのPodのlabelとセット
app: ftps
ports:
- name: ftps-datapath
port: 20
- name: ftps
port: 21
- name: pasv
port: 60000
Q. port 20, 21, 60000?
A. port 21はやり取りの開始と終了の制御だけ、です。データの送受信に使われるのがport 20なので、どちらも開けます。
60000は、パッシブモード接続のために使用します。confの設定と合わせますが、port 30000以上でありさえすればよいとか。
portsが複数ある場合は- name 必須です。
(ref) FTPの仕組み!「 21番ポート」と「20番ポート」 「アクティブモード」と「パッシブモード」について
https://mechalog.com/ftp-shikumihttps://mechalog.com/ftp-shikumi
次、confファイルを仕上げます。
/srcs/ftps/vsftpd.conf
# listen=NOだとスーパーサーバから。YESでスタンドアロン
# ref: https://linuxjm.osdn.jp/html/vsftpd/man8/vsftpd.8.html
listen=YES
# ローカルユーザアカウント(/etc/passwd に記録されている ユーザ ID が 500 以降のユーザ アカウント)のログインを許可する。
local_enable=YES
# 次の許可。制御対象 FTP コマンド : STOR, DELE, RNFR, MKD, RMD, APPE, SITE
write_enable=YES
# サーバ側が使用するデータ転送用ポート番号の指定方法を定義する。 YES: ftp_data_port で指定するポートを使用する。
connect_from_port_20=YES
ftp_data_port=20
# seccomp filter をオフにする ( ログインに失敗する場合はオフにする )
# seccompはlinuxカーネルの3.5から入ったシステムコールのフィルター。
# カーネルのバージョンが3.5以上のときはONにしないといけないらしい。
seccomp_sandbox=NO
# FTPで特定のユーザに上位ディレクトリを見せないための設定
# ref: https://qiita.com/kenichiro-yamato/items/08aa845b61804373d739
anonymous_enable=NO
chroot_local_user=YES
allow_writeable_chroot=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
# TLSを有効化
ssl_enable=YES
# 使用プロトコル (必要なプロトコルをYESに設定する)
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=YES
#ssl_tlsv1_1=NO この設定は存在しない
#ssl_tlsv1_2=YES
# 暗号化方式
# ssl_ciphers=kEECDH+AESGCM+AES128:kEECDH+AESGCM:kEECDH+AES128:kEECDH+AES:!aNULL:!eNULL:!LOW:!EXP
# サーバ証明書、秘密鍵
rsa_cert_file=/etc/nginx/ssl/ft_service.crt
rsa_private_key_file=/etc/nginx/ssl/ft_service.key
# パッシブモードの接続を許可する
pasv_enable=YES
# FTPサーバのIPアドレスを指定(パッシブモードで接続時)
pasv_address=192.168.10.10
# ※上記のIPは固定となります。
# ポート指定 00: 1024~65535番のうちのポート番号がランダムで使用されるようになります。
pasv_min_port=60000
pasv_max_port=60000
# ※ポートはハイポートであれば特に指定はありません
pasv_addr_resolve=YES
# vsftpd および xferlog の両形式のログを取得する。
# ただし、xferlog_enable が YES でなければならない。
dual_log_enable=YES
xferlog_enable=YES
# FTP のすべての要求と応答を記録する。 デバッグ等に使用する。
# xferlog_std_format ディレクティブは NO に設定することが必須である。
log_ftp_protocol=YES
xferlog_std_format=NO
# メッセージ ファイル (message_file で指定) を設置したディレクトリにアクセスがあると、メッセージ ファイルの内容を表示する。
dirmessage_enable=YES
vsftpd_log_file=/var/log/vsftpd.log
xferlog_file=/var/log/vsftpd.log
Q. それぞれどういう意味?
A. 一覧表があります。
(ref) http://www.nina.jp/server/redhat/vsftpd/vsftpd.conf.html
Q. chroot_list_enable=YES ?
A.
実動作を先に案内します。
1. ftpsサーバには、利用ユーザを登録できます。
2. ローカルVMからftpsサーバにアクセスするときに、ユーザを指定してアクセスします。
3. ftpsサーバの中身を全員が全部見えてしまっては、実運用に問題があります。
4. そのため、ユーザごとにルートディレクトリを決められます。特定の階層以上に上がれないよう、制限を設けます。
5. chroot_list_file=/etc/vsftpd/chroot_list
とすることで、/etc/vsftpd/chroot_listに制限するユーザのリストを設置し、有効化できます。
6. chroot_listファイルの中身に、local_root=<path>を指定することで、ログイン時のパスを指定できます。
/srcs/ftps/chroot_list
local_root=/var/www/ftp_dir
Q. エラーログ?
A. 多分出ません。頑張ったのですがまだうまくいきません。
vsftpd_log_file=/var/log/vsftpd.log
xferlog_file=/var/log/vsftpd.log
ここに出ればいいのですが。
Q. どこいじる?
A. このあたりをそろえます。
・外部IP(192.168.10.10)
・passiveのport(60000)
・ssl認証キーのパス rsa_cert_file / rsa_private_key_file
Q. なぜこんなに多い?
A. 各種参考サイトを継ぎ足したため。最低限の設定を探す余地はあります。
次に、ftpsユーザの設定です
/srcs/ftps/Dockerfile
FROM basecamp
# -S 指定されたシェルの存在や妥当性を確認しません。
# -G -G groups 追加グループ。 このオプションは、ユーザに付与する追加グループを指定します。 ユーザは、ログイングループに加え、これらのグループのメンバです。
# -D パスワードの入力まちをスルー?
# chpasswd = username:password
RUN adduser -D ftp-user \
&& echo 'ftp-user:ftp-user' | chpasswd
# FTPで接続したときにデフォルトでたどり着くディレクトリ
RUN mkdir -p /var/www/ftp_dir &&\
chown ftp-user /var/www/ftp_dir &&\
chmod 755 /var/www/ftp_dir
RUN mkdir -p /etc/vsftpd/user_conf
RUN touch /var/log/vsftpd.log
COPY start.sh /tmp/start.sh
COPY vsftpd.conf /etc/vsftpd/vsftpd.conf
COPY chroot_list /etc/vsftpd/chroot_list
# 書き込み権限いるかも
RUN chmod -R 777 /tmp /var /etc
# port
EXPOSE 20 21 60000
WORKDIR /
CMD [ "/tmp/start.sh" ]
Q. adduser?
A. Alpineでは、useraddが使えません。パスワードの入力待機を避けるために、chpasswdでパスワードを設定します。
ftpsも、起動コマンド必要です
/srcs/ftps/start.sh
#!/bin/sh
/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
Q. .conf?
A. vsftpd <confのパス> で実行します。
設定ファイルの宣言を必須とするコマンドなので注意。
ここまで一息に書ききって、ようやく動作確認です。
/run.sh
# del
kubectl delete -f srcs/ftps/ftps.yaml
# image
docker build -t myftps srcs/ftps/.
# apply
kubectl apply -f srcs/ftps/ftps.yaml
➜ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ftps LoadBalancer 10.110.1.107 192.168.10.10 20:35811/TCP,21:1316/TCP,60000:63997/TCP 79s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 17m
mysql ClusterIP None <none> 3306/TCP 83s
nginx-metallb LoadBalancer 10.106.43.97 192.168.10.10 80:12714/TCP,443:55763/TCP 88s
phpmyadmin LoadBalancer 10.102.204.165 192.168.10.10 5000:2054/TCP 86s
wordpress LoadBalancer 10.101.118.158 192.168.10.10 5050:49817/TCP 81s
ftpsを見ると、LoadBalancerのport 20/21/60000が開いてます。
Q. 実動作
A. FTPSサーバとやりとりには、bashのようなコマンドツールが必要です。「lftp」なるツールが便利なので、VMローカルに落とします。
apt-get install lftp
sh ./run.sh
VMにて、
-> lftp -e 'set ssl:verify-certificate false' -u ftp-user -p 21 192.168.10.10
-> pass: ftp-user
でログイン。
IPやユーザー名が間違えていても、必ずlftpが起動します。
lftp ftp-user@192.168.10.10:/> pwd
ftp://ftp-user@192.168.10.10:21/
lftp内でコマンドが動作されれば開通です。
_n
( l _、_
\ \ ( <_,` )
ヽ___ ̄ ̄ ) グッジョブ!!
/ /
続いてファイル転送できるか確認。
// ローカルVMにtext.txtを作成 ( ! : ローカルVM操作に切り替え )
!echo "aaaaa" > test.txt
// ftpsサーバにtest.txtを設置。
put test.txt
// ftpsサーバにファイルがコピーされていればOK
// ローカルVMで、test.txtを削除
!rm test.txt
// ftpsサーバからローカルVMに、test.txtをコピー
get test.txt
// ftpsサーバからローカルVMにファイルがコピーされていればOK
Q. 'set ssl:verify-certificate false'?
A. SSLの正当性を無視します。今回オレオレ証明書なので、必ずエラーが出てしまいます。必須です。また、エラーがSSL設定成功の確認になります。
・(10. ftpsを永続ボリューム化)
仕様ならそれでいいかもしれませんが。今はpodを消すと、ftpsサーバにうつしたデータが消失します。
ローカルフォルダをftpsサーバの保存領域にマウントすれば、データを残せます。
Q. ftpsサーバの保存領域?
A. /home/<user名>
chroot_listの中で、local_root=/var/www/ftp_dir としたはずですが、どうもftpsサーバ内でのログイン場所?保存場所にはならないようです。
ftpsサーバのマウントを/homeに設定します。
/srcs/ftps/ftps.yaml
- containerPort: 60000
name: pasv
--------------追加----------------
volumeMounts:
- name: ftps-persistent-storage
mountPath: /home
volumes:
- name: ftps-persistent-storage
persistentVolumeClaim:
claimName: ftps-pv-claim
-------------ここまで----------------
---
pv.yamlをコピーして、名称だけ変更します。
/srcs/ftps/ftps-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: ftps-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 100Mi
accessModes:
- ReadWriteOnce
hostPath:
path: "/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: ftps-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
また、ローカルVMで以下の操作を行います。
Q. マウントされた場合、書き込み権限はどっちにあるの?
A. ローカルVMの権限が優先されるように見えます。
今のままだと、ローカル/data/ftp-userフォルダに書き込むことになりますが、権限ありません。
/run.sh
# ftps pv
if [ ! -d "/data/ftp-user" ]; then
sudo mkdir -p /data/ftp-user
sudo chmod 777 /data/ftp-user
echo "[run.sh] /data/ftp-user made."
else
echo "[run.sh] /data/ftp-user already exist."
fi
# lftp install
sudo apt-get install lftp
# apply
kubectl apply -f srcs/ftps/ftps-pv.yaml
sudo mkdir /data/ftp-user
sudo chmod 777 /data/ftp-user
ftpsサーバにtest.txtを設置し、ftpsのpodを再起動し、残っていたら大成功。
sh ./run.sh
lftp -e 'set ssl:verify-certificate false' -u ftp-user -p 21 192.168.10.10
<ファイル設置する>
sh ./run.sh # podを再起動。永続ボリュームでなければ消失しているはず。
lftp -e 'set ssl:verify-certificate false' -u ftp-user -p 21 192.168.10.10
ls
ある?
これで永続ボリューム化完了。
---TRUE END---