./knowledge-base/cdk/lib/waf-stack.ts
import * as cdk from "aws-cdk-lib";
import * as wafv2 from "aws-cdk-lib/aws-wafv2";
import { Construct } from "constructs";
import { ALLOWED_IPS } from "./allowed-ips";
/**
* WAF WebACL スタック(CloudFront用はus-east-1に作成必須)
* CloudFrontディストリビューションへのIPアドレス制限を提供する
*/
export class WafStack extends cdk.Stack {
public readonly webAclArn: string;
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// 許可IPアドレスセット(NHK社内ネットワーク+固定IP+リモートアクセスIP)
// IPリストは allowed-ips.ts で一元管理
const ipSet = new wafv2.CfnIPSet(this, "AllowedIPSet", {
name: "historical-research-allowed-ips",
scope: "CLOUDFRONT",
ipAddressVersion: "IPV4",
addresses: ALLOWED_IPS,
});
// CloudFront用 WAF WebACL(デフォルト: ブロック、許可IPのみ通過)
const webAcl = new wafv2.CfnWebACL(this, "CloudFrontWebACL", {
name: "historical-research-cloudfront-waf",
scope: "CLOUDFRONT",
defaultAction: { block: {} },
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: "historical-research-cloudfront-waf",
sampledRequestsEnabled: true,
},
rules: [
{
name: "AllowSpecificIPs",
priority: 1,
action: { allow: {} },
statement: {
ipSetReferenceStatement: {
arn: ipSet.attrArn,
},
},
visibilityConfig: {
cloudWatchMetricsEnabled: true,
metricName: "AllowSpecificIPs",
sampledRequestsEnabled: true,
},
},
],
});
this.webAclArn = webAcl.attrArn;
new cdk.CfnOutput(this, "WebAclArn", {
value: webAcl.attrArn,
exportName: "HistoricalResearchWebAclArn",
description: "WAF WebACL ARN for CloudFront IP restriction",
});
}
}