Skip to content

Instantly share code, notes, and snippets.

@mechamogera
Last active October 24, 2023 06:36
Show Gist options
  • Save mechamogera/57a2821b9d64eb406ee85688a0af6143 to your computer and use it in GitHub Desktop.
Save mechamogera/57a2821b9d64eb406ee85688a0af6143 to your computer and use it in GitHub Desktop.
NetworkFirewallとClientVPNを伴うVPCのCloudFormationテンプレート

ここではNetworkFirewallとClientVPNを伴うVPCのCloudFormationテンプレートを管理します。 NetworkFirewallではVPC内部から外部への通信は80番と443番のみ許可し、許可ドメインのみ通信可能にしています。 ClientVPNに接続すると上記Firewall内からの通信となるので通信制限した環境でアクセスできるかの確認ができます。

テンプレートの利用手順

相互認証用の証明書のキーと証明書の作成

以下のURLを参照してサーバー証明書とキーをACMにアップロードしておきそのARNを記録しておきます。 クライアント証明書とキーのファイルはPCの適当な場所に保管しておきます。

https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/mutual.html

CloudFormationテンプレートの実行

CloudFormationテンプレートを実行します。 パラメータのACMArnは上で記録したARNを指定します。そのほか必要に応じてCIDRなどを指定します。

VPNの接続

AWS VPN Clientをインストールしておきます。 ManagementConsoleのVPCのクライアントVPNエンドポイントからクライアント設定をダウンロードします。 クライアント設定の最後の行に以下の内容を追加します。

cert [クライアントの証明書.crtファイルのパス、例:d:\\VPN\\client1.domain.tld.crt]
key [クライアントのキー.keyファイルのパス、例:d:\\VPN\\client1.domain.tld.key]

AWS VPN Clientのプロファイルの管理で上記の設定ファイルを読み込み、接続します。

参照サイト

