mcpField
F
firewall-config

firewall-config

github.com/bagelholeセキュリティ1.2k464 回インストール23 週間前に更新
リポジトリ

firewall-config について

サーバー管理者向けのファイアウォール設定スキルで、Linux ホストのルールと AWS セキュリティグループを扱います。iptables、UFW、nftables の設定や監査、トラブルシューティングの例を提供します。

主な機能

  1. 01iptables、UFW、nftables の設定
  2. 02デフォルト拒否とアクセスルールの設定
  3. 03AWS セキュリティグループの設定
  4. 04ルールの監査と問題の調査

活用シーン

  1. 01新しいサーバーのネットワークアクセス制限
  2. 02アプリケーション層間のネットワーク分割
  3. 03iptables ルールから nftables への移行
  4. 04ルール監査やインシデント時の通信遮断

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/bagelhole/devops-security-agent-skills --skill firewall-config

インストール後、Claude Code で/firewall-configを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
iptables-rules.sh
references/
iptables-guide.md
scripts/
firewall-audit.sh
setup-ufw.sh

詳細

ファイアウォールの設定

ネットワークセキュリティのために、ホストベースおよびクラウドのファイアウォールを設定します。

このスキルを使用する場面

次の場合にこのスキルを使用します。

  • 新しいサーバーをセットアップし、ネットワークアクセスを制限する必要がある場合
  • アプリケーション階層間のネットワークセグメンテーションを実装する場合
  • AWS、GCP、または Azure リソースのクラウドセキュリティグループを設定する場合
  • iptables から nftables に移行する場合
  • コンプライアンスのために既存のファイアウォールルールを監査する場合
  • 緊急のネットワーク遮断が必要なセキュリティインシデントに対応する場合

前提条件

  • Linux ホストへの root または sudo アクセス
  • クラウドセキュリティグループ用に設定された AWS CLI
  • TCP/IP、ポート、プロトコルに関する理解
  • 必要なトラフィックフローを示すネットワーク図

iptables

デフォルト拒否による基本設定
# Flush existing rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t mangle -F

# Default policies - deny all inbound, allow outbound
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Allow established connections
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# Allow loopback
iptables -A INPUT -i lo -j ACCEPT

# Drop invalid packets
iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Allow SSH (restrict to management subnet)
iptables -A INPUT -p tcp --dport 22 -s 10.0.100.0/24 -j ACCEPT

# Allow HTTP/HTTPS from anywhere
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT

# Allow ICMP (ping) with rate limiting
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 4 -j ACCEPT

# Log dropped packets (rate limited to avoid log flooding)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPTABLES-DROP: " --log-level 4

# Save rules (Debian/Ubuntu)
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
DDoS 対策ルール
# SYN flood protection
iptables -A INPUT -p tcp --syn -m limit --limit 25/s --limit-burst 50 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP

# Limit new connections per source IP
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT

# Block port scanning (detect TCP flags abuse)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
アプリケーション固有のルール
# Web server with database backend
# Allow app servers to reach database (port 5432)
iptables -A INPUT -p tcp --dport 5432 -s 10.0.1.0/24 -j ACCEPT

# Allow monitoring (Prometheus node exporter)
iptables -A INPUT -p tcp --dport 9100 -s 10.0.200.0/24 -j ACCEPT

# DNS resolution
iptables -A INPUT -p udp --sport 53 -j ACCEPT
iptables -A INPUT -p tcp --sport 53 -j ACCEPT

# NTP
iptables -A INPUT -p udp --sport 123 -j ACCEPT

# Block specific IP (incident response)
iptables -I INPUT 1 -s 203.0.113.50 -j DROP

UFW(Uncomplicated Firewall)

# Enable UFW with default deny
ufw default deny incoming
ufw default allow outgoing
ufw enable

# Allow SSH from management network
ufw allow from 10.0.100.0/24 to any port 22 proto tcp

# Allow HTTP/HTTPS
ufw allow 80/tcp
ufw allow 443/tcp

# Allow specific application profile
ufw allow 'Nginx Full'

