システム開発, 受託開発

Ubuntuサーバーを守る基本のセキュリティ対策 ― UFWとFail2banをやさしく解説

Webシステムを公開するとき、アプリケーションの機能だけでなく、サーバーそのものをどう守るかも重要です。

特にインターネット上にあるVPSやクラウドサーバーは、公開しただけでさまざまなアクセスを受けるようになります。

そこでUbuntuサーバーを運用するときに、基本的なセキュリティ対策としてよく利用されるのが、

  • UFW
  • Fail2ban
  • SSHの公開鍵認証
  • VPN・Tailscaleなどによるアクセス制限

といった仕組みです。

今回はその中でも、Ubuntuで使いやすい UFWとFail2ban を中心に、「何をしている仕組みなのか」「なぜ必要なのか」を初学者向けに紹介します。

そもそもサーバーの「ポート」とは?

まず理解しておきたいのが「ポート」です。

サーバーでは、用途ごとに通信の入口となる番号が使われています。

代表的なものでは、

ポート主な用途
22SSH
80HTTP
443HTTPS
5432PostgreSQL
6379Redis

などがあります。

Webサイトを公開するのであれば80番や443番は必要ですが、PostgreSQLを外部から直接利用しないのであれば、5432番をインターネットに公開する必要はありません。

セキュリティの基本的な考え方はシンプルで、

「必要のない入口は、最初から開けない」

というものです。

そこで利用するのがファイアウォールです。


UFWとは?

UFWは Uncomplicated Firewall の略で、Ubuntuでファイアウォールを扱いやすくするための仕組みです。

Ubuntu公式ドキュメントでも、Ubuntuの標準的なファイアウォール管理ツールとしてUFWが案内されています。

イメージとしては、

インターネット
      ↓
 ┌─────────┐
 │   UFW   │
 │  門番   │
 └────┬────┘
      ↓
 Ubuntuサーバー

です。

UFWで、

この通信は通してよい
この通信は通してはいけない

というルールを決めます。


基本は「全部閉じて、必要なものだけ開ける」

サーバーのファイアウォールでは、

外部からの通信は基本的に拒否し、必要なものだけ許可する

という考え方が分かりやすいです。

例えば、

sudo ufw default deny incoming
sudo ufw default allow outgoing

と設定します。

それぞれの意味は次の通りです。

deny incoming

sudo ufw default deny incoming

外部からサーバーに入ってくる通信を、原則として拒否します。

つまり、

明示的に許可していない通信は入れない

という設定です。

allow outgoing

sudo ufw default allow outgoing

サーバーからインターネットへ出ていく通信は許可します。

例えば、

  • Ubuntuのアップデート
  • 外部APIへのアクセス
  • パッケージのダウンロード

などに必要です。


必要なポートだけ許可する

例えば一般的なWebサーバーであれば、

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

と設定します。

これは、

80  → HTTPを許可
443 → HTTPSを許可

という意味です。

そしてSSHをインターネット経由で利用する場合は、

sudo ufw allow 22/tcp

などを追加します。

Ubuntu公式ドキュメントでも、UFWを使って特定ポートの許可・拒否を設定する方法が案内されています。


UFWを有効にする

ルールを設定したら、

sudo ufw enable

でUFWを有効化します。

現在の状態は、

sudo ufw status verbose

で確認できます。

例えば、

Status: active

To        Action
22/tcp    ALLOW
80/tcp    ALLOW
443/tcp   ALLOW

となっていれば、

SSH
HTTP
HTTPS

だけを許可している状態です。


SSH接続中のUFW設定には注意

ここは非常に重要です。

SSHでサーバーへ接続している状態で、

sudo ufw enable

としてしまい、その前にSSHを許可していなければ、

自分自身のSSH接続まで遮断してしまう可能性があります。

そのため、

sudo ufw allow OpenSSH

あるいは、

sudo ufw allow 22/tcp

などでSSHを許可してからUFWを有効にします。

セキュリティ設定では、

「強くすれば強くするほどよい」わけではありません。

運用方法を考えながら、安全に変更することが大切です。


Fail2banとは?

UFWが「入口を管理する門番」だとすれば、Fail2banは、