AWSTemplateFormatVersion: 2010-09-09
Parameters:
VPCCidrBlock:
Type: String
Default: 10.0.0.0/16
PrivateSubnetCidrBlock:
Type: String
Default: 10.0.1.0/24
FirewallSubnetCidrBlock:
Type: String
Default: 10.0.2.0/24
PublicSubnetCidrBlock:
Type: String
Default: 10.0.3.0/24
VPNCidrBlock:
Type: String
Default: 10.1.0.0/16
Description: VPN CIDR must not overlap by VPC CIDR.
VPNDNS:
Type: String
Default: 10.0.0.2
Description: VPC IPv4 network range plus 2
ACMArn:
Type: String
Default:
Description: Specify the ACM ARN of the server certificate and key uploaded in the referenced steps. https://docs.aws.amazon.com/ja_jp/vpn/latest/clientvpn-admin/mutual.html
Resources:
# VPC及びサブネット
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidrBlock
PrivateSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref PrivateSubnetCidrBlock
VpcId: !Ref VPC
AvailabilityZone: !Select
- '0'
- !GetAZs
Ref: 'AWS::Region'
FirewallSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref FirewallSubnetCidrBlock
VpcId: !Ref VPC
AvailabilityZone: !Select
- '0'
- !GetAZs
Ref: 'AWS::Region'
PublicSubnet:
Type: AWS::EC2::Subnet
Properties:
CidrBlock: !Ref PublicSubnetCidrBlock
VpcId: !Ref VPC
AvailabilityZone: !Select
- '0'
- !GetAZs
Ref: 'AWS::Region'
# InternetGateway
InternetGateway:
Type: AWS::EC2::InternetGateway
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
# NATGateway
NATGateway:
Type: AWS::EC2::NatGateway
Properties:
SubnetId: !Ref PublicSubnet
AllocationId: !GetAtt NATEIP.AllocationId
NATEIP:
Type: AWS::EC2::EIP
# ネットワークファイアウォール
FirewallLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join
- ''
- - "/aws/networkfirewall-"
- !Ref AWS::StackName
RetentionInDays: 90
NetworkFirewall:
Type: AWS::NetworkFirewall::Firewall
Properties:
FirewallName: !Join
- ''
- - NetworkFirewall
- !Ref AWS::StackName
FirewallPolicyArn: !Ref NetworkFirewallPolicy
VpcId: !Ref VPC
SubnetMappings:
- SubnetId: !Ref FirewallSubnet
NetworkFirewallPolicy:
Type: AWS::NetworkFirewall::FirewallPolicy
Properties:
FirewallPolicyName: !Join
- ''
- - NetworkFirewallPolicy
- !Ref AWS::StackName
FirewallPolicy:
StatelessDefaultActions:
- 'aws:forward_to_sfe'
StatelessFragmentDefaultActions:
- 'aws:forward_to_sfe'
StatelessRuleGroupReferences:
- ResourceArn: !Ref StatelessRuleGroup
Priority: 10
StatefulRuleGroupReferences:
- ResourceArn: !Ref StatefulRuleGroup
Tags:
- Key: Name
Value: NetworkFirewallPolicy
StatefulRuleGroup:
Type: AWS::NetworkFirewall::RuleGroup
Properties:
RuleGroupName: !Join
- ""
- - "StatefulRuleGroup"
- !Ref AWS::StackName
Type: STATEFUL
Capacity: 100
RuleGroup:
RuleVariables:
IPSets:
HOME_NET:
Definition:
- !Ref VPCCidrBlock
RulesSource:
RulesSourceList:
Targets:
- ".oculus.com"
- ".facebook.com"
- ".oculuscdn.com"
- ".ap-northeast-1.amazonaws.com"
- ".fbcdn.net"
TargetTypes:
- "TLS_SNI"
- "HTTP_HOST"
GeneratedRulesType: "ALLOWLIST"
Tags:
- Key: Name
Value: AllowDomainList
StatelessRuleGroup:
Type: "AWS::NetworkFirewall::RuleGroup"
Properties:
RuleGroupName: !Join
- ""
- - "HTTPOnly"
- !Ref AWS::StackName
Type: "STATELESS"
Capacity: 100
RuleGroup:
RulesSource:
StatelessRulesAndCustomActions:
StatelessRules:
- RuleDefinition:
MatchAttributes:
Sources:
- AddressDefinition: "10.0.0.0/16"
Destinations:
- AddressDefinition: "0.0.0.0/0"
SourcePorts:
- FromPort: 0
ToPort: 65535
DestinationPorts:
- FromPort: 80
ToPort: 80
- FromPort: 443
ToPort: 443
Protocols:
- 6
Actions:
- "aws:forward_to_sfe"
Priority: 10
- RuleDefinition:
MatchAttributes:
Sources:
- AddressDefinition: "10.0.0.0/16"
Destinations:
- AddressDefinition: "0.0.0.0/0"
Actions:
- "aws:drop"
Priority: 100
NetworkFirewallLogging:
Type: AWS::NetworkFirewall::LoggingConfiguration
Properties:
FirewallArn: !Ref NetworkFirewall
LoggingConfiguration:
LogDestinationConfigs:
- LogType: ALERT
LogDestinationType: CloudWatchLogs
LogDestination:
logGroup: !Ref FirewallLogGroup
- LogType: FLOW
LogDestinationType: CloudWatchLogs
LogDestination:
logGroup: !Ref FirewallLogGroup
# PrivateSubnetのルートテーブル
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PrivateRouteTable
PrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: "0.0.0.0/0"
VpcEndpointId: !Select ["1", !Split [":", !Select ["0", !GetAtt NetworkFirewall.EndpointIds]]]
PrivateRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet
# FirewallSubnetのルートテーブル
FirewallRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: FirewallRouteTable
FirewallRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref FirewallRouteTable
DestinationCidrBlock: "0.0.0.0/0"
NatGatewayId: !Ref NATGateway
FirewallRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref FirewallRouteTable
SubnetId: !Ref FirewallSubnet
# PublicSubnetのルートテーブル
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: PublicRouteTable
PublicRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: "0.0.0.0/0"
GatewayId: !Ref InternetGateway
PublicRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: !Ref PrivateSubnetCidrBlock
VpcEndpointId: !Select ["1", !Split [":", !Select ["0", !GetAtt NetworkFirewall.EndpointIds]]]
PublicRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet
# ClientVPN
VPNLogGroup:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: !Join
- ''
- - "/aws/vpn-"
- !Ref AWS::StackName
RetentionInDays: 90
VPNLogStream:
Type: AWS::Logs::LogStream
Properties:
LogGroupName: !Ref VPNLogGroup
LogStreamName: Vpn-All
AwsClinentVPN:
Type: AWS::EC2::ClientVpnEndpoint
DependsOn: VPNLogStream
Properties:
AuthenticationOptions:
- Type: "certificate-authentication"
MutualAuthentication:
ClientRootCertificateChainArn: !Ref ACMArn
ClientCidrBlock: !Ref VPNCidrBlock
ConnectionLogOptions:
Enabled: true
CloudwatchLogGroup: !Ref VPNLogGroup
CloudwatchLogStream: !Ref VPNLogStream
Description: "private vpn"
DnsServers:
- !Ref VPNDNS
ServerCertificateArn: !Ref ACMArn
TransportProtocol: udp
TagSpecifications:
- ResourceType: "client-vpn-endpoint"
Tags:
- Key: Name
Value: "vpn"
ClientVpnTargetNetworkAssociation:
Type: AWS::EC2::ClientVpnTargetNetworkAssociation
DependsOn: PrivateSubnet
Properties:
ClientVpnEndpointId: !Ref AwsClinentVPN
SubnetId: !Ref PrivateSubnet
ClientVpnAuthorizationRule:
Type: AWS::EC2::ClientVpnAuthorizationRule
Properties:
ClientVpnEndpointId: !Ref AwsClinentVPN
AuthorizeAllGroups: true
TargetNetworkCidr: 0.0.0.0/0
ClientVpnRoute:
Type: AWS::EC2::ClientVpnRoute
DependsOn: ClientVpnTargetNetworkAssociation
Properties:
ClientVpnEndpointId: !Ref AwsClinentVPN
DestinationCidrBlock: 0.0.0.0/0
TargetVpcSubnetId: !Ref PrivateSubnet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment