Classic Loadbalancerを使ったvsftpdとの接続設定

6ヶ月以上、ちょっと悩んでましたが、やっと解決したかも
カシマです。

案件で費用は抑えつつFTPは使いたいみたいな要望があり、しかしながらそこそこセキュアに…という内容でどうしたもんかな、と考えてましたが、答えに辿り着きました。

本題

通常通りEC2とClassic Loadbalancerは構築して問題はなく、Listenするポートが50000 – 50030 みたいな形で大量にClassc Loadbalancer側で必要になるのですが、やれなくはないんだなと知りました。

もちろんClassic LoadbalancerもEC2のセキュリティグループも50000 – 500030のようなPASV通信に使うポート開放が必要になります。

設定ファイルはこんな感じ

anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
xferlog_enable=YES
xferlog_file=/var/log/vsftpd.log
xferlog_std_format=NO
ascii_upload_enable=NO
ascii_download_enable=NO
ftpd_banner=Welcome to FTP service.
chroot_local_user=NO
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
ls_recurse_enable=YES
listen=YES

pam_service_name=vsftpd
userlist_enable=YES
userlist_deny=NO
tcp_wrappers=NO
userlist_file=/etc/vsftpd/user_list

pasv_enable=YES
pasv_promiscuous=YES
pasv_addr_resolve=YES
pasv_address=(Classic Loadbalancerのエンドポイント)
pasv_min_port=50000
pasv_max_port=50049

allow_writeable_chroot=YES
use_localtime=YES

困るポイント

ELBは変動IPなのでIPが変わるとvsftpdはログインはできてもPASV通信ができなくなります。

vsftpd FTPクライアントからPassiveモードの接続が出来ない

デーモンとして起動すると一度設定した値はメモリ上に置かれるので
途中で、グローバルIPが変わるような動的IPの場合は
変わったIPの値を返さないのでエラーになってします

゚(□)゚エェェ!!

変わったIPの値を返さないのでエラーになってします

Oh…というわけで、これが原因なんじゃないかと思われる案件があったのとmackerelを導入していたこともあり、障害の後に復旧させるscriptを書いてみました。

監視するshellscript

#!/bin/sh
set -eu

CURRENT_IP_FILE='/var/tmp/current_ip.txt'
PREV_IP=`cat $CURRENT_IP_FILE` 2>/dev/null

touch $CURRENT_IP_FILE

NEW_IP=`dig $1 | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\S*' | grep -v '#'` 2>/dev/null

RESULT=0

for oldip in `echo "$PREV_IP"`
do
    CHECK=`echo "$NEW_IP" | grep -Eo "$oldip" | wc -l`
    if [ $CHECK -eq 1 ]; then
        # match ip list
        RESULT=0
        continue
    else
        # not match ip list
        echo "$NEW_IP" > $CURRENT_IP_FILE
        RESULT=2
        break
    fi
done

exit $RESULT

こんな感じのshellを /usr/local/bin/check-publicip.sh として置いておきます。
呼び出すときはこんな感じです。

sh /usr/local/bin/check-publicip.sh (ドメイン)

これで設定したドメインのIPを返してくれて、返ってきたIPと /var/tmp/current_ip.txt に一致するIPが含まれなければ /var/tmp/current_ip.txt へ保存した上でIPが変わったことを知らせてくれます。

mackerel側の設定

[plugin.checks.public_ip]
command = "sh /usr/local/bin/check-publicip.sh (ドメイン)"
action = { command = "bash -c '[ \"$MACKEREL_STATUS\" != \"OK\" ]' && systemctl restart vsftpd.service", user = "root" }

多分こんな設定でできるかと思います。

仮にmackerelを使っていなかったとしても、スクリプトを工夫すればvsftpdをrestartさせられるかと思います。

終わり。

vsftpdは大体ローカル環境(VPCピアリングするなりダイレクトコネクトやVPN環境)でしか繋がないし、外部提供することってそんなになかっただけに知らない挙動でした。
一応動作チェックで全然無関係なIPで試して正常動作していることの確認も取れていますので、大丈夫かな、と思います。

一つ解決してよかった。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

%d人のブロガーが「いいね」をつけました。