怪しいアクセスを検知して追い出す警備員

のような存在です。

例えばSSHをインターネットに公開すると、自動化されたプログラムから、

root
admin
ubuntu
test

といったユーザー名で大量のログイン試行が行われることがあります。

そこでFail2banはログを監視します。

SSHログイン失敗
        ↓
SSHログイン失敗
        ↓
SSHログイン失敗
        ↓
    Fail2ban
        ↓
「このIPは怪しい」
        ↓
       BAN

という仕組みです。


UFWとFail2banは役割が違う

この2つは似ているように見えますが、役割が違います。

UFWFail2ban
主な役割通信の許可・拒否不審なアクセスを検知
判断するものポート・IPなどログ・失敗回数など
443番は許可SSH失敗5回でBAN
ブルートフォース対策補助的得意

例えばSSHについて、

UFWは、

22番ポートへの通信は許可

します。

しかしFail2banは、

このIPから短時間に何度もログイン失敗している

と判断した場合、そのIPを一時的に遮断します。

つまり、

UFW
「SSHの入口自体は使っていい」

        ↓

Fail2ban
「でも、この人は怪しいので入れない」

という関係です。


Fail2banをインストールする

Ubuntuでは例えば、

sudo apt update
sudo apt install fail2ban

でインストールできます。

設定を変更するときは、配布されている jail.conf を直接変更するより、

/etc/fail2ban/jail.local

などの .local ファイルにカスタム設定を書く方法が推奨されています。

これにより、パッケージのアップデート時にも設定を管理しやすくなります。


SSHをFail2banで保護する

例えば、

[sshd]

enabled = true
port = ssh
maxretry = 5
findtime = 10m
bantime = 1h

のような設定があります。

意味を分解してみましょう。

enabled

enabled = true

この監視ルールを有効にします。


maxretry

maxretry = 5

何回失敗したらBAN候補にするかを設定します。

ここでは5回です。


findtime

findtime = 10m

どのくらいの時間内の失敗を数えるかを設定します。

ここでは10分です。


bantime

bantime = 1h

BANする時間です。

ここでは1時間です。

つまり、

10分以内に
     ↓
SSHログインを5回失敗
     ↓
そのIPを1時間BAN

という設定になります。

なお、適切な回数や時間はシステムの利用方法によって異なります。厳しすぎる設定にすると正規ユーザーまで遮断する可能性があるため、運用に合わせた調整が必要です。


Fail2banの状態を確認する

Fail2ban全体の状態は、

sudo fail2ban-client status

で確認できます。

SSHについて確認する場合は、

sudo fail2ban-client status sshd

などを利用します。


さらに重要なのがSSHそのものの設定

ただし、Fail2banを入れればSSHが安全になるわけではありません。

より重要なのは、

SSHそのものへの侵入を難しくすること

です。

代表的なのが公開鍵認証です。

パスワード認証

ユーザー名
+
パスワード

ではなく、

公開鍵認証

秘密鍵を持つPC
        ↓
   SSHサーバー

という仕組みにします。

適切に公開鍵認証を準備したうえで、運用要件に応じてパスワードログインを無効化することで、パスワードの総当たり攻撃に対する耐性を高められます。

Fail2banの公式SSHフィルターでも、公開鍵認証を準備してからパスワード認証を無効化する考え方が説明されています。


そもそもSSHを一般公開しない方法もある

さらに一歩進めると、

SSHの22番ポートそのものをインターネットへ公開しない

という方法があります。

例えばTailscaleなどのVPNを利用します。

一般インターネット

443 HTTPS
    ↓
Ubuntu Server


管理者PC
    ↓
Tailscale
    ↓
SSH
    ↓
Ubuntu Server

この構成では、

Webサイト → インターネット公開

SSH       → VPN内部だけ

と分離できます。

Fail2banで攻撃者をBANすることも大切ですが、

攻撃対象となる入口自体を公開しない

という考え方は、さらに基本的な防御になります。


「多層防御」で考える

サーバーセキュリティでは、一つの仕組みにすべてを任せるのではなく、複数の対策を組み合わせます。

例えば、

① 不要なサービスを公開しない
          ↓
② UFWで通信を制限
          ↓
