実稼働サーバーのセキュリティ強化: 包括的なチェックリスト

SSH セキュリティ、ファイアウォール ルール、WAF 構成、侵入検知、自動セキュリティ パッチ適用のベスト プラクティスを使用して、運用サーバーを強化します。

E
ECOSIRE Research and Development Team
|2026年3月16日5 分で読める1.1k 語数|

実稼働サーバーのセキュリティ強化: 包括的なチェックリスト

データ侵害を特定するまでの平均時間は 204 日です。 運用サーバーの強化により攻撃対象領域が減少するため、侵害の開始が困難になり、検出が迅速化されます。このガイドでは、SSH 構成から Web アプリケーション ファイアウォールに至るまで、すべての実稼働サーバーが実装する必要がある具体的なセキュリティ対策について説明します。

重要なポイント

  • SSH キーのみの認証と非標準ポートにより、自動化されたブルート フォース攻撃を 99% ブロックします
  • 適切に構成されたファイアウォールにより、攻撃対象領域が数千のエントリ ポイントから 10 未満に減少します
  • Web アプリケーション ファイアウォールは、SQL インジェクション、XSS、およびその他の OWASP トップ 10 攻撃をネットワーク層でブロックします。
  • 自動パッチ適用により、脆弱性は公開から数週間ではなく数時間以内に修正されます。

SSH の強化

構成

# /etc/ssh/sshd_config

# Disable password authentication
PasswordAuthentication no
ChallengeResponseAuthentication no

# Disable root login
PermitRootLogin no

# Use SSH keys only
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

# Limit login attempts
MaxAuthTries 3
MaxSessions 5

# Set idle timeout (5 minutes)
ClientAliveInterval 300
ClientAliveCountMax 0

# Restrict SSH to specific users
AllowUsers deploy ubuntu

# Disable X11 forwarding
X11Forwarding no

# Use only strong algorithms
KexAlgorithms [email protected],diffie-hellman-group-exchange-sha256
Ciphers [email protected],[email protected],[email protected]
MACs [email protected],[email protected]

フェイル 2 バン

# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600

