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でグレードを確認してください。