# Rate limit SSH (max 6 connections in 30 seconds)
ufw limit ssh

# Allow port range
ufw allow 8000:8080/tcp

# Deny specific IP
ufw deny from 203.0.113.50

# Check status
ufw status verbose
ufw status numbered

# Delete a rule by number
ufw delete 3

# Application profiles
ufw app list
ufw app info 'Nginx Full'

nftables

サーバーの完全な設定
#!/usr/sbin/nft -f
flush ruleset

# Define variables
define LAN = 10.0.0.0/16
define MGMT = 10.0.100.0/24
define MONITOR = 10.0.200.0/24

table inet filter {
  # Rate limiting set
  set rate_limit {
    type ipv4_addr
    flags dynamic,timeout
    timeout 1m
  }

  chain input {
    type filter hook input priority 0; policy drop;

    # Connection tracking
    ct state established,related accept
    ct state invalid drop

    # Loopback
    iif "lo" accept

    # ICMP and ICMPv6
    ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded } limit rate 10/second accept
    ip6 nexthdr icmpv6 icmpv6 type { echo-request, nd-neighbor-solicit, nd-router-advert } accept

    # SSH from management only
    tcp dport 22 ip saddr $MGMT accept

    # HTTP/HTTPS from anywhere
    tcp dport { 80, 443 } accept

    # Prometheus metrics from monitoring subnet
    tcp dport 9100 ip saddr $MONITOR accept

    # Rate limit new connections
    tcp flags syn limit rate over 25/second burst 50 packets drop

    # Log dropped traffic
    log prefix "nft-drop: " level warn limit rate 5/minute
  }

  chain forward {
    type filter hook forward priority 0; policy drop;
  }

  chain output {
    type filter hook output priority 0; policy accept;

    # Optional: restrict outbound to known destinations
    # tcp dport { 80, 443, 53 } accept
    # udp dport { 53, 123 } accept
    # ct state established,related accept
    # drop
  }
}

# NAT table for port forwarding
table ip nat {
  chain prerouting {
    type nat hook prerouting priority -100;
    # Forward port 8080 to internal app server
    tcp dport 8080 dnat to 10.0.1.10:8080
  }

  chain postrouting {
    type nat hook postrouting priority 100;
    oifname "eth0" masquerade
  }
}
nftables 管理コマンド
# Load configuration
nft -f /etc/nftables.conf

# List all rules
nft list ruleset

# List specific table
nft list table inet filter

# Add a rule dynamically
nft add rule inet filter input tcp dport 8443 accept

# Insert rule at position
nft insert rule inet filter input position 5 ip saddr 10.0.50.0/24 tcp dport 3306 accept

# Delete a rule by handle
nft -a list chain inet filter input  # show handles
nft delete rule inet filter input handle 15

# Monitor in real time
nft monitor

AWS セキュリティグループ

