Dockerコンテナ内で不正接続を弾く

目次

docker containerを守るために、fail2banで認証に失敗したアドレスからの接続を拒否するようにします。ここでは、fail2banのインストール方法と、設定、使用方法を説明します。


目的

サーバをInternetに接続すると、かなりの頻度でユーザ以外のログインが試みられます。SSHなどwell-known portsを使うサービスは特にです。そのためport番号を1024番以上に変更した方がセキュリティが向上するという話があります。しかしこれだけでちょっかいが無くなるかと言うと、全くそのようなことはありません。頻度は減っているのかも知れませんが、認証に失敗したログはちょくちょく見られます。

そこでよりセキュアにするため、ちょっかいを出してきたIPアドレスをfail2banで一定時間(気持ち的には一生)接続できないようにします。Docker containerでも設定方法は基本的に一般のサーバと同じです。しかしDocker containerはsystemdが動いていないなど環境が少し異なるので、追加での設定が必要となります。

方法

今回のcontainerは、Ubuntu baseで1100番ポートにdovecotのpop3サーバが待機していると仮定して説明します。

fail2banのインストール

fail2banとpacket filterに必要なパッケージをインストールします。

Dockerfile
RUN apt-get update \
    && apt-get install --no-install-recommends -y \
    iptables fail2ban python3-pyinotify nftables
  • pyinotifyが無くともログファイルの変化をpollingで検出できるようですが、定期的にファイルを調べる必要を無くすためにインストールします。
  • パケット・フィルタリングの操作にnftを使用しますが、Ubuntu base imageには含まれないためインストールします。

設定

fail2banの設定

fail2banの設定は、基本的に一般のサーバと同じです。ただしsystemdが動いていないので、デフォルトの設定ではログファイルの更新をfail2banが検出できません。そこで検出方法を指定するbackendautoに変更します。これで、systemdに頼らずpyinotifygaminpollingの順番に使用できる検出用法を試して使用するようになります。

なお設定の変更は、オリジナルのjail.confを修正するのではなく、jail.d/jail.localを作成して元の設定を上書きするようにします。

jail.d/jail.local
[dovecot]
enabled = true
port    = pop3,pop3s,imap,imaps,submission,465,sieve
logpath = %(dovecot_log)s
#backend = %(dovecot_backend)s
backend = auto
maxretry = 2
findtime = 1d
bantime = 12w

接続を拒否する期間は、bantimeで指定します。この値を-1にして一生拒否してもよいのですが、拒否するアドレスがたまりすぎるので12週間12wで一度拒否を解除しています。テストのため意図的にbanされることがあると思いますが、その場合は手動で解除できるので拒否期間が長くても問題ありません。

docker composeの設定

パケット・フィルタの設定には、nftコマンドを使用します。しかしdocker container内では、rootの権限が制限されています。そのためOperation not permitted (you must be root)というエラーが発生してnftコマンドを使用できません。そこでnftコマンドを使用してpacketのフィルタリング設定を変更できる権限をcompose.yamlファイルで付与します。

compose.yaml
services:
  app:
    cap_add:
      - NET_ADMIN
    privileged: true

動作確認

filerの確認

指定したフィルタが認証でのエラーを認識できているかは、次のコマンドで確認できます。

fail2ban-regex /var/log/mail.log /etc/fail2ban/filter.d/dovecot.conf
Lines: 603 lines, 74 ignored, 23 matched, 506 missed

これで指定したログにエラーが23含まれていることがわかります。

fail2banの状態確認

fail2banが認識しているエラーの数やBanしているIPアドレスは、次のコマンドで確認できます。

fail2ban-client status dovecot
Status for the jail: dovecot
|- Filter
|  |- Currently failed: 1
|  |- Total failed: 1
|  `- File list: /var/log/mail.log
`- Actions
   |- Currently banned: 0
   |- Total banned: 0
   `- Banned IP list:

この例では、フィルターにかかったエラーが1つで、BanしているIPアドレスはありません。BanしているIPアドレスがある場合は、Banned IP list:にIPアドレスが表示されます。

制限を手動で解除

fail2banの制限をマニュアルで解除するには、次のコマンドを使用します。

fail2ban-client set sshd unbanip <IP-address>