Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
771 lines (770 sloc) 31.1 KB
---
# Copyright 2018 widdix GmbH
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC: highly available SoftEther VPN bastion host/instance, a cloudonaut.io template, sponsored by https://github.com/ngault'
Metadata:
'AWS::CloudFormation::Interface':
ParameterGroups:
- Label:
default: 'Parent Stacks'
Parameters:
- ParentVPCStack
- ParentAlertStack
- ParentZoneStack
- Label:
default: 'EC2 Parameters'
Parameters:
- InstanceType
- KeyName
- IAMUserSSHAccess
- SystemsManagerAccess
- LogsRetentionInDays
- SubDomainNameWithDot
- Label:
default: 'VPN Parameters'
Parameters:
- VPNPSK
- VPNUserName
- VPNUserPassword
- VPNAdminPassword
Parameters:
ParentVPCStack:
Description: 'Stack name of parent VPC stack based on vpc/vpc-*azs.yaml template.'
Type: String
ParentAlertStack:
Description: 'Optional but recommended stack name of parent alert stack based on operations/alert.yaml template.'
Type: String
Default: ''
ParentZoneStack:
Description: 'Optional stack name of parent zone stack based on vpc/zone-*.yaml template.'
Type: String
Default: ''
KeyName:
Description: 'Optional key pair of the ec2-user to establish a SSH connection to SoftEther VPN.'
Type: String
Default: ''
IAMUserSSHAccess:
Description: 'Synchronize public keys of IAM users to enable personalized SSH access (Doc: https://cloudonaut.io/manage-aws-ec2-ssh-access-with-iam/).'
Type: String
Default: false
AllowedValues:
- true
- false
SystemsManagerAccess:
Description: 'Enable AWS Systems Manager agent and authorization.'
Type: String
Default: true
AllowedValues:
- true
- false
InstanceType:
Description: 'Instance type of SoftEther VPN.'
Type: String
Default: 't2.micro'
LogsRetentionInDays:
Description: 'Specifies the number of days you want to retain log events.'
Type: Number
Default: 14
AllowedValues: [1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653]
SubDomainNameWithDot:
Description: 'Name that is used to create the DNS entry with trailing dot, e.g. §{SubDomainNameWithDot}§{HostedZoneName}. Leave blank for naked (or apex and bare) domain. Requires ParentZoneStack parameter!'
Type: String
Default: 'vpn.'
VPNPSK:
Description: 'Specify the IPsec Pre-Shared Key.'
Type: String
NoEcho: true
VPNUserName:
Description: 'VPN user name.'
Type: String
VPNUserPassword:
Description: 'VPN user password.'
Type: String
NoEcho: true
VPNAdminPassword:
Description: 'SoftEther VPN admin password.'
Type: String
NoEcho: true
Mappings:
RegionMap:
'ap-south-1':
AMI: 'ami-0937dcc711d38ef3f'
'eu-west-3':
AMI: 'ami-0854d53ce963f69d8'
'eu-north-1':
AMI: 'ami-6d27a913'
'eu-west-2':
AMI: 'ami-0664a710233d7c148'
'eu-west-1':
AMI: 'ami-0fad7378adf284ce0'
'ap-northeast-2':
AMI: 'ami-018a9a930060d38aa'
'ap-northeast-1':
AMI: 'ami-0d7ed3ddb85b521a6'
'sa-east-1':
AMI: 'ami-0b04450959586da29'
'ca-central-1':
AMI: 'ami-0de8b8e4bc1f125fe'
'ap-southeast-1':
AMI: 'ami-04677bdaa3c2b6e24'
'ap-southeast-2':
AMI: 'ami-0c9d48b5db609ad6e'
'eu-central-1':
AMI: 'ami-0eaec5838478eb0ba'
'us-east-1':
AMI: 'ami-035be7bafff33b6b6'
'us-east-2':
AMI: 'ami-04328208f4f0cf1fe'
'us-west-1':
AMI: 'ami-0799ad445b5727125'
'us-west-2':
AMI: 'ami-032509850cf9ee54e'
Conditions:
HasKeyName: !Not [!Equals [!Ref KeyName, '']]
HasIAMUserSSHAccess: !Equals [!Ref IAMUserSSHAccess, 'true']
HasSystemsManagerAccess: !Equals [!Ref SystemsManagerAccess, 'true']
HasAlertTopic: !Not [!Equals [!Ref ParentAlertStack, '']]
HasZone: !Not [!Equals [!Ref ParentZoneStack, '']]
Resources:
StorageSG:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: !Sub '${AWS::StackName}-storage'
VpcId: {'Fn::ImportValue': !Sub '${ParentVPCStack}-VPC'}
SecurityGroupIngress:
- SourceSecurityGroupId: !Ref SecurityGroup
FromPort: 2049
ToPort: 2049
IpProtocol: tcp
Storage:
Type: 'AWS::EFS::FileSystem'
Properties:
FileSystemTags:
- Key: Name
Value: !Ref 'AWS::StackName'
PerformanceMode: generalPurpose
StoragePercentIOLimitTooHighAlarm:
Condition: HasAlertTopic
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmDescription: 'Average IO utilization over last 10 minutes higher than 80%'
Namespace: 'AWS/EFS'
MetricName: PercentIOLimit
Statistic: Average
Period: 600
EvaluationPeriods: 1
ComparisonOperator: GreaterThanThreshold
Threshold: 80
AlarmActions:
- {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}
Dimensions:
- Name: FileSystemId
Value: !Ref Storage
StorageBurstCreditBalanceTooLowAlarm:
Condition: HasAlertTopic
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmDescription: 'EFS file system is running out of burst credits. You can expect a significant performance drop in the next hour.'
Namespace: 'AWS/EFS'
MetricName: BurstCreditBalance
Statistic: Average
Period: 600
EvaluationPeriods: 1
ComparisonOperator: LessThanThreshold
Threshold: 192416666667 # 192 GB in Bytes (last hour where you can burst at 100 MB/sec)
AlarmActions:
- {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}
Dimensions:
- Name: FileSystemId
Value: !Ref Storage
StorageMountTargetA:
Type: 'AWS::EFS::MountTarget'
Properties:
FileSystemId: !Ref Storage
SecurityGroups:
- !Ref StorageSG
SubnetId: {'Fn::ImportValue': !Sub '${ParentVPCStack}-SubnetAPublic'}
StorageMountTargetB:
Type: 'AWS::EFS::MountTarget'
Properties:
FileSystemId: !Ref Storage
SecurityGroups:
- !Ref StorageSG
SubnetId: {'Fn::ImportValue': !Sub '${ParentVPCStack}-SubnetBPublic'}
RecordSet:
Condition: HasZone
Type: 'AWS::Route53::RecordSet'
Properties:
HostedZoneId: {'Fn::ImportValue': !Sub '${ParentZoneStack}-HostedZoneId'}
Name: !Sub
- '${SubDomainNameWithDot}${HostedZoneName}'
- SubDomainNameWithDot: !Ref SubDomainNameWithDot
HostedZoneName: {'Fn::ImportValue': !Sub '${ParentZoneStack}-HostedZoneName'}
ResourceRecords:
- !Ref EIP
TTL: '60'
Type: A
EIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
Logs:
Type: 'AWS::Logs::LogGroup'
Properties:
RetentionInDays: !Ref LogsRetentionInDays
SecurityGroup:
Type: 'AWS::EC2::SecurityGroup'
Properties:
GroupDescription: !Ref 'AWS::StackName'
SecurityGroupIngress:
- CidrIp: '0.0.0.0/0'
IpProtocol: tcp
FromPort: 443
ToPort: 443
- CidrIp: '0.0.0.0/0'
IpProtocol: tcp
FromPort: 992
ToPort: 992
- CidrIp: '0.0.0.0/0'
IpProtocol: tcp
FromPort: 5555
ToPort: 5555
- CidrIp: 0.0.0.0/0
IpProtocol: udp
FromPort: 500
ToPort: 500
- CidrIp: 0.0.0.0/0
IpProtocol: udp
FromPort: 1194
ToPort: 1194
- CidrIp: 0.0.0.0/0
IpProtocol: udp
FromPort: 4500
ToPort: 4500
VpcId: {'Fn::ImportValue': !Sub '${ParentVPCStack}-VPC'}
SecurityGroupInSSHBastion:
Type: 'AWS::EC2::SecurityGroupIngress'
Properties:
GroupId: !Ref SecurityGroup
IpProtocol: tcp
FromPort: 22
ToPort: 22
SourceSecurityGroupId: !Ref SecurityGroup
InstanceProfile:
Type: 'AWS::IAM::InstanceProfile'
Properties:
Roles:
- !Ref IAMRole
IAMRole:
Type: 'AWS::IAM::Role'
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: 'ec2.amazonaws.com'
Action: 'sts:AssumeRole'
ManagedPolicyArns: !If [HasSystemsManagerAccess, ['arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM'], []] # TODO get rid of managed policy
Policies:
- PolicyName: 'ec2'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'ec2:AssociateAddress'
- 'ec2:ModifyInstanceAttribute'
Resource: '*'
- PolicyName: logs
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- 'logs:CreateLogStream'
- 'logs:PutLogEvents'
- 'logs:DescribeLogStreams'
Resource: !GetAtt 'Logs.Arn'
IAMPolicySSHAccess:
Type: 'AWS::IAM::Policy'
Condition: HasIAMUserSSHAccess
Properties:
Roles:
- !Ref IAMRole
PolicyName: iam
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action: 'iam:ListUsers'
Resource: '*'
- Effect: Allow
Action:
- 'iam:ListSSHPublicKeys'
- 'iam:GetSSHPublicKey'
Resource: !Sub 'arn:aws:iam::${AWS::AccountId}:user/*'
LaunchConfiguration:
Type: 'AWS::AutoScaling::LaunchConfiguration'
Metadata:
'AWS::CloudFormation::Init':
configSets:
default: !If [HasIAMUserSSHAccess, [awslogs, ssh-access, mount, install, config], [awslogs, mount, install, config]]
awslogs:
packages:
yum:
awslogs: []
files:
'/etc/awslogs/awscli.conf':
content: !Sub |
[default]
region = ${AWS::Region}
[plugins]
cwlogs = cwlogs
mode: '000644'
owner: root
group: root
'/etc/awslogs/awslogs.conf':
content: !Sub |
[general]
state_file = /var/lib/awslogs/agent-state
[/var/log/amazon/ssm/amazon-ssm-agent.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/amazon/ssm/amazon-ssm-agent.log
log_stream_name = {instance_id}/var/log/amazon/ssm/amazon-ssm-agent.log
log_group_name = ${Logs}
[/var/log/amazon/ssm/errors.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/amazon/ssm/errors.log
log_stream_name = {instance_id}/var/log/amazon/ssm/errors.log
log_group_name = ${Logs}
[/var/log/audit/audit.log]
file = /var/log/audit/audit.log
log_stream_name = {instance_id}/var/log/audit/audit.log
log_group_name = ${Logs}
[/var/log/awslogs.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/awslogs.log
log_stream_name = {instance_id}/var/log/awslogs.log
log_group_name = ${Logs}
[/var/log/boot.log]
file = /var/log/boot.log
log_stream_name = {instance_id}/var/log/boot.log
log_group_name = ${Logs}
[/var/log/cfn-hup.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/cfn-hup.log
log_stream_name = {instance_id}/var/log/cfn-hup.log
log_group_name = ${Logs}
[/var/log/cfn-init-cmd.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/cfn-init-cmd.log
log_stream_name = {instance_id}/var/log/cfn-init-cmd.log
log_group_name = ${Logs}
[/var/log/cfn-init.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/cfn-init.log
log_stream_name = {instance_id}/var/log/cfn-init.log
log_group_name = ${Logs}
[/var/log/cfn-wire.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/cfn-wire.log
log_stream_name = {instance_id}/var/log/cfn-wire.log
log_group_name = ${Logs}
[/var/log/cloud-init-output.log]
file = /var/log/cloud-init-output.log
log_stream_name = {instance_id}/var/log/cloud-init-output.log
log_group_name = ${Logs}
[/var/log/cloud-init.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/cloud-init.log
log_stream_name = {instance_id}/var/log/cloud-init.log
log_group_name = ${Logs}
[/var/log/cron]
datetime_format = %b %d %H:%M:%S
file = /var/log/cron
log_stream_name = {instance_id}/var/log/cron
log_group_name = ${Logs}
[/var/log/dmesg]
file = /var/log/dmesg
log_stream_name = {instance_id}/var/log/dmesg
log_group_name = ${Logs}
[/var/log/grubby_prune_debug]
file = /var/log/grubby_prune_debug
log_stream_name = {instance_id}/var/log/grubby_prune_debug
log_group_name = ${Logs}
[/var/log/maillog]
datetime_format = %b %d %H:%M:%S
file = /var/log/maillog
log_stream_name = {instance_id}/var/log/maillog
log_group_name = ${Logs}
[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
log_stream_name = {instance_id}/var/log/messages
log_group_name = ${Logs}
[/var/log/secure]
datetime_format = %b %d %H:%M:%S
file = /var/log/secure
log_stream_name = {instance_id}/var/log/secure
log_group_name = ${Logs}
[/var/log/yum.log]
datetime_format = %b %d %H:%M:%S
file = /var/log/yum.log
log_stream_name = {instance_id}/var/log/yum.log
log_group_name = ${Logs}
mode: '000644'
owner: root
group: root
'/etc/awslogs/config/efs.conf':
content: !Sub |
[/var/log/amazon/efs/mount.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/amazon/efs/mount.log
log_stream_name = {instance_id}/var/log/amazon/efs/mount.log
log_group_name = ${Logs}
mode: '000644'
owner: root
group: root
'/etc/awslogs/config/vpnserver.conf':
content: !Sub |
[/usr/local/vpnserver/packet_log/DEFAULT/pkt.log]
datetime_format = %Y-%m-%d,%H:%M:%S
file = /usr/local/vpnserver/packet_log/DEFAULT/pkt_*.log
log_stream_name = {instance_id}/usr/local/vpnserver/packet_log/DEFAULT/pkt.log
log_group_name = ${Logs}
[/usr/local/vpnserver/security_log/DEFAULT/sec.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /usr/local/vpnserver/security_log/DEFAULT/sec_*.log
log_stream_name = {instance_id}/usr/local/vpnserver/security_log/DEFAULT/sec.log
log_group_name = ${Logs}
[/usr/local/vpnserver/server_log/vpn.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /usr/local/vpnserver/server_log/vpn_*.log
log_stream_name = {instance_id}/usr/local/vpnserver/server_log/vpn.log
log_group_name = ${Logs}
mode: '000644'
owner: root
group: root
services:
sysvinit:
awslogsd:
enabled: true
ensureRunning: true
packages:
yum:
- awslogs
files:
- '/etc/awslogs/awslogs.conf'
- '/etc/awslogs/awscli.conf'
- '/etc/awslogs/config/efs.conf'
- '/etc/awslogs/config/vpnserver.conf'
ssh-access:
files:
'/opt/authorized_keys_command.sh':
content: |
#!/bin/bash -e
if [ -z "$1" ]; then
exit 1
fi
UnsaveUserName="$1"
UnsaveUserName=${UnsaveUserName//".plus."/"+"}
UnsaveUserName=${UnsaveUserName//".equal."/"="}
UnsaveUserName=${UnsaveUserName//".comma."/","}
UnsaveUserName=${UnsaveUserName//".at."/"@"}
aws iam list-ssh-public-keys --user-name "$UnsaveUserName" --query "SSHPublicKeys[?Status == 'Active'].[SSHPublicKeyId]" --output text | while read -r KeyId; do
aws iam get-ssh-public-key --user-name "$UnsaveUserName" --ssh-public-key-id "$KeyId" --encoding SSH --query "SSHPublicKey.SSHPublicKeyBody" --output text
done
mode: '000755'
owner: root
group: root
'/opt/import_users.sh':
content: |
#!/bin/bash -e
aws iam list-users --query "Users[].[UserName]" --output text | while read User; do
SaveUserName="$User"
SaveUserName=${SaveUserName//"+"/".plus."}
SaveUserName=${SaveUserName//"="/".equal."}
SaveUserName=${SaveUserName//","/".comma."}
SaveUserName=${SaveUserName//"@"/".at."}
if [ "${#SaveUserName}" -le "32" ]; then
if ! id -u "$SaveUserName" >/dev/null 2>&1; then
#sudo will read each file in /etc/sudoers.d, skipping file names that end in ‘~’ or contain a ‘.’ character to avoid causing problems with package manager or editor temporary/backup files.
SaveUserFileName=$(echo "$SaveUserName" | tr "." " ")
/usr/sbin/useradd "$SaveUserName"
echo "$SaveUserName ALL=(ALL) NOPASSWD:ALL" > "/etc/sudoers.d/$SaveUserFileName"
fi
else
echo "Can not import IAM user ${SaveUserName}. User name is longer than 32 characters."
fi
done
mode: '000755'
owner: root
group: root
'/etc/cron.d/import_users':
content: |
*/10 * * * * root /opt/import_users.sh
mode: '000644'
owner: root
group: root
commands:
'a_configure_sshd_command':
command: 'sed -e ''/AuthorizedKeysCommand / s/^#*/#/'' -i /etc/ssh/sshd_config; echo -e ''\nAuthorizedKeysCommand /opt/authorized_keys_command.sh'' >> /etc/ssh/sshd_config'
test: '! grep -q ''^AuthorizedKeysCommand /opt/authorized_keys_command.sh'' /etc/ssh/sshd_config'
'b_configure_sshd_commanduser':
command: 'sed -e ''/AuthorizedKeysCommandUser / s/^#*/#/'' -i /etc/ssh/sshd_config; echo -e ''\nAuthorizedKeysCommandUser nobody'' >> /etc/ssh/sshd_config'
test: '! grep -q ''^AuthorizedKeysCommandUser nobody'' /etc/ssh/sshd_config'
'c_import_users':
command: './import_users.sh'
cwd: '/opt'
services:
sysvinit:
sshd:
enabled: true
ensureRunning: true
commands:
- 'a_configure_sshd_command'
- 'b_configure_sshd_commanduser'
mount:
packages:
yum:
'amazon-efs-utils': []
commands:
'a_mount':
command: !Sub 'mkdir /mnt/storage && echo "${Storage} /mnt/storage efs defaults,_netdev 0 0" >> /etc/fstab && mount -a -t efs'
test: '[ ! -d /mnt/storage ]'
'b_mkdir_backup':
command: 'mkdir backup.vpn_server.config && chmod 700 backup.vpn_server.config'
cwd: '/mnt/storage'
test: '[ ! -d /mnt/storage/backup.vpn_server.config ]'
install:
sources:
'/usr/local/src/softether': 'http://www.softether-download.com/files/softether/v4.29-9680-rtm-2019.02.28-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.29-9680-rtm-2019.02.28-linux-x64-64bit.tar.gz'
files:
'/etc/init.d/vpnserver':
content: |
#!/bin/sh
# chkconfig: 2345 99 01
# description: SoftEther VPN Server
DAEMON=/usr/local/vpnserver/vpnserver
LOCK=/var/lock/subsys/vpnserver
test -x $DAEMON || exit 0
case "$1" in
start)
$DAEMON start
touch $LOCK
;;
stop)
$DAEMON stop
rm $LOCK
;;
restart)
$DAEMON stop
sleep 3
$DAEMON start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
mode: '000755'
owner: root
group: root
commands:
'a_install_dev_tools':
command: 'yum -y group install "Development Tools"' # can this be reduced to yum install gcc make? see 7.3.3 https://www.softether.org/4-docs/1-manual/7._Installing_SoftEther_VPN_Server/7.3_Install_on_Linux_and_Initial_Configurations
test: '[ ! -d /usr/local/vpnserver ]'
'b_make':
command: 'yes 1 | make'
cwd: '/usr/local/src/softether/vpnserver'
test: '[ ! -d /usr/local/vpnserver ]'
'c_chmod':
command: 'chmod 600 * && chmod 700 vpncmd vpnserver'
cwd: '/usr/local/src/softether/vpnserver'
test: '[ ! -d /usr/local/vpnserver ]'
'd_move':
command: 'mv /usr/local/src/softether/vpnserver /usr/local/vpnserver'
test: '[ ! -d /usr/local/vpnserver ]'
'e_mount_config_backup':
command: 'mkdir /usr/local/vpnserver/backup.vpn_server.config && mount --bind /mnt/storage/backup.vpn_server.config /usr/local/vpnserver/backup.vpn_server.config'
test: '[ ! -d /usr/local/vpnserver/backup.vpn_server.config ]'
'f_link_config':
command: 'ln -s /mnt/storage/vpn_server.config /usr/local/vpnserver/vpn_server.config'
test: '[ ! -f /usr/local/vpnserver/vpn_server.config ]'
services:
sysvinit:
vpnserver:
enabled: true
ensureRunning: true
config:
files:
'/etc/cfn/cfn-hup.conf':
content: !Sub |
[main]
stack=${AWS::StackId}
region=${AWS::Region}
interval=1
mode: '000400'
owner: root
group: root
'/etc/cfn/hooks.d/cfn-auto-reloader.conf':
content: !Sub |
[cfn-auto-reloader-hook]
triggers=post.update
path=Resources.LaunchConfiguration.Metadata.AWS::CloudFormation::Init
action=/opt/aws/bin/cfn-init --verbose --stack=${AWS::StackName} --region=${AWS::Region} --resource=LaunchConfiguration
runas=root
commands:
'a_await_vpnserver':
command: 'while ! (echo > /dev/tcp/localhost/443) >/dev/null 2>&1; do sleep 10; done'
'b_set_password':
command: !Sub './vpncmd /server localhost /cmd ServerPasswordSet ${VPNAdminPassword} && touch /mnt/storage/config_set_password_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_set_password_done.txt ]'
'c_create_local_bridge': # tap prevents high cpu usage http://forum.softether.org/viewtopic.php?t=2922
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /cmd BridgeCreate DEFAULT /device:tap /TAP:yes && touch /mnt/storage/config_create_local_bridge_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_create_local_bridge_done.txt ]'
'd_disable_kernel_mode_secure_nat': # prevents high CPU usage http://www.vpnusers.com/viewtopic.php?f=7&t=1216&p=10815
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /adminhub:DEFAULT /cmd ExtOptionSet DisableKernelModeSecureNAT /VALUE:1 && touch /mnt/storage/config_disable_kernel_mode_secure_nat_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_disable_kernel_mode_secure_nat_done.txt ]'
'e_enable_secure_nat':
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /adminhub:DEFAULT /cmd SecureNatEnable && touch /mnt/storage/config_enable_secure_nat_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_enable_secure_nat_done.txt ]'
'f_set_dhcp_set': # needed for split tunnel
command: !Sub
- './vpncmd /server localhost /password:${VPNAdminPassword} /adminhub:DEFAULT /cmd DhcpSet /START:192.168.30.10 /END:192.168.30.200 /MASK:255.255.255.0 /EXPIRE:7200 /GW:none /DNS:192.168.30.1 /DNS2:none /DOMAIN:none /PUSHROUTE:${VPCCidrBlock}/192.168.30.1 /LOG:yes && touch /mnt/storage/config_disable_defaut_gateway_client_notification_done.txt'
- VPNAdminPassword: !Ref VPNAdminPassword
VPCCidrBlock: {'Fn::ImportValue': !Sub '${ParentVPCStack}-CidrBlock'}
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_disable_defaut_gateway_client_notification_done.txt ]'
'g_enable_ipsec_psk':
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /cmd IPsecEnable /L2TP:yes /L2TPRAW:yes /ETHERIP:no /PSK:${VPNPSK} /DEFAULTHUB:DEFAULT && touch /mnt/storage/config_enable_ipsec_psk_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_enable_ipsec_psk_done.txt ]'
'h_create_user':
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /adminhub:DEFAULT /cmd UserCreate ${VPNUserName} /GROUP:none /REALNAME:none /NOTE:none && touch /mnt/storage/config_create_user_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_create_user_done.txt ]'
'i_set_user_password':
command: !Sub './vpncmd /server localhost /password:${VPNAdminPassword} /adminhub:DEFAULT /cmd UserPasswordSet ${VPNUserName} /PASSWORD:${VPNUserPassword} && touch /mnt/storage/config_set_user_password_done.txt'
cwd: '/usr/local/vpnserver'
test: '[ ! -f /mnt/storage/config_set_user_password_done.txt ]'
services:
sysvinit:
cfn-hup:
enabled: true
ensureRunning: true
files:
- '/etc/cfn/cfn-hup.conf'
- '/etc/cfn/hooks.d/cfn-auto-reloader.conf'
amazon-ssm-agent:
enabled: !If [HasSystemsManagerAccess, true, false]
ensureRunning: !If [HasSystemsManagerAccess, true, false]
Properties:
AssociatePublicIpAddress: true
EbsOptimized: false
IamInstanceProfile: !Ref InstanceProfile
ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI]
InstanceType: !Ref InstanceType
SecurityGroups:
- !Ref SecurityGroup
KeyName: !If [HasKeyName, !Ref KeyName, !Ref 'AWS::NoValue']
UserData:
'Fn::Base64': !Sub |
#!/bin/bash -ex
trap '/opt/aws/bin/cfn-signal -e 1 --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup' ERR
INSTANCEID=$(curl -s -m 60 http://169.254.169.254/latest/meta-data/instance-id)
aws --region ${AWS::Region} ec2 associate-address --instance-id $INSTANCEID --allocation-id ${EIP.AllocationId}
aws --region ${AWS::Region} ec2 modify-instance-attribute --instance-id $INSTANCEID --source-dest-check "{\"Value\": false}"
/opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource LaunchConfiguration --region ${AWS::Region}
/opt/aws/bin/cfn-signal -e 0 --region ${AWS::Region} --stack ${AWS::StackName} --resource AutoScalingGroup
AutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
DependsOn:
- StorageMountTargetA
- StorageMountTargetB
Properties:
LaunchConfigurationName: !Ref LaunchConfiguration
MaxSize: '1'
MinSize: '1'
Tags:
- Key: Name
Value: 'SoftEther VPN'
PropagateAtLaunch: true
NotificationConfigurations: !If
- HasAlertTopic
- - NotificationTypes:
- 'autoscaling:EC2_INSTANCE_LAUNCH_ERROR'
- 'autoscaling:EC2_INSTANCE_TERMINATE_ERROR'
TopicARN: {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}
- []
VPCZoneIdentifier:
- {'Fn::ImportValue': !Sub '${ParentVPCStack}-SubnetAPublic'}
- {'Fn::ImportValue': !Sub '${ParentVPCStack}-SubnetBPublic'}
CreationPolicy:
ResourceSignal:
Count: 1
Timeout: PT10M
UpdatePolicy:
AutoScalingRollingUpdate:
PauseTime: PT10M
SuspendProcesses:
- HealthCheck
- ReplaceUnhealthy
- AZRebalance
- AlarmNotification
- ScheduledActions
WaitOnResourceSignals: true
CPUTooHighAlarm:
Condition: HasAlertTopic
Type: 'AWS::CloudWatch::Alarm'
Properties:
AlarmDescription: 'Average CPU utilization over last 10 minutes higher than 80%'
Namespace: 'AWS/EC2'
MetricName: CPUUtilization
Statistic: Average
Period: 600
EvaluationPeriods: 1
ComparisonOperator: GreaterThanThreshold
Threshold: 80
AlarmActions:
- {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}
Dimensions:
- Name: AutoScalingGroupName
Value: !Ref AutoScalingGroup
Outputs:
TemplateID:
Description: 'cloudonaut.io template id.'
Value: 'vpc/vpc-vpn-bastion'
TemplateVersion:
Description: 'cloudonaut.io template version.'
Value: '__VERSION__'
StackName:
Description: 'Stack name.'
Value: !Sub '${AWS::StackName}'
SecurityGroup:
Description: 'Use this Security Group to reference incoming traffic from SoftEther VPN.'
Value: !Ref SecurityGroup
Export:
Name: !Sub '${AWS::StackName}-SecurityGroup'
IPAddress:
Description: 'The public IP address of SoftEther VPN.'
Value: !Ref EIP
Export:
Name: !Sub '${AWS::StackName}-IPAddress'
You can’t perform that action at this time.