[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600

ファイアウォール構成

UFW (Ubuntu)

# Reset and set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow SSH (consider changing port)
sudo ufw allow 22/tcp

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

# Allow specific IPs for management
sudo ufw allow from 203.0.113.10 to any port 9090 comment "Grafana"
sudo ufw allow from 203.0.113.10 to any port 9093 comment "Alertmanager"

# Deny everything else (implicit with default deny)
sudo ufw enable
sudo ufw status verbose

AWS セキュリティ グループ

# Terraform security group
resource "aws_security_group" "app" {
  name_prefix = "app-"
  vpc_id      = aws_vpc.main.id

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

  # Allow SSH from office IP only
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["203.0.113.0/24"]
    description = "SSH from office"
  }

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

# Database security group - no public access
resource "aws_security_group" "db" {
  name_prefix = "db-"
  vpc_id      = aws_vpc.main.id

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

Nginx セキュリティ ヘッダー

# Security headers for all responses
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self'; connect-src 'self' https://api.example.com;" always;

# Hide server version
server_tokens off;

# Limit request size
client_max_body_size 10m;

# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=api:10m rate=30r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;

server {
    location / {
        limit_req zone=general burst=20 nodelay;
    }

    location /api/ {
        limit_req zone=api burst=50 nodelay;
    }

    location /auth/ {
        limit_req zone=login burst=3 nodelay;
    }
}

SSL/TLS 構成

# Modern TLS configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# Session configuration
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;

# Certificate (Let's Encrypt)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

証明書の自動更新

# /etc/cron.d/certbot
0 0,12 * * * root certbot renew --quiet --post-hook "nginx -s reload"

コンテナのセキュリティ

本番環境で Docker を実行している場合は、次の追加の強化措置を適用します。

Docker デーモンのセキュリティ

{
  "userns-remap": "default",
  "no-new-privileges": true,
  "live-restore": true,
  "userland-proxy": false,
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
  }
}

コンテナのランタイム制限

# docker-compose.yml security settings
services:
  api:
    security_opt:
      - no-new-privileges:true
    read_only: true
    tmpfs:
      - /tmp
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE

重要な原則:

  • すべての機能を削除し、必要なものだけを再度追加します
  • 読み取り専用ファイルシステムにより、攻撃者によるコンテナの内容の変更を防止します
  • 新しい権限がないにより、コンテナ内での権限昇格が防止されます
  • Dockerfile 内の 非 root ユーザー (Docker 導入ガイド を参照)

画像セキュリティ

  • 公式の最小限の基本イメージ (Alpine バリアント) を使用します。
  • イメージのバージョンを固定します (運用環境では :latest を決して使用しないでください)
  • Trivy または Grype を使用してイメージをスキャンして脆弱性を見つける
  • Docker Content Trust を使用してイメージに署名する
  • アクセス制御を備えたプライベート レジストリを使用する

データベースのセキュリティ

PostgreSQL の強化

# postgresql.conf security settings
listen_addresses = 'localhost'        # Only listen on localhost
ssl = on                              # Require SSL for connections
ssl_cert_file = '/path/to/server.crt'
ssl_key_file = '/path/to/server.key'
password_encryption = scram-sha-256   # Modern password hashing
log_connections = on                  # Log all connections
log_disconnections = on               # Log disconnections
log_statement = 'ddl'                 # Log DDL statements
# pg_hba.conf - restrict connections
# TYPE  DATABASE  USER  ADDRESS      METHOD
local   all       all                scram-sha-256
host    all       all   10.0.0.0/8   scram-sha-256
hostssl all       all   0.0.0.0/0    scram-sha-256
  • PostgreSQL を公共のインターネットに公開しないでください
  • 必要最小限の権限を持つ専用データベース ユーザーを使用します。
  • 接続暗号化(SSL)を有効にする
  • 強力なパスワードポリシーを設定する
  • 定期的なバックアップ検証 (災害復旧ガイド を参照)

侵入検知

OSSEC 構成

<!-- /var/ossec/etc/ossec.conf -->
<ossec_config>
  <syscheck>
    <!-- Monitor critical files for changes -->
    <directories check_all="yes">/etc,/usr/bin,/usr/sbin</directories>
    <directories check_all="yes">/opt/app/dist</directories>

    <!-- Ignore frequently changing files -->
    <ignore>/etc/mtab</ignore>
    <ignore>/etc/resolv.conf</ignore>

    <!-- Run integrity check every 6 hours -->
    <frequency>21600</frequency>
  </syscheck>

  <rootcheck>
    <rootkit_files>/var/ossec/etc/shared/rootkit_files.txt</rootkit_files>
    <rootkit_trojans>/var/ossec/etc/shared/rootkit_trojans.txt</rootkit_trojans>
  </rootcheck>
</ossec_config>

AWS GuardDuty

resource "aws_guardduty_detector" "main" {
  enable = true

  datasources {
    s3_logs {
      enable = true
    }
    kubernetes {
      audit_logs {
        enable = true
      }
    }
  }
}

自動セキュリティパッチ適用

# Ubuntu: Enable unattended security updates
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades

# /etc/apt/apt.conf.d/50unattended-upgrades
Unattended-Upgrade::Allowed-Origins {
    "${distro_id}:${distro_codename}-security";
};

Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
Unattended-Upgrade::Mail "[email protected]";

セキュリティ強化チェックリスト

サーバーレベル

  • SSH キーのみの認証、root ログインは無効
  • デフォルト拒否ポリシーが設定されたファイアウォール
  • Fail2Ban が SSH および Web サーバーでアクティブになっています
  • 自動セキュリティ更新が有効になっています
  • 必須ではないサービスが無効になっています
  • ファイル整合性監視 (OSSEC または同等のもの)
  • 監査ログが有効になっています (auditd)

アプリケーションレベル

  • すべてのエンドポイントで TLS 1.2+、HSTS が有効化
  • 設定されたセキュリティ ヘッダー (CSP、X-Frame-Options など)
  • すべてのパブリック エンドポイントのレート制限
  • 入力検証とパラメータ化されたクエリ (sql.raw() なし)
  • HttpOnly、認証用のセキュア Cookie
  • CORS は既知の起源に限定されています
  • エラー応答はスタック トレースを漏らさない

ネットワークレベル

  • データベースは公開されていません
  • プライベート サブネット上の内部サービス
  • AWS サービスの VPC エンドポイント (パブリック インターネットなし)
  • パブリック向けエンドポイント上の WAF
  • DDoS 保護 (Cloudflare、AWS Shield)

モニタリング

  • セキュリティ イベント アラートが設定されています
  • ログは少なくとも 90 日間保存されます
  • 失敗した認証試行を監視します
  • 異常なトラフィック パターンが検出されました

よくある質問

セキュリティ監査はどのくらいの頻度で実行する必要がありますか?

四半期ごとの自動スキャン (脆弱性スキャン、依存関係の監査) と年に一度の手動侵入テスト。高リスクのアプリケーション (支払い処理、医療データ) は、6 か月ごとに外部侵入テストを行う必要があります。すべての実稼働デプロイメントには、CI/CD パイプラインに自動セキュリティ スキャンを含める必要があります。CI/CD ベスト プラクティス ガイド を参照してください。

すでにレート制限がある場合、WAF は必要ですか?

はい。レート制限は悪用を防止しますが、リクエストの内容は検査しません。 WAF は、リクエスト ペイロードを分析することで、SQL インジェクション、XSS、その他のアプリケーション層攻撃をブロックします。レート制限はフラッド防御、WAF はコンテンツ検査と考えてください。両方が必要です。

Odoo 運用サーバーを保護するにはどうすればよいですか?

上記の一般的な強化に加えて、運用環境でデータベース マネージャーを無効にし (list_db = False)、強力な admin_passwd を設定し、dbfilter を使用してデータベース アクセスを制限し、Nginx の背後で Odoo を実行し (Odoo を直接公開しないでください)、Odoo とすべてのモジュールを最新の状態に保ちます。 ECOSIRE は、マネージド ホスティング サービスの一部として Odoo セキュリティ強化 を提供します。

最も効果的なセキュリティ対策は何ですか?

すべての管理者アカウントで MFA (多要素認証) を有効にします。この単一の制御により、資格情報ベースの攻撃を 99% 阻止します。他の強化策を講じる前に、SSH (PAM 経由)、AWS コンソール、データベース管理ツール、およびアプリケーション管理パネルに MFA を実装します。


次に何が起こるか

セキュリティの強化は継続的に行われています。検出には 監視とアラート、回復力には 災害復旧、予防には CI/CD セキュリティ スキャン を組み合わせます。

セキュリティ強化に関するコンサルティングについては ECOSIRE にお問い合わせ、完全なインフラストラクチャ ロードマップについては DevOps ガイド をご覧ください。


ECOSIRE が発行 -- 企業の生産インフラの安全確保を支援します。

E

執筆者

ECOSIRE Research and Development Team

ECOSIREでエンタープライズグレードのデジタル製品を開発。Odoo統合、eコマース自動化、AI搭載ビジネスソリューションに関するインサイトを共有しています。

WhatsAppでチャット