Introduction
Do you rely solely on Windows servers in your environment and lack access to third-party networking equipment? Are you looking to establish a site-to-site VPN connection to your AWS environment but unsure how to do so with your existing setup? If so, fear not, because it’s possible to achieve this with just a Windows Server acting as a router. In this blog post, we’ll guide you through the steps needed to establish a secure connection between your LAN and AWS, enabling bidirectional communication between your servers and the cloud platform.
Prerequisites
- Windows Server to be used as a router
- I am using Server Operating System 2019
- An AWS account
- An AWS IAM object with adequate rights
- An AWS VPC with an EC2 instance for testing connectivity
- I am using Terraform to create all AWS objects
AWS Tasks
Create VPC
resource "aws_vpc" "vpc" {
cidr_block = "192.168.0.0/16"
}
Create Subnets
#Private Subnet in AZ-A
resource "aws_subnet" "prisub1" {
cidr_block = 192.168.0.0/24
vpc_id = aws_vpc.vpc.id
availability_zone = data.aws_availability_zones.available.names[0]
}
#Private Subnet in AZ-B
resource "aws_subnet" "prisub2" {
cidr_block = 192.168.1.0/24
vpc_id = aws_vpc.vpc.id
availability_zone = data.aws_availability_zones.available.names[1]
}
Create and Attach Route Table
resource "aws_route_table" "routetableprivate" {
vpc_id = aws_vpc.vpc.id
}
resource "aws_route_table_association" "prisub1" {
subnet_id = aws_subnet.prisub1.id
route_table_id = aws_route_table.routetableprivate.id
}
resource "aws_route_table_association" "prisub2" {
subnet_id = aws_subnet.prisub2.id
route_table_id = aws_route_table.routetableprivate.id
}
resource "aws_vpn_gateway_route_propagation" "routepropagation" {
vpn_gateway_id = aws_vpn_gateway.vgw.id
route_table_id = aws_route_table.routetableprivate.id
}
# this will enable routing to on-premise CIDR via propagation upon successful connection to the VPN
Create and Attach Virtual Private Gateway
resource "aws_vpn_gateway" "vgw" {
vpc_id = aws_vpc.vpc.id
}
resource "aws_vpn_gateway_attachment" "vgw_attachment" {
vpc_id = aws_vpc.vpc.id
vpn_gateway_id = aws_vpn_gateway.vgw.id
}
Create Customer Gateway
resource "aws_customer_gateway" "cgw" {
bgp_asn = 65000
ip_address = "20.85.247.126" #this is your public IP address you will obtain from your Windows Server
type = "ipsec.1"
}
Create Site to Site VPN
resource "aws_vpn_connection" "vpn" {
vpn_gateway_id = aws_vpn_gateway.vgw.id
customer_gateway_id = aws_customer_gateway.cgw.id
type = "ipsec.1"
static_routes_only = true
tunnel1_preshared_key = "abc123xyz987"
#this can be anything you want and will be used when configuring the VPN on the Windows Server
}
resource "aws_vpn_connection_route" "remote" {
destination_cidr_block = "10.0.0.0/24" #this is your LAN CIDR where your Windows Server sits
vpn_connection_id = aws_vpn_connection.vpn.id
}
output "tunnel1IP" {
value = aws_vpn_connection.vpn.tunnel1_address
#this will be the AWS gateway which will be used when configuring the VPN on the Windows Server
}
Create Test EC2
data "aws_ssm_parameter" "linux" {
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
resource "aws_security_group" "sg-private" {
name = "allow_onprem"
vpc_id = aws_vpc.vpc.id
ingress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["10.0.0.0/24"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "privateLinux" {
ami = "${data.aws_ssm_parameter.linux.value}"
instance_type = "t3.medium"
subnet_id = aws_subnet.prisub1.id
vpc_security_group_ids = [aws_security_group.sg-private.id]
}
output "privateLinuxIP" {
value = aws_instance.privateLinux.private_ip
}
Windows Server Tasks
These tasks can be done via PowerShell.
Install Routing Services
Install-WindowsFeature -Name Routing -IncludeManagementTools
Install-RemoteAccess -VpnType VpnS2S
$tunnel1IP = <input the tunnel IP address terraform outputs>
$psk = 'abc123xyz987'
Add-VpnS2SInterface -Name AWS1 -Destination $tunnel1IP -Protocol IKEv2 -AuthenticationMethod PSKOnly -SharedSecret $psk -IPv4Subnet 192.168.0.0/16:100
restart-service RemoteAccess; start-sleep 15; Connect-VpnS2SInterface -Name AWS1 -PassThru
Install and Configure Remote Access with IPSec
Install-RemoteAccess -VpnType VpnS2S
$tunnel1IP = <input the tunnel IP address terraform outputs>
$psk = 'abc123xyz987'
Add-VpnS2SInterface -Name AWS1 -Destination $tunnel1IP -Protocol IKEv2 -AuthenticationMethod PSKOnly -SharedSecret $psk -IPv4Subnet 192.168.0.0/16:100
restart-service RemoteAccess; start-sleep 15; Connect-VpnS2SInterface -Name AWS1 -PassThru
Verification
As AWS never initiates a connection, you will have to initiate the connection over the Site to Site VPN. An easy way to achieve this is by pinging the test AWS instance we created via Terraform. The private IP address for the EC2 instance has been outputted when running Terraform.
ping a.b.c.d -t #continuous ping; replace a.b.c.d with the private IP address of the test EC2 instance
Confirm Inbound and Outbound connection
Get-NetIPsecQuickModeSA
You should see both, Inbound and Outbound connections from your server to AWS.
To take this one step further, you can set the default gateway for other machines in your LAN to the IP Address of your Windows Server acting as a router to AWS so that you can communicate from our LAN servers to AWS, and vice versa.
Conclusion
With Windows Server Operating Systems, establishing a Site to Site IPSec VPN tunnel to AWS is easy and allows you to efficiently direct traffic through a Windows Server functioning as a router. This solution is ideal for creating a fast and straightforward lab environment that allows you to test Site to Site VPN connectivity and dependencies that rely on a Site to Site VPN connection.