③ SSH公開鍵認証
          ↓
④ Tailscaleなどで管理経路を限定
          ↓
⑤ Fail2banで不審アクセスを遮断
          ↓
⑥ OSやパッケージを更新

といった形です。

これを「多層防御」として考えると分かりやすいでしょう。

一つ突破されても、次の仕組みで防御する考え方です。


Dockerを使っている場合は特に注意

最近のWebシステムではDockerを利用するケースも多くあります。

ここで注意したいのがポート公開です。

例えば、

docker run -p 3000:3000 ...

のように実行すると、IPアドレスを指定していない場合、Dockerは標準ではホストのすべてのインターフェースにポートを公開します。

そのため、

UFWで3000番を許可していない

↓

だから外部からアクセスできないはず

と単純に考えるのは危険です。

Docker公式ドキュメントでも、Dockerが作成するファイアウォールルールによって、公開したコンテナポートへの通信がUFWの通常の処理を迂回する場合があることが説明されています。

特に、

PostgreSQL
Redis
管理画面
内部API

などをDockerで動かしている場合は注意が必要です。


内部サービスはlocalhostに限定する

外部から直接アクセスする必要がないサービスであれば、

-p 127.0.0.1:3000:3000

のようにlocalhostへ限定する方法があります。

Docker公式ドキュメントでも、127.0.0.1 を指定した場合はホスト自身からのアクセスに限定できることが案内されています。

例えば、

Internet

   ↓ 443

Nginx
   ↓
127.0.0.1:3000
   ↓
Webアプリ

という構成にすれば、3000番ポートへ直接アクセスさせず、Webサーバーを経由させることができます。


セキュリティで大切なのは「設定すること」ではなく「理由を理解すること」

ここまでさまざまな設定を紹介しましたが、

UFWを入れたから安全

Fail2banを入れたから安全

というわけではありません。

大切なのは、

何を守るための設定なのかを理解すること

です。

例えば、

UFW
→ 不要な通信を減らす

Fail2ban
→ 不審なアクセスを自動的に遮断する

SSH公開鍵認証
→ 認証を強化する

Tailscale
→ 管理用の入口を一般公開しない

Dockerのポート制御
→ 意図しないサービス公開を防ぐ

というように、それぞれ違う役割があります。


私たちがシステム開発で意識していること

Webシステムのセキュリティというと、

  • SQLインジェクション
  • XSS
  • 認証・認可
  • APIのアクセス制御

といったアプリケーション側の対策が注目されがちです。

しかし実際のシステム運用では、

アプリケーションだけでなく、その下にあるサーバーやネットワークまで含めて考える必要があります。

例えば、

アプリケーション
├─ 認証・認可
├─ 入力値検証
└─ セキュアなAPI

インフラ
├─ UFW
├─ SSH
├─ Fail2ban
├─ VPN
└─ Dockerネットワーク

運用
├─ アップデート
├─ ログ監視
├─ バックアップ
└─ 権限管理

というように、複数の層があります。

私たちもシステムを構築する際には、単に「画面が動く」「機能が完成した」だけではなく、

公開範囲・アクセス経路・認証・サーバー設定・コンテナ設定・運用方法まで含めて、安全に運用できる構成を考える

ことを大切にしています。


まとめ

Ubuntuサーバーの基本的な防御を整理すると、

UFW

必要な通信だけを許可する「門番」。

Fail2ban

不審なアクセスを検知して一時的に遮断する「警備員」。

SSH公開鍵認証

サーバー管理者の認証を強化する仕組み。

TailscaleなどのVPN

管理用の入口を一般のインターネットから分離する仕組み。

と考えると分かりやすいでしょう。

重要なのは、

攻撃されたら防ぐ

だけではありません。

まず、

不要なものを公開しない

そして、

必要なものだけ許可する

さらに、

怪しいアクセスを検知する

という順番で考えることです。

セキュリティには「これを入れれば絶対に安全」というものはありません。

だからこそ、一つひとつの仕組みの役割を理解し、複数の対策を積み重ねていくことが、安全なシステム運用につながります。

関連記事

お気軽にご相談ください

ご質問やご相談がございましたら、お気軽にお問い合わせください。

お問い合わせはこちら