IMAPでLoginできたIPアドレスからのssh/ftp他を動的に許可する方法(CentOS 8/Redhat EL 8 + dovecot + firewalld)

日付 2020.01.10
タイトル IMAPでLoginできたIPアドレスからのssh/ftp他を動的に許可する方法(CentOS 8/Redhat EL 8 + dovecot + firewalld)
本文
サーバにログインするorコンテンツを書き換えるサービスについては、固定IPアドレスからのみ通信を許可するか、キーによるログインに制限できれば良いのですが、諸々の都合(キー配布で同一ログインに制約が会社感の都合で難しいとか、sftpでchrootさせるとホームをroot所有にしなければいけないがそれは別な都合で実施できないとか、)でそうできない場合もあります。

しかしポートを野晒しに開けておくと、sshや(s)ftpへのパスワード総当たり攻撃にさらされることになるため、できるだけ野晒しにせず、必要な時だけ任意のIPアドレスからのssh/ftp通信を許可(パケットフィルタリングをパス)するほうが安心です。

CentOS/RedHat EL 7までは、xinetd(tcp wrapper) + popper + watcher2(というperl script)の組み合わせでできたのですが、CentOS/Redhat EL 8からtcpwrapperが標準では提供されなくなるなど、この手が使えなくなりそうです。

そこで、代替の方法はないか模索したところ、Dovecot/IMAP認証時にスクリプト実行 -> nftablesのチェーンを動的書き換え、という方法で動的IPアドレスの通信を一定時間許可することができたのでメモしておきます。


# rootで作業します ----------------
su -

# dovecot設定変更 ----------------
cd /etc/dovecot/conf.d

# imap login時にスクリプト実行を指定します
# 作業前にバックアップ
mkdir .bk
cp -pi 10-master.conf .bk/10-master.conf.bkYYMMDD

vi 10-master.conf
# ----->>>
service imap {
# ... ~~
# 以下を追記
executable = imap imap-postlogin
}

service imap-postlogin {
executable = script-login /etc/dovecot/scripts/postlogin.sh
  #user = root
unix_listener imap-postlogin {
# listener内は特に定義せず
}
}
# -----<<<

# 実行するスクリプトを作成
cd ../
mkdir scripts
cd scripts

vi postlogin.sh
#----->>>
#!/bin/sh

# 同一IPアドレスを削除
/usr/sbin/nft -a list chain inet firewalld filter_IN_public_allow | /usr/bin/grep 'ip saddr '$IP' .* "temperm:' | /usr/bin/sed 's|.* # handle \(.*\)|\1|' | /usr/bin/xargs -I{} /usr/sbin/nft delete rule inet firewalld filter_IN_public_allow handle {}

# コメントのタイムスタンプを見て一定時間過ぎていたら削除
DT=`/usr/bin/date +%Y%m%d%H%M%S`
/usr/sbin/nft -a list chain inet firewalld filter_IN_public_allow | /usr/bin/awk 'match($0, /"temperm:[0-9]{14}"/) && '$DT' - substr($0, RSTART + 9, RLENGTH - 9) > 1800 { sub(/.* # handle /, ""); print $0; }' | /usr/bin/xargs -I{} /usr/sbin/nft delete rule inet firewalld filter_IN_public_allow handle {}

# 新たに追加
/usr/sbin/nft add rule inet firewalld filter_IN_public_allow ip saddr $IP ct state new counter accept comment \"temperm:$DT\"

exec "$@"
#-----<<<

chmod 755 postlogin.sh
systemctl restart dovecot


# 一定時間ごとにリフレッシュするためにpostlogin.shをcronに登録
crontab -e
# ----->>> 以下追記
# refresh allow ipaddrs
0 * * * * IP=127.0.0.1 /etc/dovecot/scripts/postlogin.sh > /dev/null 2>&1
# -----<<<


IMAP認証へのブルートフォースが心配な場合は、特定のwebページへのクライアント認証などで置き換えても良いかもしれません。
以上、何らかのお役に立てば。