From 5968cb558e9badc9d483440bd8cadf1cce988168 Mon Sep 17 00:00:00 2001 From: Slawomir Koszewski Date: Fri, 25 Apr 2025 06:45:10 +0200 Subject: [PATCH] Finished LZ. --- README.md | 96 ++++++++++++++++++++ main.tf | 166 ++++++++++++++++++++-------------- modules/linux-vm/main.tf | 32 +++++++ modules/linux-vm/variables.tf | 21 +++++ variables.tf | 14 +++ wireguard_setup.sh | 37 ++++++++ 6 files changed, 298 insertions(+), 68 deletions(-) create mode 100644 wireguard_setup.sh diff --git a/README.md b/README.md index c44dd9e..895a538 100644 --- a/README.md +++ b/README.md @@ -22,3 +22,99 @@ Compute Engine free tier regions: * `us-east1-b` * `us-east1-c` * `us-east1-d` + +## Terraform and Google Cloud + +Initialize Google authentication: + +```shell +gcloud auth +``` + +## Firewall configuration + +Google Cloud network range: `192.168.16.0/20` or `192.168.16.0/24` and `192.168.17.0/24` +On-premise network range: `192.168.0.0/20` or `192.168.2.0/24` and `192.168.10.0/24` + +* Allow ICMP traffic (`allow-icmp-ingress`): + * from: `0.0.0.0/0` + * to: `gcp-range` + * protocol: `icmp` +* Allow SSH access (`allow-ssh-ingress`): + * from: `35.235.240.0/20`, `gcp-range`, `on-prem-range` + * to: `gcp-range` + * protocol: `tcp` + * port(s): `22` +* Allow Wireguard access (`allow-wireguard-ingress`): + * from: `0.0.0.0/0` + * to: `vm-gw-internal-ip` + * protocol: `udp` + * port(s): `51820-51829` +* Allow web traffic (`allow-web-ingress`): + * from: `0.0.0.0/0` or `gcp-range` and `on-prem-range` + * to: `gcp-range` + * protocol: `tcp` + * port(s): `80,443,5000,8080,8443` or `80,443` +* Allow DNS traffic (`allow-dns-ingress`): + * from: `35.199.192.0/19`, `gcp-range` + * to: `on-prem-range` + +## Configure Wireguard on NVA + +Elevate to `root`: + +```shell +sudo -i +``` + +Install wireguard software: + +```shell +apt -y install wireguard-tools +``` + +Enable IP forwarding. + +```shell +cat >/etc/sysctl.d/20-ip-forwarding.conf < /etc/wireguard/wg0.pub +``` + +Create a server config file: + +```shell +cat >/etc/wireguard/wg0.conf < NOTE: DNS query traffic comes from the `35.199.192.0/19` range. diff --git a/main.tf b/main.tf index aa79f1d..82f2204 100644 --- a/main.tf +++ b/main.tf @@ -33,77 +33,107 @@ module "hub_network" { nat = true } -module "spoke_network" { - source = "./modules/network" +# module "spoke_network" { +# source = "./modules/network" - name = "${var.spoke.name}-vpc" - project_id = var.spoke.project +# name = "${var.spoke.name}-vpc" +# project_id = var.spoke.project - subnets = [ - { - name = "${var.spoke.name}-network" - cidr = var.spoke.cidr - region = local.spoke_region - } - ] +# subnets = [ +# { +# name = "${var.spoke.name}-network" +# cidr = var.spoke.cidr +# region = local.spoke_region +# } +# ] - nat = true -} +# nat = true +# } -module "hub_to_spoke_peering" { - source = "./modules/network-peering" +# module "hub_to_spoke_peering" { +# source = "./modules/network-peering" - left = { - project_id = var.hub.project - network_id = module.hub_network.id - network_name = module.hub_network.name - } +# left = { +# project_id = var.hub.project +# network_id = module.hub_network.id +# network_name = module.hub_network.name +# } - right = { - project_id = var.spoke.project - network_id = module.spoke_network.id - network_name = module.spoke_network.name - } +# right = { +# project_id = var.spoke.project +# network_id = module.spoke_network.id +# network_name = module.spoke_network.name +# } - hub_spoke = true +# hub_spoke = true - depends_on = [ - module.hub_network, - module.spoke_network - ] -} +# depends_on = [ +# module.hub_network, +# module.spoke_network +# ] +# } -module "gw" { - source = "./modules/cloud-vpn" +# module "gw" { +# source = "./modules/cloud-vpn" - name = "${var.hub.name}-vpn" - network_name = module.hub_network.name - region = local.hub_region - vpn_external_ip = var.vpn_external_ip -} +# name = "${var.hub.name}-vpn" +# network_name = module.hub_network.name +# region = local.hub_region +# vpn_external_ip = var.vpn_external_ip +# } -module "to_lazurowa" { - source = "./modules/cloud-vpn-tunnel" - name = "${var.hub.name}-to-lazurowa" - gw_name = module.gw.name - peer_ip = var.peer_ip - shared_secret = var.shared_secret +# module "to_lazurowa" { +# source = "./modules/cloud-vpn-tunnel" +# name = "${var.hub.name}-to-lazurowa" +# gw_name = module.gw.name +# peer_ip = var.peer_ip +# shared_secret = var.shared_secret - local_selectors = [var.hub.cidr, var.spoke.cidr] - remote_selectors = var.remote_selectors +# local_selectors = [var.hub.cidr, var.spoke.cidr] +# remote_selectors = var.remote_selectors + +# depends_on = [module.gw] +# } module "vm_gw" { source = "./modules/linux-vm" - name = "vm-${var.hub.name}-gw" - network_name = "${var.hub.name}-vpc" - subnet_name = "${var.hub.name}-network" - ssh = var.ssh - can_ip_forward = true + name = "vm-${var.hub.name}-gw" + network_name = "${var.hub.name}-vpc" + subnet_name = "${var.hub.name}-network" + ssh = var.ssh + can_ip_forward = true + internal_ip = "192.168.16.100" + external_ip_name = var.vpn_external_ip + remote_subnets = var.remote_selectors + + startup_script = var.wireguard != null ? templatefile("${path.module}/wireguard_setup.sh", + { + address_space = var.wireguard.address_space + private_key = var.wireguard.private_key + public_key = var.wireguard.public_key + remote_public_key = var.wireguard.remote_public_key + remote_address_space = var.wireguard.remote_address_space + } + ) : null + depends_on = [module.hub_network] } +resource "google_compute_firewall" "allow_wireguard" { + name = "allow-wireguard" + network = module.hub_network.name + + allow { + protocol = "udp" + ports = ["51820-51829"] + } + + source_ranges = ["0.0.0.0/0"] + destination_ranges = ["192.168.16.100/32"] +} + module "vm_hub" { source = "./modules/linux-vm" @@ -115,17 +145,17 @@ module "vm_hub" { depends_on = [module.hub_network] } -module "vm_spoke" { - source = "./modules/linux-vm" +# module "vm_spoke" { +# source = "./modules/linux-vm" - name = "vm-${var.spoke.name}" - project_id = var.spoke.project - network_name = "${var.spoke.name}-vpc" - subnet_name = "${var.spoke.name}-network" - ssh = var.ssh +# name = "vm-${var.spoke.name}" +# project_id = var.spoke.project +# network_name = "${var.spoke.name}-vpc" +# subnet_name = "${var.spoke.name}-network" +# ssh = var.ssh - depends_on = [module.spoke_network] -} +# depends_on = [module.spoke_network] +# } module "koszewscy_internal_zone" { source = "./modules/dns-managed-zone" @@ -137,13 +167,13 @@ module "koszewscy_internal_zone" { target_name_servers = ["192.168.2.5"] } -module "koszewscy_internal_zone_spoke" { - source = "./modules/dns-managed-zone" +# module "koszewscy_internal_zone_spoke" { +# source = "./modules/dns-managed-zone" - project_id = var.spoke.project - dns_name = "koszewscy.waw.pl." - zone_name = "koszewscy-waw-pl-spoke" +# project_id = var.spoke.project +# dns_name = "koszewscy.waw.pl." +# zone_name = "koszewscy-waw-pl-spoke" - network_id = module.spoke_network.id - peering_network_id = module.hub_network.id -} +# network_id = module.spoke_network.id +# peering_network_id = module.hub_network.id +# } diff --git a/modules/linux-vm/main.tf b/modules/linux-vm/main.tf index 056bf72..21c9616 100644 --- a/modules/linux-vm/main.tf +++ b/modules/linux-vm/main.tf @@ -17,10 +17,26 @@ resource "google_compute_instance" "vm" { network = var.network_name subnetwork = var.subnet_name subnetwork_project = var.project_id != null ? var.project_id : data.google_client_config.default.project + network_ip = var.internal_ip != null ? var.internal_ip : null + + dynamic "access_config" { + for_each = var.external_ip_name != null && var.external_ip_name != "AUTO" ? [1] : [] + content { + nat_ip = data.google_compute_address.external_ip[0].address + } + } + + dynamic "access_config" { + for_each = var.external_ip_name == "AUTO" ? [1] : [] + content { + nat_ip = google_compute_address.external_ip[0].address + } + } } metadata = { ssh-keys = "${var.ssh[0].public_key} ${var.ssh[0].ssh_user}" + startup_script = var.startup_script } } @@ -33,3 +49,19 @@ resource "google_compute_route" "route_to_remote_network" { next_hop_instance = google_compute_instance.vm.id next_hop_instance_zone = google_compute_instance.vm.zone } + +resource "google_compute_address" "external_ip" { + count = var.external_ip_name == "AUTO" ? 1 : 0 + + name = "${var.name}-ip" + project = var.project_id != null ? var.project_id : data.google_client_config.default.project + address_type = "EXTERNAL" + address = var.external_ip_name +} + +data "google_compute_address" "external_ip" { + count = var.external_ip_name != null && var.external_ip_name != "AUTO" ? 1 : 0 + + name = var.external_ip_name + project = var.project_id != null ? var.project_id : data.google_client_config.default.project +} diff --git a/modules/linux-vm/variables.tf b/modules/linux-vm/variables.tf index 3356945..de7a6c9 100644 --- a/modules/linux-vm/variables.tf +++ b/modules/linux-vm/variables.tf @@ -39,6 +39,20 @@ variable "subnet_name" { type = string } +variable "internal_ip" { + description = "The internal IP address of the VM instance." + type = string + nullable = true + default = null +} + +variable "external_ip_name" { + description = "The external IP address of the VM instance." + type = string + nullable = true + default = null +} + variable "ssh" { description = "SSH Key(s) definition" type = list(object({ @@ -51,3 +65,10 @@ variable "remote_subnets" { type = list(string) default = [] } + +variable "startup_script" { + description = "Startup script to run on the VM instance." + type = string + nullable = true + default = null +} diff --git a/variables.tf b/variables.tf index 80c0dfb..7c2eb39 100644 --- a/variables.tf +++ b/variables.tf @@ -45,3 +45,17 @@ variable "shared_secret" { variable "remote_selectors" { type = list(string) } + +# Wireguard settings +variable "wireguard" { + type = object({ + address_space = string + private_key = string + public_key = string + remote_public_key = string + remote_address_space = string + }) + sensitive = true + nullable = true + default = null +} diff --git a/wireguard_setup.sh b/wireguard_setup.sh new file mode 100644 index 0000000..f43d6d8 --- /dev/null +++ b/wireguard_setup.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +# Ensure the script is run as root +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit 1 +fi + +# Install WireGuard +apt update && apt install -y wireguard + +# Configure IP forwarding +cat >/etc/sysctl.d/20-ip-forwarding.conf < /etc/wireguard/wg0.key +echo "${public_key}" > /etc/wireguard/wg0.pub + +# Create server configuration file +cat >/etc/wireguard/wg0.conf <