Skip to content

Commit

Permalink
Initial commit.
Browse files Browse the repository at this point in the history
  • Loading branch information
“Alexander committed Nov 4, 2023
1 parent 4894003 commit 5662209
Show file tree
Hide file tree
Showing 23 changed files with 1,206 additions and 3 deletions.
230 changes: 227 additions & 3 deletions README.md

Large diffs are not rendered by default.

59 changes: 59 additions & 0 deletions compute.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# =================
# Compute Resources
# =================

# Define SGW Folder
data "yandex_resourcemanager_folder" "sgw_folder" {
cloud_id = var.cloud_id
name = var.yc_sgw.folder_name
}

# Define the VM image for SGW
data "yandex_compute_image" "sgw_image" {
folder_id = var.yc_sgw.image_folder_id
name = var.yc_sgw.image_name
# family = container-optimized-image
}

# Create SGW VM
resource "yandex_compute_instance" "sgw" {
folder_id = data.yandex_resourcemanager_folder.sgw_folder.id
name = lower(var.yc_sgw.name)
hostname = lower(var.yc_sgw.name)
platform_id = "standard-v3"
zone = var.yc_sgw.zone
labels = var.labels
resources {
cores = 2
memory = 4
}

boot_disk {
initialize_params {
image_id = data.yandex_compute_image.sgw_image.id
}
}

network_interface {
subnet_id = yandex_vpc_subnet.sgw_subnet.id
ip_address = var.yc_sgw.inside_ip
nat = true
nat_ip_address = yandex_vpc_address.sgw_public_ip.external_ipv4_address[0].address
security_group_ids = [yandex_vpc_security_group.sgw_sg.id]
}

metadata = {
user-data = templatefile("${path.module}/sgw-vm-init.tpl", {
ADMIN_NAME = var.yc_sgw.admin_name
ADMIN_SSH_KEY = file(var.yc_sgw.admin_key_path)

REMOTE_SGW_IP = var.remote_sgw.outside_ip
POLICY_NAME = var.ipsec_policy.policy_name
IKE_PROPOSAL = var.ipsec_policy.ike_proposal
ESP_PROPOSAL = var.ipsec_policy.esp_proposal
PSK = var.ipsec_policy.psk

ROUTE_LIST = trim("%{for prefix in var.remote_subnets}ip route add ${prefix} dev ipsec0;%{~endfor~}", ";")
})
}
}
1 change: 1 addition & 0 deletions examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.txt
5 changes: 5 additions & 0 deletions examples/env-yc.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

export TF_VAR_cloud_id=$(yc config get cloud-id)
export TF_VAR_folder_id=$(yc config get folder-id)
export YC_TOKEN=$(yc iam create-token)
83 changes: 83 additions & 0 deletions examples/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# ============================================================
# Example of using IPsec-SGW Terraform module for Yandex Cloud
# ============================================================

# ==================================
# Terraform & Provider Configuration
# ==================================
terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
version = "~> 0.89.0"
}
null = {
source = "hashicorp/null"
version = "~> 3.2.1"
}
local = {
source = "hashicorp/local"
version = "~> 2.4.0"
}
}
}

# =====================
# Call IPsec-SGW module
# =====================
module "ipsec-sgw" {
source = "../"
cloud_id = var.cloud_id
folder_id = var.folder_id
labels = { tag = "ipsec-sgw" }

# ==================================================================
# IPsec profile for both sides (strongSwan keywords values)
# https://docs.strongswan.org/docs/5.9/config/IKEv2CipherSuites.html
# ==================================================================
ipsec_policy = {
policy_name = "yc-ipsec"
ike_proposal = "aes128gcm16-prfsha256-ecp256"
esp_proposal = "aes128gcm16"
psk = "Sup@385paS4"
}

# =================================
# Yandex Cloud side: strongSwan SGW
# =================================
yc_subnets = {
net_name = "default"
rt_name = "sgw-rt"
rt_internet_access = false
force_subnets_update = false
prefix_list = ["10.128.0.0/24", "10.129.0.0/24"]
}

yc_sgw = {
name = "yc-sgw"
folder_name = "folder1"
image_folder_id = "b1g4n62gio32v96mdvrb"
image_name = "ipsec-sgw"
zone = "ru-central1-a"
subnet = "192.168.200.0/24"
inside_ip = "192.168.200.10"
admin_name = "admin"
admin_key_path = "~/.ssh/id_ed25519.pub"
}

# =================================
# Remote side: 3rd party IPsec SGW
# =================================
remote_subnets = ["10.10.201.0/24", "10.10.202.0/24"]

remote_sgw = {
name = "Router1"
type = "cisco-iosxe"
outside_ip = "51.250.13.97"
}
}

