Linuxサーバーを運用していると、必ず出会うのが iptables(アイピーテーブルズ) です。
「なんだか難しそう…」
「間違えてサーバーにアクセスできなくなったらどうしよう…」
「どのルールが必要なのか分からない…」
そんな不安を持つ方は多いでしょう。
この記事では、Linuxのファイアウォール設定に欠かせないiptablesについて、初心者の方にも分かりやすく解説していきます。
iptables(アイピーテーブルズ)とは何か?
iptables は、Linuxカーネルに組み込まれたファイアウォール機能を設定するためのツールです。
一言で言うと、サーバーへの出入りを管理する「門番」を設定するためのコマンドです。
空港のセキュリティチェックに例えると分かりやすい
空港には、厳格なセキュリティチェックがありますよね。
入国審査では:
- パスポートを確認
- 目的を質問
- 危険物を持っていないかチェック
- 条件を満たした人だけ入国許可
iptablesも同じです:
- 通信の送信元を確認
- 通信先のポート番号をチェック
- プロトコル(TCP、UDPなど)を確認
- 条件に合った通信だけを許可
iptablesでできること
通信の許可・拒否:
- 特定のIPアドレスからの接続を許可
- 特定のポートへのアクセスを遮断
- 外部への不要な通信をブロック
ネットワークアドレス変換(NAT):
- プライベートIPとグローバルIPの変換
- ポートフォワーディング
パケットの加工:
- パケットの内容を書き換える
- ログの記録
接続の追跡:
- 確立された接続を記憶
- 関連する通信を自動的に許可
なぜiptablesが必要なのか?
ファイアウォールがないと、どんな危険があるのでしょうか。
理由1:不正アクセスの防止
インターネットに接続しているサーバーは、常に攻撃にさらされています。
よくある攻撃:
- SSH(ポート22)への総当たり攻撃
- 脆弱性のあるサービスへの攻撃
- DDoS攻撃(大量のアクセスでサーバーをダウンさせる)
iptablesで不要なポートを閉じることで、攻撃の入り口を減らせます。
理由2:内部ネットワークの保護
外部からの攻撃だけでなく、内部のセキュリティも重要です。
例:
- データベースサーバーは、Webサーバーからのアクセスのみ許可
- 管理用ポートは、特定のIPアドレスからのみアクセス可能
理由3:コンプライアンス(法令遵守)
多くの規格や法律で、ファイアウォールの設置が求められています。
例:
- PCI DSS(クレジットカード情報保護)
- HIPAA(医療情報保護)
- GDPR(個人情報保護)
理由4:トラフィックの制御
不要な通信を遮断することで:
- 帯域の節約
- サーバー負荷の軽減
- ネットワークパフォーマンスの向上
iptablesの基本概念:テーブル、チェーン、ルール
iptablesを理解するには、3つの概念を知る必要があります。
テーブル(Table)
テーブルは、ルールを分類するための大きな箱のようなものです。
主なテーブル:
filter(フィルター)テーブル:
- 最もよく使う
- パケットの許可・拒否を決定
- デフォルトのテーブル
nat(ナット)テーブル:
- ネットワークアドレス変換
- IPアドレスやポートの書き換え
mangle(マングル)テーブル:
- パケットの改変
- 高度な設定に使用
raw(ロー)テーブル:
- 接続追跡の設定
- 特殊な用途
チェーン(Chain)
チェーンは、パケットが通過するポイントです。
主なチェーン:
INPUT(入力):
- サーバーに入ってくる通信
- 例:外部からSSH接続、Webサイトへのアクセス
OUTPUT(出力):
- サーバーから出ていく通信
- 例:外部へのHTTPリクエスト、メール送信
FORWARD(転送):
- サーバーを経由する通信
- ルーターとして動作する場合に使用
PREROUTING(ルーティング前):
- パケットがルーティングされる前
- NAT用
POSTROUTING(ルーティング後):
- パケットがルーティングされた後
- NAT用
ルール(Rule)
ルールは、具体的な条件と動作を定義します。
構造:
条件 + 動作
例:
送信元が192.168.1.0/24で、宛先ポートが22(SSH)の場合 → 許可
ターゲット(Target)
ルールにマッチしたパケットに対する動作です。
主なターゲット:
ACCEPT(受け入れ):
- パケットを通過させる
DROP(破棄):
- パケットを破棄する
- 送信元に何も返さない
REJECT(拒否):
- パケットを拒否する
- 送信元にエラーメッセージを返す
LOG(記録):
- パケットの情報をログに記録
- 他のターゲットと組み合わせて使用
iptablesの基本的な使い方
実際にiptablesを使ってみましょう。
現在のルールを確認する
基本コマンド:
sudo iptables -L
詳細表示(推奨):
sudo iptables -L -v -n
オプションの意味:
-L
:ルールをリスト表示-v
:詳細情報を表示-n
:名前解決せずに数値で表示(高速)
出力例:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ルールの基本的な追加方法
基本構文:
sudo iptables -A チェーン名 条件 -j ターゲット
例1:特定のIPアドレスからのSSH接続を許可
sudo iptables -A INPUT -p tcp -s 192.168.1.100 --dport 22 -j ACCEPT
意味:
-A INPUT
:INPUTチェーンにルールを追加-p tcp
:プロトコルはTCP-s 192.168.1.100
:送信元IPアドレス--dport 22
:宛先ポート番号(SSH)-j ACCEPT
:許可する
ルールの削除
方法1:ルール番号で削除
# ルールに番号を付けて表示
sudo iptables -L INPUT --line-numbers
# 3番目のルールを削除
sudo iptables -D INPUT 3
方法2:ルール内容を指定して削除
sudo iptables -D INPUT -p tcp -s 192.168.1.100 --dport 22 -j ACCEPT
すべてのルールをクリア
# すべてのルールを削除
sudo iptables -F
# 特定のチェーンだけクリア
sudo iptables -F INPUT
警告: SSH経由でサーバーに接続している場合、不用意にルールをクリアすると接続が切れる可能性があります。
デフォルトポリシーの設定
チェーンのデフォルト動作を設定します。
すべて拒否(推奨):
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
意味:
- 入ってくる通信:デフォルトで拒否
- 転送通信:デフォルトで拒否
- 出ていく通信:デフォルトで許可
これで「必要な通信だけを個別に許可する」という安全な設定になります。
実践的なルール設定例
実際のサーバーでよく使うルール設定です。
例1:Webサーバーの基本設定
HTTPとHTTPSだけを許可する設定です。
# デフォルトポリシーを設定
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
# ループバック(localhost)を許可
sudo iptables -A INPUT -i lo -j ACCEPT
# 確立された接続と関連する通信を許可
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# HTTP(ポート80)を許可
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# HTTPS(ポート443)を許可
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# SSH(ポート22)を許可
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Ping(ICMP)を許可
sudo iptables -A INPUT -p icmp -j ACCEPT
例2:特定のIPアドレスだけにSSHを許可
セキュリティを強化するため、管理者のIPアドレスからのみSSHを許可します。
# 特定のIPからのSSHを許可
sudo iptables -A INPUT -p tcp -s 203.0.113.100 --dport 22 -j ACCEPT
# その他のSSH接続は拒否
sudo iptables -A INPUT -p tcp --dport 22 -j DROP
例3:特定の国からのアクセスを拒否
# 特定のIP範囲を拒否(例:203.0.113.0/24)
sudo iptables -A INPUT -s 203.0.113.0/24 -j DROP
例4:ポートスキャンを防ぐ
# 新規接続の頻度を制限(SYNフラッド対策)
sudo iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn -j DROP
例5:ログを記録する
# 拒否する前にログに記録
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 7
sudo iptables -A INPUT -j DROP
ログは /var/log/syslog
または /var/log/messages
に記録されます。
例6:データベースサーバーの保護
特定のWebサーバーからのみMySQL接続を許可します。
# Webサーバー(192.168.1.10)からのMySQLアクセスを許可
sudo iptables -A INPUT -p tcp -s 192.168.1.10 --dport 3306 -j ACCEPT
# その他からのMySQLアクセスは拒否
sudo iptables -A INPUT -p tcp --dport 3306 -j DROP
よく使うポート番号
主要なサービスのポート番号です。
サービス | ポート番号 | プロトコル |
---|---|---|
SSH | 22 | TCP |
HTTP | 80 | TCP |
HTTPS | 443 | TCP |
FTP | 20, 21 | TCP |
SMTP(メール送信) | 25 | TCP |
DNS | 53 | TCP/UDP |
POP3(メール受信) | 110 | TCP |
IMAP(メール受信) | 143 | TCP |
MySQL/MariaDB | 3306 | TCP |
PostgreSQL | 5432 | TCP |
Redis | 6379 | TCP |
MongoDB | 27017 | TCP |
iptablesの設定を保存・復元する
再起動するとルールが消えてしまうので、保存が必要です。
Ubuntu/Debian系での保存
方法1:iptables-persistentを使う(推奨)
# インストール
sudo apt install iptables-persistent
# 設定を保存
sudo netfilter-persistent save
# 設定を復元
sudo netfilter-persistent reload
インストール時に現在のルールを保存するか聞かれます。
方法2:手動で保存
# 保存
sudo iptables-save > /etc/iptables/rules.v4
# 復元
sudo iptables-restore < /etc/iptables/rules.v4
RHEL/CentOS系での保存
# 保存
sudo service iptables save
# または
sudo iptables-save > /etc/sysconfig/iptables
# 復元
sudo iptables-restore < /etc/sysconfig/iptables
起動時に自動的に読み込む
/etc/rc.local に追加(古い方法):
#!/bin/bash
iptables-restore < /etc/iptables/rules.v4
exit 0
systemdのサービスとして登録(推奨):
iptables-persistentを使えば自動的に設定されます。
iptablesのトラブルシューティング
よくある問題と解決方法です。
問題1:SSH接続ができなくなった
原因:
デフォルトポリシーをDROPにしてから、SSHを許可するルールを追加し忘れた。
予防策:
# SSH接続を許可してから、デフォルトポリシーを変更
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -P INPUT DROP
復旧方法:
- 物理的にサーバーにアクセス
- またはVPSのコンソール機能を使用
- ルールをクリアするか、適切なルールを追加
問題2:ルールの順序が間違っている
iptablesは上から順番にルールを評価します。
悪い例:
# 1. すべて拒否
sudo iptables -A INPUT -j DROP
# 2. SSHを許可(←これは実行されない!)
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
正しい例:
# 1. SSHを許可
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 2. その他は拒否
sudo iptables -A INPUT -j DROP
解決方法:
ルールを先頭に挿入:
sudo iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
-I
(Insert)は先頭に、-A
(Append)は末尾に追加します。
問題3:DROPとREJECTの使い分け
DROP:
- パケットを黙って捨てる
- 送信元は応答を待ち続ける(タイムアウトまで)
- 攻撃者に情報を与えない
REJECT:
- パケットを拒否し、エラーを返す
- 送信元はすぐに拒否されたと分かる
- 正規のユーザーには親切
推奨:
- 外部からの接続:DROP(攻撃者に情報を与えない)
- 内部からの接続:REJECT(エラーがすぐ分かる)
問題4:既存の接続が切れる
新しいルールを追加した後、既存の接続が切れる場合があります。
解決策:
# 確立された接続を許可するルールを最初に追加
sudo iptables -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
問題5:設定が再起動後に消える
iptablesのルールは一時的です。
解決策:
sudo apt install iptables-persistent
sudo netfilter-persistent save
UFWやfirewalldとの関係
iptablesの代わりに使えるツールがあります。
UFW(Uncomplicated Firewall)
特徴:
- iptablesのフロントエンド
- Ubuntuで推奨
- コマンドが簡単
比較:
iptables:
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
UFW:
sudo ufw allow 22
詳しくは別の記事で解説しています。
firewalld
特徴:
- iptablesのフロントエンド
- RHEL/CentOS/Fedoraで標準
- ゾーンベースの管理
比較:
iptables:
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
firewalld:
sudo firewall-cmd --add-service=http --permanent
nftables
特徴:
- iptablesの後継
- より柔軟な構文
- パフォーマンスが向上
Debian 10以降、RHEL 8以降で標準になりつつあります。
使い分け
iptablesを直接使うべき場合:
- 細かい制御が必要
- 既存のiptablesスクリプトがある
- 学習目的
UFW/firewalldを使うべき場合:
- シンプルな設定で十分
- 初心者
- 管理を楽にしたい
iptablesのベストプラクティス
安全で効果的な設定のためのポイントです。
1. デフォルトは拒否、必要なものだけ許可
ホワイトリスト方式:
# デフォルトは拒否
sudo iptables -P INPUT DROP
# 必要なものだけ許可
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
2. ループバックを必ず許可
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT
これを忘れると、ローカルホスト通信ができなくなります。
3. 確立された接続を許可
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
これで、サーバーから始めた通信の返答を受け取れます。
4. ルールの順序に注意
よく使うルール、具体的なルールを上に配置します。
5. ログを記録する
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables: "
ログの量が多すぎないように、limitオプションを使います。
6. テストサーバーで試す
本番環境で試す前に、テスト環境で動作確認しましょう。
7. バックアップを取る
sudo iptables-save > /root/iptables-backup-$(date +%Y%m%d).txt
8. ドキュメント化
どのルールが何のためにあるのか、コメントを残しましょう。
# Webサーバー用(HTTP/HTTPS)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
9. 定期的な見直し
不要になったルールは削除します。
10. 最小権限の原則
必要最小限のポートだけを開放しましょう。
スクリプトでiptablesを管理する
複雑な設定をスクリプト化すると便利です。
基本的なスクリプト例
#!/bin/bash
# /root/firewall.sh
# 既存のルールをクリア
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
# デフォルトポリシー
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# ループバック
iptables -A INPUT -i lo -j ACCEPT
# 確立された接続
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# SSH(特定のIPのみ)
iptables -A INPUT -p tcp -s 203.0.113.100 --dport 22 -j ACCEPT
# HTTP/HTTPS
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# ICMP(Ping)
iptables -A INPUT -p icmp -j ACCEPT
# ログ
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: "
# 設定を保存
iptables-save > /etc/iptables/rules.v4
echo "Firewall configured successfully"
実行:
sudo chmod +x /root/firewall.sh
sudo /root/firewall.sh
まとめ:iptablesはLinuxセキュリティの要
iptablesは、Linuxサーバーのセキュリティを守るための重要なツールです。
この記事のポイント:
- iptablesはLinuxのファイアウォール設定ツール
- テーブル、チェーン、ルールの3層構造
- デフォルトは拒否、必要なものだけ許可が基本
- ルールの順序が重要(上から順に評価)
- 設定は保存しないと再起動で消える
基本的なコマンド:
# ルールの確認
sudo iptables -L -v -n
# ルールの追加
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# ルールの削除
sudo iptables -D INPUT 3
# すべてクリア
sudo iptables -F
# 設定の保存
sudo iptables-save > /etc/iptables/rules.v4
覚えておきたい基本設定:
# デフォルトポリシー
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT
# ループバック許可
sudo iptables -A INPUT -i lo -j ACCEPT
# 確立された接続を許可
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# SSH許可
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
初心者が注意すべきこと:
- SSH接続を許可してから、デフォルトポリシーを変更
- ルールの順序に注意
- 必ず設定を保存
- テスト環境で試してから本番適用
- UFWやfirewalldも検討する
iptablesは最初は難しく感じるかもしれませんが、基本を理解すれば強力なセキュリティツールになります。
サーバーを安全に運用するために、ぜひこの記事を参考にiptablesを使いこなしてくださいね!
コメント