Terraform 設定
# Web tier security group
resource "aws_security_group" "web" {
  name_prefix = "web-sg-"
  vpc_id      = aws_vpc.main.id
  description = "Security group for web servers"

  ingress {
    description = "HTTPS from internet"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    description = "HTTP redirect"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  egress {
    description = "All outbound"
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name        = "web-sg"
    Environment = "production"
    ManagedBy   = "terraform"
  }
}

# App tier - only accepts traffic from web tier
resource "aws_security_group" "app" {
  name_prefix = "app-sg-"
  vpc_id      = aws_vpc.main.id
  description = "Security group for application servers"

  ingress {
    description     = "HTTP from web tier"
    from_port       = 8080
    to_port         = 8080
    protocol        = "tcp"
    security_groups = [aws_security_group.web.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

# Database tier - only accepts from app tier
resource "aws_security_group" "db" {
  name_prefix = "db-sg-"
  vpc_id      = aws_vpc.main.id
  description = "Security group for database servers"

  ingress {
    description     = "PostgreSQL from app tier"
    from_port       = 5432
    to_port         = 5432
    protocol        = "tcp"
    security_groups = [aws_security_group.app.id]
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}
AWS CLI コマンド
# Create security group
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Web server SG" \
  --vpc-id vpc-0abc123

# Add inbound rule
aws ec2 authorize-security-group-ingress \
  --group-id sg-0abc123 \
  --protocol tcp --port 443 \
  --cidr 0.0.0.0/0

# Add rule referencing another security group
aws ec2 authorize-security-group-ingress \
  --group-id sg-0db456 \
  --protocol tcp --port 5432 \
  --source-group sg-0app789

# Remove a rule
aws ec2 revoke-security-group-ingress \
  --group-id sg-0abc123 \
  --protocol tcp --port 22 \
  --cidr 0.0.0.0/0

# Describe rules
aws ec2 describe-security-group-rules \
  --filters Name=group-id,Values=sg-0abc123

ファイアウォールルール監査スクリプト

#!/bin/bash
# firewall-audit.sh - Audit current firewall rules for common issues

echo "=== Firewall Audit Report ==="
echo "Date: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "Host: $(hostname)"
echo ""

# Check if firewall is active
if command -v nft &>/dev/null; then
    echo "--- nftables rules ---"
    nft list ruleset
elif command -v iptables &>/dev/null; then
    echo "--- iptables rules ---"
    iptables -L -n -v --line-numbers
fi

echo ""
echo "--- Open ports ---"
ss -tlnp

echo ""
echo "--- Potential issues ---"

# Check for overly permissive rules
if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:22"; then
    echo "WARNING: SSH (port 22) open to 0.0.0.0/0 - restrict to management subnet"
fi

if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:3306"; then
    echo "CRITICAL: MySQL (port 3306) open to 0.0.0.0/0"
fi

if iptables -L INPUT -n 2>/dev/null | grep -q "0.0.0.0/0.*dpt:5432"; then
    echo "CRITICAL: PostgreSQL (port 5432) open to 0.0.0.0/0"
fi

# Check default policies
DEFAULT_INPUT=$(iptables -L INPUT 2>/dev/null | head -1 | grep -oP 'policy \K\w+')
if [ "$DEFAULT_INPUT" = "ACCEPT" ]; then
    echo "CRITICAL: Default INPUT policy is ACCEPT - should be DROP"
fi

トラブルシューティング

問題原因解決策
SSH から締め出されたルールの順序、または許可ルールの適用前にデフォルト拒否が適用された帯域外コンソールアクセスを使用し、最初に SSH 許可ルールを追加します
再起動後にルールが失われるルールが永続化されていないiptables-persistent をインストールするか、/etc/nftables.conf に保存します
Docker が iptables を迂回するDocker が iptables の FORWARD チェーンを変更するカスタムルールには DOCKER-USER チェーンを使用し、daemon.json で "iptables": false を設定します
nftables と iptables が競合する両方が同時に実行されているnftables に完全移行し、iptables パッケージを削除します
AWS SG のルール上限に達したSG ごとのインバウンドルール上限は 60 件プレフィックスリストを使用するか、CIDR 範囲を統合します
正当なトラフィックがブロックされるルールの順序に問題があるより具体的な許可ルールを、一般的な拒否ルールより前に配置します

ベストプラクティス

  • すべてのチェーンでデフォルト拒否ポリシーを適用します
  • ルールセットは最小限にします。必要なものだけを開放します
  • ルールを定期的に監査します(月に最低 1 回)
  • セキュリティ監視のため、拒否されたトラフィックをログに記録します
  • すべてのルールに説明とチケット参照を記載します
  • ステートフルインスペクションにはコネクショントラッキングを使用します
  • DDoS を防ぐためにインバウンド接続をレート制限します
  • 管理トラフィックとアプリケーショントラフィックを分離します
  • 本番環境の前にステージング環境でルール変更をテストします
  • 動作するルールセットのバックアップを常に保持します

関連スキル

  • linux-hardening - システムセキュリティ
  • aws-vpc - AWS ネットワーキング
  • zero-trust - アイデンティティベースのアクセスパターン
  • vpn-setup - セキュアなトンネルの設定

コメント