output "yc_rt_cmd" {
description = "yc cli command for update the routing table."
value = module.ipsec-sgw.yc_rt_cmd
}
12 changes: 12 additions & 0 deletions examples/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# ============================================================
# Example of using IPsec-SGW Terraform module for Yandex Cloud
# Input variables for this example.
# ============================================================

variable "cloud_id" {
description = "YC cloud-id. Taken from environment variable."
}

variable "folder_id" {
description = "YC folder-id. Taken from environment variable."
}
3 changes: 3 additions & 0 deletions images/sgw-diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions ipsec-configs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ==================================================================
# IPsec configuration file builder for the selected remote SGW type.
# ==================================================================

# Create an SGW configuration file for the remote site
locals {

subnets_pairs = flatten([
for key in var.yc_subnets.prefix_list : [
for val in var.remote_subnets : {
yc = key
remote = val
}
]
])

remote_ipsec_config = templatefile("${path.module}/templates/ipsec-${var.remote_sgw.type}.tpl", {
SGW_NAME = var.yc_sgw.name
YC_SGW_IP = "${yandex_vpc_address.sgw_public_ip.external_ipv4_address[0].address}"
REMOTE_SGW_IP = var.remote_sgw.outside_ip
POLICY_NAME = var.ipsec_policy.policy_name
IKE_PROPOSAL = var.ipsec_policy.ike_proposal
ESP_PROPOSAL = var.ipsec_policy.esp_proposal
PSK = var.ipsec_policy.psk
# For remote SGW's which are supported the Routed mode (IPsec Tunnel interface)
YC_SUBNETS = var.yc_subnets.prefix_list
# For remote SGW's which are NOT SUPPORTED the Routed mode, e.g. Mikrotik
SUBNETS_PAIRS = local.subnets_pairs
})
}

resource "local_file" "remote_ipsec_config" {
content = local.remote_ipsec_config
filename = "${var.remote_sgw.name}-config.txt"
}
16 changes: 16 additions & 0 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# =======================================
# IPsec Security Gateway (SGW) deployment
# Outputs
# =======================================

# ipsec-configs
output "subnets_pairs" {
description = "Subnet pairs for Remote SGW which is not supported Route-based policies, such as Mikrotik CHR."
value = local.subnets_pairs
}

# vpc
output "yc_rt_cmd" {
description = "Provide yc CLI command string for change traffic flow via route-table manually."
value = var.yc_subnets.force_subnets_update ? "true" : local.yc_rt_cmd
}
20 changes: 20 additions & 0 deletions providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# ==================================
# Terraform & Provider Configuration
# ==================================

terraform {
required_providers {
yandex = {
source = "yandex-cloud/yandex"
version = "~> 0.89.0"
}
null = {
source = "hashicorp/null"
version = "~> 3.2.1"
}
local = {
source = "hashicorp/local"
version = "~> 2.4.0"
}
}
}
51 changes: 51 additions & 0 deletions samples/cisco-asa-sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@

! Cisco ASA with Routed mode (Tunnel) <-- IPSEC --> strongSwan Instance
!
! Tested with Cisco ASAv v9.15(1)10
!
! Should be work with Cisco ASA/ASAv families
!

!
crypto ikev2 enable outside
!
crypto ikev2 policy 1

encryption aes-gcm
integrity null
group 19
prf sha256
!
crypto ipsec ikev2 ipsec-proposal IKE2-PROPOSAL

protocol esp encryption aes-gcm protocol esp integrity null
!
crypto ipsec profile IKE2-PROFILE
set ikev2 ipsec-proposal IKE2-PROPOSAL
set security-association lifetime kilobytes unlimited
set security-association lifetime seconds 50000
!
group-policy IKE2-POLICY internal
group-policy IKE2-POLICY attributes
vpn-tunnel-protocol ikev2
!
tunnel-group 158.160.45.51 type ipsec-l2l
tunnel-group 158.160.45.51 general-attributes
default-group-policy IKE2-POLICY
!
tunnel-group 158.160.45.51 ipsec-attributes
ikev2 remote-authentication pre-shared-key OcsIc-321
ikev2 local-authentication pre-shared-key OcsIc-321
!
interface Tunnel10
nameif vti
ip address 169.254.254.1 255.255.255.252
tunnel source interface outside
tunnel destination 158.160.45.51
tunnel mode ipsec ipv4
tunnel protection ipsec profile IKE2-PROFILE
!

