サイトのAPI図鑑B版
掲載情報が正確でない可能性があります。
セキュリティ・コンプライアンス

APIのTLS/SSL設定のベストプラクティス【証明書管理・HSTS・証明書ピニング】

APIのTLS/SSL設定の正しい方法(TLS 1.3・強力な暗号スイート・HSTS・Let's Encryptによる証明書自動更新・証明書ピニング)とHTTPS移行時の注意点を解説します。

#TLS#SSL#HTTPS#証明書管理

TLS/SSLはAPIセキュリティの基盤

APIの通信はHTTPSを使った暗号化が必須です。TLS/SSLの設定を適切に行うことで、通信の盗聴・改ざん・中間者攻撃(MITM)を防止できます。証明書の管理・暗号スイートの設定・HSTSの導入など、TLS設定の全体を見直しましょう。

NGINXのTLS設定(TLS 1.3対応)

server {
  listen 443 ssl http2;
  server_name api.example.com;
  
  ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
  
  # TLS 1.2と1.3のみ許可(TLS 1.0・1.1は無効化)
  ssl_protocols TLSv1.2 TLSv1.3;
  
  # 強力な暗号スイート(TLS 1.2向け)
  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 on;
  
  # OCSP Stapling(証明書失効確認の高速化)
  ssl_stapling on;
  ssl_stapling_verify on;
  resolver 8.8.8.8;
  
  # DH鍵の強化
  ssl_dhparam /etc/nginx/dhparam.pem;
  
  # セッション再利用の設定
  ssl_session_cache shared:SSL:10m;
  ssl_session_timeout 10m;
  
  # HSTSの設定(1年間・サブドメイン含む)
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  
  # その他のセキュリティヘッダー
  add_header X-Content-Type-Options nosniff;
  add_header X-Frame-Options DENY;
  add_header X-XSS-Protection "1; mode=block";
  add_header Content-Security-Policy "default-src 'none'; frame-ancestors 'none'";
}

Let's Encryptで証明書を取得・自動更新

# Certbotで証明書を取得
sudo certbot certonly --nginx -d api.example.com

# 自動更新の設定(/etc/cron.d/certbot)
0 0,12 * * * root python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew -q --post-hook "nginx -s reload"

Node.jsサーバーでのTLS設定

import https from 'https';
import fs from 'fs';
import express from 'express';

const app = express();

const httpsOptions = {
  key: fs.readFileSync('/etc/letsencrypt/live/api.example.com/privkey.pem'),
  cert: fs.readFileSync('/etc/letsencrypt/live/api.example.com/fullchain.pem'),
  minVersion: 'TLSv1.2',
  ciphers: [
    'ECDHE-ECDSA-AES128-GCM-SHA256',
    'ECDHE-RSA-AES128-GCM-SHA256',
    '!aNULL',
    '!eNULL',
    '!EXPORT',
    '!DES',
    '!RC4',
    '!MD5',
    '!PSK',
    '!SRP',
    '!CAMELLIA'
  ].join(':')
};

https.createServer(httpsOptions, app).listen(443);

APIクライアントでの証明書ピニング

// Node.jsでの証明書ピニング(HTTPSリクエスト時)
import https from 'https';
import tls from 'tls';
import { createHash } from 'crypto';

const EXPECTED_FINGERPRINT = 'sha256/base64encodedPublicKeyHash==';

const agent = new https.Agent({
  checkServerIdentity: (host, cert) => {
    const fingerprint = createHash('sha256')
      .update(cert.raw)
      .digest('base64');
    const pinnedFingerprint = `sha256/${fingerprint}`;
    
    if (pinnedFingerprint !== EXPECTED_FINGERPRINT) {
      throw new Error(`証明書のピニング検証失敗: ${host}`);
    }
    return undefined; // 検証OK
  }
});

SSL設定のグレード確認

SSL Labsの「SSL Server Test」(ssllabs.com/ssltest)でAPIドメインをスキャンして、TLS設定のグレード(A・B・C・F)を確認できます。AグレードまたはA+を目指してください。

まとめ

TLS 1.3の有効化・弱い暗号スイートの無効化・HSTSの設定は全てのAPIで実施すべき基本的なセキュリティ対策です。Let's Encryptで無料の証明書を取得し、certbotで自動更新を設定することで証明書の失効による障害を防止できます。定期的にSSL Labsでグレードを確認してください。

よくある質問

Q.TLS 1.2とTLS 1.3の違いは何ですか?

TLS 1.3は1.2と比較して、ハンドシェイクの往復回数が1-RTTに削減(1.2は2-RTT)されレイテンシが向上します。また、弱い暗号アルゴリズムが除去されセキュリティが向上しています。現代のAPIにはTLS 1.3以上を推奨します。

Q.Let's EncryptのSSL証明書を自動更新するには?

Certbotを使ってLet's Encryptの証明書を発行し、cronまたはsystemdタイマーで`certbot renew`コマンドを定期実行(週2回推奨)することで自動更新できます。NGINXまたはApacheはリロードで新しい証明書が適用されます。

Q.HSTSとは何ですか?なぜ設定すべきですか?

HSTS(HTTP Strict Transport Security)はブラウザに「このドメインへの接続は常にHTTPS経由で行う」ことを指示するHTTPレスポンスヘッダーです。設定することで最初のHTTPリクエストも含めてHTTPSにリダイレクトされ、プロトコルダウングレード攻撃(SSL Stripping)を防止できます。

関連記事