! Route YC prefixes via IPsec Tunnel interface
route vti 10.128.0.0 255.255.255.0 169.254.254.2 1
route vti 10.129.0.0 255.255.255.0 169.254.254.2 1
49 changes: 49 additions & 0 deletions samples/cisco-iosxe-sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

! Cisco IOS-XE with Routed mode (Tunnel) <-- IPSEC --> strongSwan Instance
!
! Tested with Cisco Catalyst 8000v (IOS-XE v17.06.02).
!
! Should be work with Cisco CSR 1000v, Cisco ASR 1000,
! Cisco ISR 4000 and other Cisco IOS-XE platforms.

!
crypto ikev2 proposal IKE2-PROPOSAL
encryption aes-gcm-128
prf sha256
group 19
!
crypto ikev2 policy IKE2-POLICY
match fvrf any
proposal IKE2-PROPOSAL
!
crypto ikev2 keyring IKE2-KEYS
peer YC-SGW
address 62.84.117.252
pre-shared-key 0 OcsIc-321
!
crypto ikev2 profile IKE2-PROFILE
match identity remote any
authentication remote pre-share
authentication local pre-share
keyring local IKE2-KEYS
dpd 10 3 on-demand
!
crypto ipsec transform-set TS esp-gcm 128
mode tunnel
!
crypto ipsec profile IPSEC-PROFILE
set transform-set TS
set ikev2-profile IKE2-PROFILE
!
interface Tunnel10
description == IPSEC-Tunnel ==
ip unnumbered GigabitEthernet2
tunnel source GigabitEthernet2
tunnel mode ipsec ipv4
tunnel destination 62.84.117.252
tunnel protection ipsec profile IPSEC-PROFILE
!

! Route YC prefixes via IPsec Tunnel interface
ip route 10.128.0.0 255.255.255.0 Tunnel10
ip route 10.129.0.0 255.255.255.0 Tunnel10
35 changes: 35 additions & 0 deletions samples/mikrotik-chr-sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# ================================================
# Mikrotik CHR RouterOS 7.x
# https://help.mikrotik.com/docs/display/ROS/IPsec
# ================================================

# All IPsec firewall filters should be configured BEFORE ANY action=drop RULES !
/ip firewall filter
add action=accept chain=input comment="Allow UDP 500,4500 IPSec for YC peer" protocol=udp dst-port=500,4500 dst-address=51.250.78.223
add action=accept chain=input comment="Allow IPSec ESP for YC peer" protocol=ipsec-esp dst-address=51.250.78.223
add action=accept chain=forward comment="defconf: accept in ipsec policy" ipsec-policy=in,ipsec
add action=accept chain=forward comment="defconf: accept out ipsec policy" ipsec-policy=out,ipsec


/ip ipsec profile add dh-group=ecp256 prf-algorithm=sha256 nat-traversal=yes proposal-check=obey name "IKE2-PROFILE"
/ip ipsec proposal add auth-algorithms="" enc-algorithms=aes-128-gcm pfs-group=none lifetime=8h disabled=no name="IKE2-PROPOSAL"

/ip ipsec peer add address=51.250.78.223 exchange-mode=ike2 passive=no send-initial-contact=yes profile="IKE2-PROFILE" disabled=no name="YC"
/ip ipsec identity add peer=YC auth-method=pre-shared-key remote-id=ignore secret="OcsIc-321"

# Policy routing via IPsec SA
/ip ipsec policy set 0 disabled=yes

/ip ipsec policy add src-address=10.128.0.0/24 dst-address=10.10.201.0/24 tunnel=yes action=encrypt proposal=IKE2-PROPOSAL peer=YC
/ip ipsec policy add src-address=10.129.0.0/24 dst-address=10.10.202.0/24 tunnel=yes action=encrypt proposal=IKE2-PROPOSAL peer=YC


## Diagnostic & Monitoring
/ip ipsec proposal print
/ip ipsec profile print
/ip ipsec peer print
/ip ipsec identity print
/ip ipsec policy print

/ip ipsec active-peers print detail
/ip ipsec installed-sa print
20 changes: 20 additions & 0 deletions samples/unknown-sample.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# =====================================
# IPSEC attributes for Remote IPSEC SGW
# =====================================

yc-ipsec:
mode: IPSEC Tunnel mode
ike-version: IKEv2

ike-proposal: aes128gcm16-prfsha256-ecp256
esp-proposal: aes128gcm16
psk: OcsIc-321

local-sgw-ip: 51.250.13.97
# Yandex Cloud Security Gateway - yc-sgw
yc-sgw-ip: 51.250.90.9
#

YC-prefixes:
10.128.0.0/24
10.129.0.0/24
Loading

0 comments on commit 5662209

Please sign in to comment.