diff options
31 files changed, 2092 insertions, 0 deletions
diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/diagram/VyOS-instance-on-Azure.png b/Terraform/Azure/Site-to-Site-BGP-FW/diagram/VyOS-instance-on-Azure.png Binary files differnew file mode 100644 index 0000000..03b9b30 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/diagram/VyOS-instance-on-Azure.png diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/files/on_prem_vyos_instance.conf b/Terraform/Azure/Site-to-Site-BGP-FW/files/on_prem_vyos_instance.conf new file mode 100644 index 0000000..207aba2 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/files/on_prem_vyos_instance.conf @@ -0,0 +1,193 @@ +#On Prem VyOS instance configuration +set system host-name 'VyOS-02' +set system login banner pre-login 'Welcome to the VyOS on Azure' +set interfaces ethernet eth0 description 'OUTSIDE' +set interfaces ethernet eth1 description 'INSIDE' +set system name-server '<DNS IP>' +set system name-server '<DNS IP>' +set service dns forwarding name-server '<DNS IP>' +set service dns forwarding listen-address '<VyOS_Priv_NIC_IP>' +set service dns forwarding allow-from '<On_Prem_Priv_Subnet_Prefix>' +set service dns forwarding no-serve-rfc1918 +set nat source rule 10 outbound-interface name 'eth0' +set nat source rule 10 source address '<On_Prem_Priv_Subnet_Prefix>' +set nat source rule 10 translation address 'masquerade' +set vpn ipsec interface 'eth0' +set vpn ipsec esp-group AZURE lifetime '3600' +set vpn ipsec esp-group AZURE mode 'tunnel' +set vpn ipsec esp-group AZURE pfs 'dh-group2' +set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256' +set vpn ipsec esp-group AZURE proposal 1 hash 'sha1' +set vpn ipsec ike-group AZURE dead-peer-detection action 'restart' +set vpn ipsec ike-group AZURE dead-peer-detection interval '15' +set vpn ipsec ike-group AZURE dead-peer-detection timeout '30' +set vpn ipsec ike-group AZURE ikev2-reauth +set vpn ipsec ike-group AZURE key-exchange 'ikev2' +set vpn ipsec ike-group AZURE lifetime '28800' +set vpn ipsec ike-group AZURE proposal 1 dh-group '2' +set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256' +set vpn ipsec ike-group AZURE proposal 1 hash 'sha1' +set vpn ipsec ike-group AZURE close-action start +set vpn ipsec option disable-route-autoinstall +set vpn ipsec interface 'eth0' +set interfaces vti vti1 address '10.2.100.11/32' +set interfaces vti vti1 description 'Azure Tunnel to VyOS 01' +set interfaces vti vti1 ip adjust-mss '1350' +set protocols static route 10.1.100.11/32 interface vti1 +set vpn ipsec authentication psk VyOS id '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec authentication psk VyOS id '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec authentication psk VyOS secret 'ch00s3-4-s3cur3-psk' +set vpn ipsec site-to-site peer VyOS-01 authentication local-id '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 authentication mode 'pre-shared-secret' +set vpn ipsec site-to-site peer VyOS-01 authentication remote-id '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 connection-type 'initiate' +set vpn ipsec site-to-site peer VyOS-01 description 'AZURE TUNNEL to 01' +set vpn ipsec site-to-site peer VyOS-01 ike-group 'AZURE' +set vpn ipsec site-to-site peer VyOS-01 ikev2-reauth 'inherit' +set vpn ipsec site-to-site peer VyOS-01 local-address '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 remote-address '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 vti bind 'vti1' +set vpn ipsec site-to-site peer VyOS-01 vti esp-group 'AZURE' +set protocols bgp system-as '<On_Prem_Net_BGP_AS_Number>' +set protocols bgp address-family ipv4-unicast network '<On_Prem_Net_Subnet_Prefix>' +set protocols bgp neighbor 10.1.100.11 remote-as '<Azure_Net_BGP_AS_Number>' +set protocols bgp neighbor 10.1.100.11 address-family ipv4-unicast soft-reconfiguration inbound +set protocols bgp neighbor 10.1.100.11 timers holdtime '30' +set protocols bgp neighbor 10.1.100.11 timers keepalive '10' +set protocols bgp neighbor 10.1.100.11 disable-connected-check +set firewall group network-group Local network '<On_Prem_Net_Subnet_Prefix>' +set firewall group port-group dns_ports port '53' +set firewall group port-group mail_ports port '110' +set firewall group port-group mail_ports port '25' +set firewall group port-group web_ports port '443' +set firewall group port-group web_ports port '8080' +set firewall group port-group web_ports port '80' +set firewall ipv4 forward filter default-action 'drop' +set firewall ipv4 forward filter rule 10 action 'accept' +set firewall ipv4 forward filter rule 10 state 'established' +set firewall ipv4 forward filter rule 10 state 'related' +set firewall ipv4 forward filter rule 11 action 'drop' +set firewall ipv4 forward filter rule 11 state 'invalid' +set firewall ipv4 forward filter rule 20 action 'accept' +set firewall ipv4 forward filter rule 20 description 'Allow ICMP' +set firewall ipv4 forward filter rule 20 icmp type-name 'echo-request' +set firewall ipv4 forward filter rule 20 inbound-interface name 'eth0' +set firewall ipv4 forward filter rule 20 protocol 'icmp' +set firewall ipv4 forward filter rule 20 state 'new' +set firewall ipv4 forward filter rule 30 action 'drop' +set firewall ipv4 forward filter rule 30 description 'Mitigate SSH brute-forcing' +set firewall ipv4 forward filter rule 30 destination port '22' +set firewall ipv4 forward filter rule 30 inbound-interface name 'eth0' +set firewall ipv4 forward filter rule 30 protocol 'tcp' +set firewall ipv4 forward filter rule 30 recent count '4' +set firewall ipv4 forward filter rule 30 recent time 'minute' +set firewall ipv4 forward filter rule 30 state 'new' +set firewall ipv4 forward filter rule 31 action 'accept' +set firewall ipv4 forward filter rule 31 description 'Allow SSH' +set firewall ipv4 forward filter rule 31 destination port '22' +set firewall ipv4 forward filter rule 31 inbound-interface name 'eth0' +set firewall ipv4 forward filter rule 31 protocol 'tcp' +set firewall ipv4 forward filter rule 31 state 'new' +set firewall ipv4 forward filter rule 120 action 'accept' +set firewall ipv4 forward filter rule 120 description 'LAN clients web requests to Web SRVs' +set firewall ipv4 forward filter rule 120 destination group port-group 'web_ports' +set firewall ipv4 forward filter rule 120 inbound-interface name 'eth1' +set firewall ipv4 forward filter rule 120 protocol 'tcp' +set firewall ipv4 forward filter rule 130 action 'accept' +set firewall ipv4 forward filter rule 130 description 'LAN clients ICMP' +set firewall ipv4 forward filter rule 130 icmp type-name 'echo-request' +set firewall ipv4 forward filter rule 130 inbound-interface name 'eth1' +set firewall ipv4 forward filter rule 130 protocol 'icmp' +set firewall ipv4 forward filter rule 130 state 'new' +set firewall ipv4 forward filter rule 140 action 'drop' +set firewall ipv4 forward filter rule 140 description 'Mitigate clients SSH brute-forcing' +set firewall ipv4 forward filter rule 140 destination port '22' +set firewall ipv4 forward filter rule 140 inbound-interface name 'eth1' +set firewall ipv4 forward filter rule 140 protocol 'tcp' +set firewall ipv4 forward filter rule 140 recent count '4' +set firewall ipv4 forward filter rule 140 recent time 'minute' +set firewall ipv4 forward filter rule 140 state 'new' +set firewall ipv4 forward filter rule 141 action 'accept' +set firewall ipv4 forward filter rule 141 description 'Allow clients SSH' +set firewall ipv4 forward filter rule 141 destination port '22' +set firewall ipv4 forward filter rule 141 inbound-interface name 'eth1' +set firewall ipv4 forward filter rule 141 protocol 'tcp' +set firewall ipv4 forward filter rule 141 state 'new' +set firewall ipv4 input filter default-action 'drop' +set firewall ipv4 input filter rule 10 action 'accept' +set firewall ipv4 input filter rule 10 description 'Allow established/related' +set firewall ipv4 input filter rule 10 state 'established' +set firewall ipv4 input filter rule 10 state 'related' +set firewall ipv4 input filter rule 11 action 'drop' +set firewall ipv4 input filter rule 11 state 'invalid' +set firewall ipv4 input filter rule 20 action 'accept' +set firewall ipv4 input filter rule 20 description 'Allow ESP' +set firewall ipv4 input filter rule 20 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 20 protocol 'esp' +set firewall ipv4 input filter rule 30 action 'accept' +set firewall ipv4 input filter rule 30 description 'Allow ISAKMP' +set firewall ipv4 input filter rule 30 destination port '500' +set firewall ipv4 input filter rule 30 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 30 protocol 'udp' +set firewall ipv4 input filter rule 40 action 'accept' +set firewall ipv4 input filter rule 40 description 'IPSec NAT Traversal' +set firewall ipv4 input filter rule 40 destination port '4500' +set firewall ipv4 input filter rule 40 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 40 protocol 'udp' +set firewall ipv4 input filter rule 70 action 'accept' +set firewall ipv4 input filter rule 70 description 'Allow L2TP' +set firewall ipv4 input filter rule 70 destination port '1701' +set firewall ipv4 input filter rule 70 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 70 ipsec match-ipsec +set firewall ipv4 input filter rule 70 protocol 'udp' +set firewall ipv4 input filter rule 80 action 'accept' +set firewall ipv4 input filter rule 80 description 'Allow ICMP' +set firewall ipv4 input filter rule 80 icmp type-name 'echo-request' +set firewall ipv4 input filter rule 80 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 80 protocol 'icmp' +set firewall ipv4 input filter rule 80 state 'new' +set firewall ipv4 input filter rule 90 action 'drop' +set firewall ipv4 input filter rule 90 description 'Mitigate SSH brute-forcing' +set firewall ipv4 input filter rule 90 destination port '22' +set firewall ipv4 input filter rule 90 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 90 protocol 'tcp' +set firewall ipv4 input filter rule 90 recent count '4' +set firewall ipv4 input filter rule 90 recent time 'minute' +set firewall ipv4 input filter rule 90 state 'new' +set firewall ipv4 input filter rule 91 action 'accept' +set firewall ipv4 input filter rule 91 description 'Allow SSH' +set firewall ipv4 input filter rule 91 destination port '22' +set firewall ipv4 input filter rule 91 inbound-interface name 'eth0' +set firewall ipv4 input filter rule 91 protocol 'tcp' +set firewall ipv4 input filter rule 91 state 'new' +set firewall ipv4 input filter rule 140 action 'accept' +set firewall ipv4 input filter rule 140 description 'Allow ESP' +set firewall ipv4 input filter rule 140 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 140 protocol 'esp' +set firewall ipv4 input filter rule 150 action 'accept' +set firewall ipv4 input filter rule 150 description 'Allow ISAKMP' +set firewall ipv4 input filter rule 150 destination port '500' +set firewall ipv4 input filter rule 150 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 150 protocol 'udp' +set firewall ipv4 input filter rule 160 action 'accept' +set firewall ipv4 input filter rule 160 description 'IPSec NAT Traversal' +set firewall ipv4 input filter rule 160 destination port '4500' +set firewall ipv4 input filter rule 160 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 160 protocol 'udp' +set firewall ipv4 input filter rule 170 action 'accept' +set firewall ipv4 input filter rule 170 description 'Allow L2TP' +set firewall ipv4 input filter rule 170 destination port '1701' +set firewall ipv4 input filter rule 170 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 170 ipsec match-ipsec +set firewall ipv4 input filter rule 170 protocol 'udp' +set firewall ipv4 input filter rule 180 action 'accept' +set firewall ipv4 input filter rule 180 description 'Allow ICMP' +set firewall ipv4 input filter rule 180 icmp type-name 'echo-request' +set firewall ipv4 input filter rule 180 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 180 protocol 'icmp' +set firewall ipv4 input filter rule 180 state 'new' +set firewall ipv4 input filter rule 190 action 'accept' +set firewall ipv4 input filter rule 190 description 'Allow BGP' +set firewall ipv4 input filter rule 190 destination port '179' +set firewall ipv4 input filter rule 190 inbound-interface name 'vti1' +set firewall ipv4 input filter rule 190 protocol 'tcp' diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/files/vyos_01_user_data.tpl b/Terraform/Azure/Site-to-Site-BGP-FW/files/vyos_01_user_data.tpl new file mode 100644 index 0000000..476cdfc --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/files/vyos_01_user_data.tpl @@ -0,0 +1,204 @@ +#cloud-config +vyos_config_commands: + - set system host-name 'VyOS-01' + - set system login banner pre-login 'Welcome to the VyOS on Azure' + - set interfaces ethernet eth0 description 'OUTSIDE' + - set interfaces ethernet eth1 description 'INSIDE' + - set system name-server '${dns_1}' + - set system name-server '${dns_2}' + - set service dns forwarding name-server '${dns_1}' + - set service dns forwarding listen-address '${vyos_01_priv_nic_ip}' + - set service dns forwarding allow-from '${vnet_01_priv_subnet_prefix}' + - set service dns forwarding no-serve-rfc1918 + - set nat source rule 10 outbound-interface name 'eth0' + - set nat source rule 10 source address '${vnet_01_priv_subnet_prefix}' + - set nat source rule 10 translation address 'masquerade' + - set vpn ipsec interface 'eth0' + - set vpn ipsec esp-group AZURE lifetime '3600' + - set vpn ipsec esp-group AZURE mode 'tunnel' + - set vpn ipsec esp-group AZURE pfs 'dh-group2' + - set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256' + - set vpn ipsec esp-group AZURE proposal 1 hash 'sha1' + - set vpn ipsec ike-group AZURE dead-peer-detection action 'restart' + - set vpn ipsec ike-group AZURE dead-peer-detection interval '15' + - set vpn ipsec ike-group AZURE dead-peer-detection timeout '30' + - set vpn ipsec ike-group AZURE ikev2-reauth + - set vpn ipsec ike-group AZURE key-exchange 'ikev2' + - set vpn ipsec ike-group AZURE lifetime '28800' + - set vpn ipsec ike-group AZURE proposal 1 dh-group '2' + - set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256' + - set vpn ipsec ike-group AZURE proposal 1 hash 'sha1' + - set vpn ipsec ike-group AZURE close-action start + - set vpn ipsec option disable-route-autoinstall + - set interfaces vti vti1 address '10.1.100.11/32' + - set interfaces vti vti1 description 'Tunnel VyOS 02' + - set interfaces vti vti1 ip adjust-mss '1350' + - set protocols static route 10.2.100.11/32 interface vti1 + - set vpn ipsec authentication psk VyOS id '${public_ip_address_01}' + - set vpn ipsec authentication psk VyOS id '${on_prem_public_ip_address}' + - set vpn ipsec authentication psk VyOS secret 'ch00s3-4-s3cur3-psk' + - set vpn ipsec site-to-site peer VyOS-02 authentication local-id '${public_ip_address_01}' + - set vpn ipsec site-to-site peer VyOS-02 authentication mode 'pre-shared-secret' + - set vpn ipsec site-to-site peer VyOS-02 authentication remote-id '${on_prem_public_ip_address}' + - set vpn ipsec site-to-site peer VyOS-02 connection-type 'none' + - set vpn ipsec site-to-site peer VyOS-02 description 'AZURE TUNNEL to VyOS on NET 02' + - set vpn ipsec site-to-site peer VyOS-02 ike-group 'AZURE' + - set vpn ipsec site-to-site peer VyOS-02 ikev2-reauth 'inherit' + - set vpn ipsec site-to-site peer VyOS-02 local-address '${vyos_01_pub_nic_ip}' + - set vpn ipsec site-to-site peer VyOS-02 remote-address '${on_prem_public_ip_address}' + - set vpn ipsec site-to-site peer VyOS-02 vti bind 'vti1' + - set vpn ipsec site-to-site peer VyOS-02 vti esp-group 'AZURE' + - set protocols bgp system-as '${vnet_01_bgp_as_number}' + - set protocols bgp address-family ipv4-unicast network ${vnet_01_priv_subnet_prefix} + - set protocols bgp neighbor 10.2.100.11 remote-as '${on_prem_bgp_as_number}' + - set protocols bgp neighbor 10.2.100.11 address-family ipv4-unicast soft-reconfiguration inbound + - set protocols bgp neighbor 10.2.100.11 timers holdtime '30' + - set protocols bgp neighbor 10.2.100.11 timers keepalive '10' + - set protocols bgp neighbor 10.2.100.11 disable-connected-check + - set firewall group network-group Local network '${vnet_01_priv_subnet_prefix}' + - set firewall group port-group dns_ports port '53' + - set firewall group port-group mail_ports port '110' + - set firewall group port-group mail_ports port '25' + - set firewall group port-group web_ports port '443' + - set firewall group port-group web_ports port '8080' + - set firewall group port-group web_ports port '80' + - set firewall ipv4 forward filter default-action 'drop' + - set firewall ipv4 forward filter rule 10 action 'accept' + - set firewall ipv4 forward filter rule 10 state 'established' + - set firewall ipv4 forward filter rule 10 state 'related' + - set firewall ipv4 forward filter rule 11 action 'drop' + - set firewall ipv4 forward filter rule 11 state 'invalid' + - set firewall ipv4 forward filter rule 20 action 'accept' + - set firewall ipv4 forward filter rule 20 description 'Allow ICMP' + - set firewall ipv4 forward filter rule 20 icmp type-name 'echo-request' + - set firewall ipv4 forward filter rule 20 inbound-interface name 'eth0' + - set firewall ipv4 forward filter rule 20 protocol 'icmp' + - set firewall ipv4 forward filter rule 20 state 'new' + - set firewall ipv4 forward filter rule 30 action 'drop' + - set firewall ipv4 forward filter rule 30 description 'Mitigate SSH brute-forcing' + - set firewall ipv4 forward filter rule 30 destination port '22' + - set firewall ipv4 forward filter rule 30 inbound-interface name 'eth0' + - set firewall ipv4 forward filter rule 30 protocol 'tcp' + - set firewall ipv4 forward filter rule 30 recent count '4' + - set firewall ipv4 forward filter rule 30 recent time 'minute' + - set firewall ipv4 forward filter rule 30 state 'new' + - set firewall ipv4 forward filter rule 31 action 'accept' + - set firewall ipv4 forward filter rule 31 description 'Allow SSH' + - set firewall ipv4 forward filter rule 31 destination port '22' + - set firewall ipv4 forward filter rule 31 inbound-interface name 'eth0' + - set firewall ipv4 forward filter rule 31 protocol 'tcp' + - set firewall ipv4 forward filter rule 31 state 'new' + - set firewall ipv4 forward filter rule 120 action 'accept' + - set firewall ipv4 forward filter rule 120 description 'LAN clients web requests to Web SRVs' + - set firewall ipv4 forward filter rule 120 destination group port-group 'web_ports' + - set firewall ipv4 forward filter rule 120 inbound-interface name 'eth1' + - set firewall ipv4 forward filter rule 120 protocol 'tcp' + - set firewall ipv4 forward filter rule 130 action 'accept' + - set firewall ipv4 forward filter rule 130 description 'LAN clients ICMP' + - set firewall ipv4 forward filter rule 130 icmp type-name 'echo-request' + - set firewall ipv4 forward filter rule 130 inbound-interface name 'eth1' + - set firewall ipv4 forward filter rule 130 state 'new' + - set firewall ipv4 forward filter rule 140 action 'drop' + - set firewall ipv4 forward filter rule 140 description 'Mitigate clients SSH brute-forcing' + - set firewall ipv4 forward filter rule 140 destination port '22' + - set firewall ipv4 forward filter rule 140 inbound-interface name 'eth1' + - set firewall ipv4 forward filter rule 140 protocol 'tcp' + - set firewall ipv4 forward filter rule 140 recent count '4' + - set firewall ipv4 forward filter rule 140 recent time 'minute' + - set firewall ipv4 forward filter rule 140 state 'new' + - set firewall ipv4 forward filter rule 141 action 'accept' + - set firewall ipv4 forward filter rule 141 description 'Allow clients SSH' + - set firewall ipv4 forward filter rule 141 destination port '22' + - set firewall ipv4 forward filter rule 141 inbound-interface name 'eth1' + - set firewall ipv4 forward filter rule 141 protocol 'tcp' + - set firewall ipv4 forward filter rule 141 state 'new' + - set firewall ipv4 input filter default-action 'drop' + - set firewall ipv4 input filter rule 10 action 'accept' + - set firewall ipv4 input filter rule 10 description 'Allow established/related' + - set firewall ipv4 input filter rule 10 state 'established' + - set firewall ipv4 input filter rule 10 state 'related' + - set firewall ipv4 input filter rule 11 action 'drop' + - set firewall ipv4 input filter rule 11 state 'invalid' + - set firewall ipv4 input filter rule 20 action 'accept' + - set firewall ipv4 input filter rule 20 description 'WireGuard_IN' + - set firewall ipv4 input filter rule 20 destination port '2224' + - set firewall ipv4 input filter rule 20 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 20 log + - set firewall ipv4 input filter rule 20 protocol 'udp' + - set firewall ipv4 input filter rule 30 action 'accept' + - set firewall ipv4 input filter rule 30 description 'OpenVPN_IN' + - set firewall ipv4 input filter rule 30 destination port '1194' + - set firewall ipv4 input filter rule 30 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 30 log + - set firewall ipv4 input filter rule 30 protocol 'udp' + - set firewall ipv4 input filter rule 40 action 'accept' + - set firewall ipv4 input filter rule 40 description 'Allow ESP' + - set firewall ipv4 input filter rule 40 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 40 protocol 'esp' + - set firewall ipv4 input filter rule 50 action 'accept' + - set firewall ipv4 input filter rule 50 description 'Allow ISAKMP' + - set firewall ipv4 input filter rule 50 destination port '500' + - set firewall ipv4 input filter rule 50 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 50 protocol 'udp' + - set firewall ipv4 input filter rule 60 action 'accept' + - set firewall ipv4 input filter rule 60 description 'IPSec NAT Traversal' + - set firewall ipv4 input filter rule 60 destination port '4500' + - set firewall ipv4 input filter rule 60 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 60 protocol 'udp' + - set firewall ipv4 input filter rule 70 action 'accept' + - set firewall ipv4 input filter rule 70 description 'Allow L2TP' + - set firewall ipv4 input filter rule 70 destination port '1701' + - set firewall ipv4 input filter rule 70 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 70 ipsec match-ipsec + - set firewall ipv4 input filter rule 70 protocol 'udp' + - set firewall ipv4 input filter rule 80 action 'accept' + - set firewall ipv4 input filter rule 80 description 'Allow ICMP' + - set firewall ipv4 input filter rule 80 icmp type-name 'echo-request' + - set firewall ipv4 input filter rule 80 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 80 protocol 'icmp' + - set firewall ipv4 input filter rule 80 state 'new' + - set firewall ipv4 input filter rule 90 action 'drop' + - set firewall ipv4 input filter rule 90 description 'Mitigate SSH brute-forcing' + - set firewall ipv4 input filter rule 90 destination port '22' + - set firewall ipv4 input filter rule 90 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 90 protocol 'tcp' + - set firewall ipv4 input filter rule 90 recent count '4' + - set firewall ipv4 input filter rule 90 recent time 'minute' + - set firewall ipv4 input filter rule 90 state 'new' + - set firewall ipv4 input filter rule 91 action 'accept' + - set firewall ipv4 input filter rule 91 description 'Allow SSH' + - set firewall ipv4 input filter rule 91 destination port '22' + - set firewall ipv4 input filter rule 91 inbound-interface name 'eth0' + - set firewall ipv4 input filter rule 91 protocol 'tcp' + - set firewall ipv4 input filter rule 91 state 'new' + - set firewall ipv4 input filter rule 140 action 'accept' + - set firewall ipv4 input filter rule 140 description 'Allow ESP' + - set firewall ipv4 input filter rule 140 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 140 protocol 'esp' + - set firewall ipv4 input filter rule 150 action 'accept' + - set firewall ipv4 input filter rule 150 description 'Allow ISAKMP' + - set firewall ipv4 input filter rule 150 destination port '500' + - set firewall ipv4 input filter rule 150 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 150 protocol 'udp' + - set firewall ipv4 input filter rule 160 action 'accept' + - set firewall ipv4 input filter rule 160 description 'IPSec NAT Traversal' + - set firewall ipv4 input filter rule 160 destination port '4500' + - set firewall ipv4 input filter rule 160 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 160 protocol 'udp' + - set firewall ipv4 input filter rule 170 action 'accept' + - set firewall ipv4 input filter rule 170 description 'Allow L2TP' + - set firewall ipv4 input filter rule 170 destination port '1701' + - set firewall ipv4 input filter rule 170 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 170 ipsec match-ipsec + - set firewall ipv4 input filter rule 170 protocol 'udp' + - set firewall ipv4 input filter rule 180 action 'accept' + - set firewall ipv4 input filter rule 180 description 'Allow ICMP' + - set firewall ipv4 input filter rule 180 icmp type-name 'echo-request' + - set firewall ipv4 input filter rule 180 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 180 protocol 'icmp' + - set firewall ipv4 input filter rule 180 state 'new' + - set firewall ipv4 input filter rule 190 action 'accept' + - set firewall ipv4 input filter rule 190 description 'Allow BGP' + - set firewall ipv4 input filter rule 190 destination port '179' + - set firewall ipv4 input filter rule 190 inbound-interface name 'vti1' + - set firewall ipv4 input filter rule 190 protocol 'tcp' diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/main.tf b/Terraform/Azure/Site-to-Site-BGP-FW/main.tf new file mode 100644 index 0000000..9219d1c --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/main.tf @@ -0,0 +1,58 @@ + + +# --------------------------- VyOS 01 -------------------------------------- +# Net 01 VyOS 01 instance +resource "azurerm_virtual_machine" "net_01_VyOS_01" { + name = join("-", [var.prefix, "VyOS", "01"]) + location = var.location + resource_group_name = var.resource_group + vm_size = var.vm_size + + network_interface_ids = [azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id, azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.id] + primary_network_interface_id = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id + delete_os_disk_on_termination = "true" + tags = var.tags + plan { + publisher = var.image_publisher + name = var.image_sku + product = var.image_offer + } + + storage_image_reference { + publisher = var.image_publisher + offer = var.image_offer + sku = var.image_sku + version = var.image_version + } + + storage_os_disk { + name = join("_", [var.prefix, "VyOS", "01", "osdisk"]) + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = join("-", [var.prefix, "VyOS", "01"]) + admin_username = var.admin_username + admin_password = var.admin_password + custom_data = base64encode(templatefile("${path.module}/files/vyos_01_user_data.tpl", { + vnet_01_priv_subnet_prefix = var.vnet_01_priv_subnet_prefix, + public_ip_address_01 = azurerm_public_ip.azure_vnet_01_public_address.ip_address, + on_prem_public_ip_address = var.on_prem_public_ip_address, + vyos_01_pub_nic_ip = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.private_ip_address, + vyos_01_priv_nic_ip = azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.private_ip_address, + dns_1 = var.dns_1, + dns_2 = var.dns_2, + vnet_01_bgp_as_number = var.vnet_01_bgp_as_number, + on_prem_bgp_as_number = var.on_prem_bgp_as_number + })) + } + + depends_on = [azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv, + azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub] + + os_profile_linux_config { + disable_password_authentication = false + } +} diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/outputs.tf b/Terraform/Azure/Site-to-Site-BGP-FW/outputs.tf new file mode 100644 index 0000000..2a0b0e9 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/outputs.tf @@ -0,0 +1,12 @@ +# Management information +output "Admin_Username" { + value = var.admin_username +} +output "Admin_Password" { + value = var.admin_password +} + +# IP Address configuration +output "VyOS_01_Public_IP_Address" { + value = azurerm_public_ip.azure_vnet_01_public_address.ip_address +} diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/provider.tf b/Terraform/Azure/Site-to-Site-BGP-FW/provider.tf new file mode 100644 index 0000000..09a6225 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/provider.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">=1.2" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">=3.99.0" + } + } +} + +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/readme.md b/Terraform/Azure/Site-to-Site-BGP-FW/readme.md new file mode 100644 index 0000000..1b79529 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/readme.md @@ -0,0 +1,79 @@ +# VyOS instance (NVA) on Azure (with Site to Site VPN, Static/Dynamic (BGP), NAT, DNS forwarding and Firewall options) + +This Terraform module deploys a VyOS instance (NVA) on Azure. All necessary parameters will be configured automatically, and you will receive management and access information from outputs. +This is the connection diagram: + + +The module consists of different files containing necessary resources and variables: + +- `provider.tf`: Each resource in the configuration must be associated with one provider configuration. Provider configurations, unlike most other concepts in Terraform, are global to an entire Terraform configuration and can be shared across module boundaries. + +- `variables.tf`: Access information, network parameters, VyOS image parameters, and virtual network parameters are defined here. You may edit/change these parameters based on your requirements. **Note:** After editing IP addresses inside `variables.tf`, check `files/vyos_01_user_data.tpl` file as well. All necessary configurations are based on this file. + +- `security_groups.tf`: Security groups are one of the most important pillars that support vNET security. They are software-defined network firewalls defined inside a vNet that allow or deny traffic to resources based on the inbound and outbound rules. They support stateful Layer 3 (Network layer) and Layer 4 (Transport layer) filtering capabilities. + +- `virtual_networks.tf`: All network resources such as Virtual Network, Subnets, Network Interface Cards, Public IP Address, Routing Table contains in this file. + +- `main.tf`: Contains the resource definitions for the VyOS VM (NVA). + +- `files/vyos_01_user_data.tpl` : All necessary configurations of the VyOS instance have been defined in this file based on the VyOS CLI reference. + +- `files/on_prem_vyos_instance.conf`: Contains the configuration for the on-premise VyOS instance, which can serve as a reference when setting up a site-to-site VPN with the Azure VyOS instance. + +- `outputs.tf`: Will contain the output definitions for the module, such as access data, Public IP Address of the VyOS instances, etc. + +## Prerequisites + +Before applying this module, ensure you have: + +- An active Azure subscription: + ```sh + az account set --subscription "<subscription ID or name>" + ``` + +- Azure CLI installed. [Installation link](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) + +- Logged in with Azure credentials via CLI: + ```sh + az version + az login + ``` + +- Azure Resource Group (RG) created: + ```sh + az group create --name demoResourceGroup --location westus + az group list + az group show --name exampleGroup + ``` + +- Terraform installed. [Installation link](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) + + +## Usage + +### Setup Variables + +All variables needed for customization are defined in `variables.tf`. Adjust them according to your infrastructure requirements. + +### Implementation Process + +1. Run `terraform fmt` to format the structure. +2. Execute `terraform validate` to perform a syntax check. +3. Use `terraform plan` to preview the infrastructure changes before applying. +4. Run `terraform apply` to apply the script and provision the infrastructure. +5. Use `terraform output` to view the management IP and credentials for the VyOS instance. +6. To destroy the infrastructure, execute `terraform destroy`. + +### Management + +For management, use the `VyOS_01_Public_IP_Address` and VyOS credentials from `outputs`. + +Sample command: `ssh vyos@<VyOS_01_Public_IP_Address>` + +### Note + +Ensure that you have appropriate permissions and configurations set up in your Azure environment before executing the Terraform commands. + +Feel free to modify the script to suit your specific testing needs. + +For further assistance or customization, refer to the VyOS, Terraform, and Azure documentation. diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/security_groups.tf b/Terraform/Azure/Site-to-Site-BGP-FW/security_groups.tf new file mode 100644 index 0000000..098f266 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/security_groups.tf @@ -0,0 +1,97 @@ +resource "azurerm_network_security_group" "VyOS" { + name = join("-", [var.prefix, "VyOS", "SG"]) + location = var.location + resource_group_name = var.resource_group + tags = var.tags + + # For SSH Traffic + security_rule { + name = "SSH" + priority = 101 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For Wireguard Traffic + security_rule { + name = "Wireguard" + priority = 102 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "51820" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For OpenVPN Traffic + security_rule { + name = "OpenVPN" + priority = 103 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "1194" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For ESP Traffic + security_rule { + name = "ESP" + priority = 104 + direction = "Inbound" + access = "Allow" + protocol = "Esp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For IKE Traffic + security_rule { + name = "IKE" + priority = 105 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "500" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For IPSEC Traffic + security_rule { + name = "IPSEC" + priority = 106 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "1701" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For NAT Traversal + security_rule { + name = "NAT_Traversal" + priority = 107 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "4500" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/variables.tf b/Terraform/Azure/Site-to-Site-BGP-FW/variables.tf new file mode 100644 index 0000000..5e6d37f --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/variables.tf @@ -0,0 +1,113 @@ +# General Variables + +variable "location" { + description = "The region where all resources will deploy" + default = "LOCATION EXAMPLE: West Europe" +} + +variable "resource_group" { + description = "The name of your Azure Resource Group." + default = "<YOUR RESOURCE GROUP>" +} + +variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_B2s" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = { + environment = "Test" + project = "VyOS sample VPN" + owner = "VyOS Networks" + created-by = "Terraform" + } +} + +variable "prefix" { + default = "DualVPN" +} + +variable "dns_1" { + default = "8.8.8.8" +} + +variable "dns_2" { + default = "8.8.4.4" +} + +# ----------------------------------------------------------------- +# Variables related credentials +variable "admin_username" { + description = "Administrator user name" + default = "vyos" +} + +variable "admin_password" { + description = "Administrator password" + default = "<ADMIN PASSWORD>" +} + +# ----------------------------------------------------------------- +# Variables related image selection + +variable "image_publisher" { + description = "Name of the publisher of the image (az vm image list)" + default = "sentriumsl" +} + +variable "image_offer" { + description = "Name of the offer (az vm image list)" + default = "vyos-1-2-lts-on-azure" +} + +variable "image_sku" { + description = "Image SKU to apply (az vm image list)" + default = "vyos-1-3" +} + +variable "image_version" { + description = "Version of the image to apply (az vm image list)" + default = "1.4.0" +} + +# ----------------------------------------------------- +# Variables related Virtual Networks + +# VNet 01 + +variable "vnet_01_name" { + description = "The name for your virtual network." + default = "Net-01" +} + +variable "vnet_01_address_prefix" { + description = "The address space that is used by the virtual network." + default = "10.1.0.0/16" +} + +variable "vnet_01_priv_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.1.0/24" +} + +variable "vnet_01_pub_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.11.0/24" +} + +variable "vnet_01_bgp_as_number" { + default = "65001" +} + +# On Prem Data Center + +variable "on_prem_bgp_as_number" { + default = "65002" +} + +variable "on_prem_public_ip_address" { + default = "192.0.2.1" +} diff --git a/Terraform/Azure/Site-to-Site-BGP-FW/virtual_networks.tf b/Terraform/Azure/Site-to-Site-BGP-FW/virtual_networks.tf new file mode 100644 index 0000000..5398da2 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP-FW/virtual_networks.tf @@ -0,0 +1,107 @@ +# vNET Creation +resource "azurerm_virtual_network" "azure_vnet_01" { + name = join("-", [var.prefix, var.vnet_01_name]) + address_space = [var.vnet_01_address_prefix] + location = var.location + resource_group_name = var.resource_group + depends_on = [ + var.resource_group + ] + tags = var.tags +} + +# Net 01 Subnet Private +resource "azurerm_subnet" "azure_vnet_01_priv_subnet" { + name = join("-", [var.prefix, var.vnet_01_name, "priv"]) + resource_group_name = var.resource_group + address_prefixes = [var.vnet_01_priv_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_01.name +} + +# Net 01 Subnet Public +resource "azurerm_subnet" "azure_vnet_01_pub_subnet" { + name = join("-", [var.prefix, var.vnet_01_name, "pub"]) + resource_group_name = var.resource_group + address_prefixes = [var.vnet_01_pub_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_01.name +} + +# Public Address +resource "azurerm_public_ip" "azure_vnet_01_public_address" { + name = join("-", [var.prefix, var.vnet_01_name, "public", "IP"]) + location = var.location + resource_group_name = var.resource_group + sku = "Standard" + allocation_method = "Static" + idle_timeout_in_minutes = "30" + tags = var.tags +} + +# VyOS Route Table +resource "azurerm_route_table" "azure_vnet_01_vyos_01_route" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "route"]) + resource_group_name = var.resource_group + location = var.location + disable_bgp_route_propagation = false + tags = var.tags + + route { + name = "Default" + address_prefix = "0.0.0.0/0" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.private_ip_address + } +} + +# Assosiate route table to subnet +resource "azurerm_subnet_route_table_association" "azure_vnet_vpn_net_assosiation_01" { + subnet_id = azurerm_subnet.azure_vnet_01_priv_subnet.id + route_table_id = azurerm_route_table.azure_vnet_01_vyos_01_route.id +} + +# --------------------------- Network Interface Cards ------------------------ + +# VyOS-01 Pub-NIC +resource "azurerm_network_interface" "azure_vnet_01_vyos_01_nic_pub" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "pub", "NIC"]) + location = var.location + resource_group_name = var.resource_group + enable_ip_forwarding = true + tags = var.tags + + ip_configuration { + name = "external-01" + subnet_id = azurerm_subnet.azure_vnet_01_pub_subnet.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.azure_vnet_01_public_address.id + } + + depends_on = [ + azurerm_virtual_network.azure_vnet_01 + ] +} + +# VyOS-01 Priv-NIC +resource "azurerm_network_interface" "azure_vnet_01_vyos_01_nic_priv" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "priv", "NIC"]) + location = var.location + resource_group_name = var.resource_group + enable_ip_forwarding = true + tags = var.tags + + ip_configuration { + name = "internal-01" + subnet_id = azurerm_subnet.azure_vnet_01_priv_subnet.id + private_ip_address_allocation = "Dynamic" + } + + depends_on = [ + azurerm_virtual_network.azure_vnet_01 + ] +} + +# VyOS 01 Security Group Assosiation +resource "azurerm_network_interface_security_group_association" "azure_vnet_01_vyos_01_pub_attach" { + network_interface_id = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id + network_security_group_id = azurerm_network_security_group.VyOS.id +} diff --git a/Terraform/Azure/Site-to-Site-BGP/diagram/VyOS-instance-on-Azure.png b/Terraform/Azure/Site-to-Site-BGP/diagram/VyOS-instance-on-Azure.png Binary files differnew file mode 100644 index 0000000..03b9b30 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/diagram/VyOS-instance-on-Azure.png diff --git a/Terraform/Azure/Site-to-Site-BGP/files/on_prem_vyos_instance.conf b/Terraform/Azure/Site-to-Site-BGP/files/on_prem_vyos_instance.conf new file mode 100644 index 0000000..e29dff6 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/files/on_prem_vyos_instance.conf @@ -0,0 +1,58 @@ +#On Prem VyOS instance configuration example +set system host-name 'VyOS-02' +set system login banner pre-login 'Welcome to the VyOS on Azure' +set interfaces ethernet eth0 description 'OUTSIDE' +set interfaces ethernet eth1 description 'INSIDE' +set system name-server '<DNS IP>' +set system name-server '<DNS IP>' +set service dns forwarding name-server '<DNS IP>' +set service dns forwarding listen-address '<VyOS_Priv_NIC_IP>' +set service dns forwarding allow-from '<On_Prem_Priv_Subnet_Prefix>' +set service dns forwarding no-serve-rfc1918 +set nat source rule 10 outbound-interface name 'eth0' +set nat source rule 10 source address '<On_Prem_Priv_Subnet_Prefix>' +set nat source rule 10 translation address 'masquerade' +set vpn ipsec interface 'eth0' +set vpn ipsec esp-group AZURE lifetime '3600' +set vpn ipsec esp-group AZURE mode 'tunnel' +set vpn ipsec esp-group AZURE pfs 'dh-group2' +set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256' +set vpn ipsec esp-group AZURE proposal 1 hash 'sha1' +set vpn ipsec ike-group AZURE dead-peer-detection action 'restart' +set vpn ipsec ike-group AZURE dead-peer-detection interval '15' +set vpn ipsec ike-group AZURE dead-peer-detection timeout '30' +set vpn ipsec ike-group AZURE ikev2-reauth +set vpn ipsec ike-group AZURE key-exchange 'ikev2' +set vpn ipsec ike-group AZURE lifetime '28800' +set vpn ipsec ike-group AZURE proposal 1 dh-group '2' +set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256' +set vpn ipsec ike-group AZURE proposal 1 hash 'sha1' +set vpn ipsec ike-group AZURE close-action start +set vpn ipsec option disable-route-autoinstall +set vpn ipsec interface 'eth0' +set interfaces vti vti1 address '10.2.100.11/32' +set interfaces vti vti1 description 'Azure Tunnel to VyOS 01' +set interfaces vti vti1 ip adjust-mss '1350' +set protocols static route 10.1.100.11/32 interface vti1 +set vpn ipsec authentication psk VyOS id '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec authentication psk VyOS id '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec authentication psk VyOS secret 'ch00s3-4-s3cur3-psk' +set vpn ipsec site-to-site peer VyOS-01 authentication local-id '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 authentication mode 'pre-shared-secret' +set vpn ipsec site-to-site peer VyOS-01 authentication remote-id '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 connection-type 'initiate' +set vpn ipsec site-to-site peer VyOS-01 description 'AZURE TUNNEL to 01' +set vpn ipsec site-to-site peer VyOS-01 ike-group 'AZURE' +set vpn ipsec site-to-site peer VyOS-01 ikev2-reauth 'inherit' +set vpn ipsec site-to-site peer VyOS-01 local-address '<On_Prem_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 remote-address '<Azure_VyOS_Instance_Public_IP_Address>' +set vpn ipsec site-to-site peer VyOS-01 vti bind 'vti1' +set vpn ipsec site-to-site peer VyOS-01 vti esp-group 'AZURE' +set protocols bgp system-as '<On_Prem_Net_BGP_AS_Number>' +set protocols bgp address-family ipv4-unicast network '<On_Prem_Net_Subnet_Prefix>' +set protocols bgp neighbor 10.1.100.11 remote-as '<Azure_Net_BGP_AS_Number>' +set protocols bgp neighbor 10.1.100.11 address-family ipv4-unicast soft-reconfiguration inbound +set protocols bgp neighbor 10.1.100.11 timers holdtime '30' +set protocols bgp neighbor 10.1.100.11 timers keepalive '10' +set protocols bgp neighbor 10.1.100.11 disable-connected-check +
\ No newline at end of file diff --git a/Terraform/Azure/Site-to-Site-BGP/files/vyos_01_user_data.tpl b/Terraform/Azure/Site-to-Site-BGP/files/vyos_01_user_data.tpl new file mode 100644 index 0000000..a814454 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/files/vyos_01_user_data.tpl @@ -0,0 +1,57 @@ +#cloud-config +vyos_config_commands: + - set system host-name 'VyOS-01' + - set system login banner pre-login 'Welcome to the VyOS on Azure' + - set interfaces ethernet eth0 description 'OUTSIDE' + - set interfaces ethernet eth1 description 'INSIDE' + - set system name-server '${dns_1}' + - set system name-server '${dns_2}' + - set service dns forwarding name-server '${dns_1}' + - set service dns forwarding listen-address '${vyos_01_priv_nic_ip}' + - set service dns forwarding allow-from '${vnet_01_priv_subnet_prefix}' + - set service dns forwarding no-serve-rfc1918 + - set nat source rule 10 outbound-interface name 'eth0' + - set nat source rule 10 source address '${vnet_01_priv_subnet_prefix}' + - set nat source rule 10 translation address 'masquerade' + - set vpn ipsec interface 'eth0' + - set vpn ipsec esp-group AZURE lifetime '3600' + - set vpn ipsec esp-group AZURE mode 'tunnel' + - set vpn ipsec esp-group AZURE pfs 'dh-group2' + - set vpn ipsec esp-group AZURE proposal 1 encryption 'aes256' + - set vpn ipsec esp-group AZURE proposal 1 hash 'sha1' + - set vpn ipsec ike-group AZURE dead-peer-detection action 'restart' + - set vpn ipsec ike-group AZURE dead-peer-detection interval '15' + - set vpn ipsec ike-group AZURE dead-peer-detection timeout '30' + - set vpn ipsec ike-group AZURE ikev2-reauth + - set vpn ipsec ike-group AZURE key-exchange 'ikev2' + - set vpn ipsec ike-group AZURE lifetime '28800' + - set vpn ipsec ike-group AZURE proposal 1 dh-group '2' + - set vpn ipsec ike-group AZURE proposal 1 encryption 'aes256' + - set vpn ipsec ike-group AZURE proposal 1 hash 'sha1' + - set vpn ipsec ike-group AZURE close-action start + - set vpn ipsec option disable-route-autoinstall + - set interfaces vti vti1 address '10.1.100.11/32' + - set interfaces vti vti1 description 'Tunnel VyOS 02' + - set interfaces vti vti1 ip adjust-mss '1350' + - set protocols static route 10.2.100.11/32 interface vti1 + - set vpn ipsec authentication psk VyOS id '${public_ip_address_01}' + - set vpn ipsec authentication psk VyOS id '${on_prem_public_ip_address}' + - set vpn ipsec authentication psk VyOS secret 'ch00s3-4-s3cur3-psk' + - set vpn ipsec site-to-site peer VyOS-02 authentication local-id '${public_ip_address_01}' + - set vpn ipsec site-to-site peer VyOS-02 authentication mode 'pre-shared-secret' + - set vpn ipsec site-to-site peer VyOS-02 authentication remote-id '${on_prem_public_ip_address}' + - set vpn ipsec site-to-site peer VyOS-02 connection-type 'none' + - set vpn ipsec site-to-site peer VyOS-02 description 'AZURE TUNNEL to VyOS on NET 02' + - set vpn ipsec site-to-site peer VyOS-02 ike-group 'AZURE' + - set vpn ipsec site-to-site peer VyOS-02 ikev2-reauth 'inherit' + - set vpn ipsec site-to-site peer VyOS-02 local-address '${vyos_01_pub_nic_ip}' + - set vpn ipsec site-to-site peer VyOS-02 remote-address '${on_prem_public_ip_address}' + - set vpn ipsec site-to-site peer VyOS-02 vti bind 'vti1' + - set vpn ipsec site-to-site peer VyOS-02 vti esp-group 'AZURE' + - set protocols bgp system-as '${vnet_01_bgp_as_number}' + - set protocols bgp address-family ipv4-unicast network ${vnet_01_priv_subnet_prefix} + - set protocols bgp neighbor 10.2.100.11 remote-as '${on_prem_bgp_as_number}' + - set protocols bgp neighbor 10.2.100.11 address-family ipv4-unicast soft-reconfiguration inbound + - set protocols bgp neighbor 10.2.100.11 timers holdtime '30' + - set protocols bgp neighbor 10.2.100.11 timers keepalive '10' + - set protocols bgp neighbor 10.2.100.11 disable-connected-check diff --git a/Terraform/Azure/Site-to-Site-BGP/main.tf b/Terraform/Azure/Site-to-Site-BGP/main.tf new file mode 100644 index 0000000..0f7ebc8 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/main.tf @@ -0,0 +1,59 @@ + + +# --------------------------- VyOS 01 -------------------------------------- +# Net 01 VyOS 01 instance +resource "azurerm_virtual_machine" "net_01_VyOS_01" { + name = join("-", [var.prefix, "VyOS", "01"]) + location = var.location + resource_group_name = var.resource_group + vm_size = var.vm_size + tags = var.tags + + network_interface_ids = [azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id, azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.id] + primary_network_interface_id = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id + delete_os_disk_on_termination = "true" + + plan { + publisher = var.image_publisher + name = var.image_sku + product = var.image_offer + } + + storage_image_reference { + publisher = var.image_publisher + offer = var.image_offer + sku = var.image_sku + version = var.image_version + } + + storage_os_disk { + name = join("_", [var.prefix, "VyOS", "01", "osdisk"]) + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = join("-", [var.prefix, "VyOS", "01"]) + admin_username = var.admin_username + admin_password = var.admin_password + custom_data = base64encode(templatefile("${path.module}/files/vyos_01_user_data.tpl", { + vnet_01_priv_subnet_prefix = var.vnet_01_priv_subnet_prefix, + public_ip_address_01 = azurerm_public_ip.azure_vnet_01_public_address.ip_address, + on_prem_public_ip_address = var.on_prem_public_ip_address, + vyos_01_pub_nic_ip = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.private_ip_address, + vyos_01_priv_nic_ip = azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.private_ip_address, + dns_1 = var.dns_1, + dns_2 = var.dns_2, + vnet_01_bgp_as_number = var.vnet_01_bgp_as_number, + on_prem_bgp_as_number = var.on_prem_bgp_as_number + })) + } + + depends_on = [azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv, + azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub] + + os_profile_linux_config { + disable_password_authentication = false + } +} diff --git a/Terraform/Azure/Site-to-Site-BGP/outputs.tf b/Terraform/Azure/Site-to-Site-BGP/outputs.tf new file mode 100644 index 0000000..2a0b0e9 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/outputs.tf @@ -0,0 +1,12 @@ +# Management information +output "Admin_Username" { + value = var.admin_username +} +output "Admin_Password" { + value = var.admin_password +} + +# IP Address configuration +output "VyOS_01_Public_IP_Address" { + value = azurerm_public_ip.azure_vnet_01_public_address.ip_address +} diff --git a/Terraform/Azure/Site-to-Site-BGP/provider.tf b/Terraform/Azure/Site-to-Site-BGP/provider.tf new file mode 100644 index 0000000..09a6225 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/provider.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">=1.2" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">=3.99.0" + } + } +} + +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + diff --git a/Terraform/Azure/Site-to-Site-BGP/readme.md b/Terraform/Azure/Site-to-Site-BGP/readme.md new file mode 100644 index 0000000..0137080 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/readme.md @@ -0,0 +1,78 @@ +# VyOS instance (NVA) on Azure (with Site to Site VPN, Static/Dynamic (BGP), NAT, DNS forwarding options) + +This Terraform module deploys a VyOS instance (NVA) on Azure. All necessary parameters will be configured automatically, and you will receive management and access information from outputs. +This is the connection diagram: + + +The module consists of different files containing necessary resources and variables: + +- `provider.tf`: Each resource in the configuration must be associated with one provider configuration. Provider configurations, unlike most other concepts in Terraform, are global to an entire Terraform configuration and can be shared across module boundaries. + +- `variables.tf`: Access information, network parameters, VyOS image parameters, and virtual network parameters are defined here. You may edit/change these parameters based on your requirements. **Note:** After editing IP addresses inside `variables.tf`, check `files/vyos_01_user_data.tpl` file as well. All necessary configurations are based on this file. + +- `security_groups.tf`: Security groups are one of the most important pillars that support vNET security. They are software-defined network firewalls defined inside a vNet that allow or deny traffic to resources based on the inbound and outbound rules. They support stateful Layer 3 (Network layer) and Layer 4 (Transport layer) filtering capabilities. + +- `virtual_networks.tf`: All network resources such as Virtual Network, Subnets, Network Interface Cards, Public IP Address, Routing Table contains in this file. + +- `main.tf`: Contains the resource definitions for the VyOS VM (NVA). + +- `files/vyos_01_user_data.tpl` : All necessary configurations of the VyOS instance have been defined in this file based on the VyOS CLI reference. + +- `files/on_prem_vyos_instance.conf`: Contains the configuration for the on-premise VyOS instance, which can serve as a reference when setting up a site-to-site VPN with the Azure VyOS instance. + +- `outputs.tf`: Will contain the output definitions for the module, such as access data, Public IP Address of the VyOS instances, etc. + +## Prerequisites + +Before applying this module, ensure you have: + +- An active Azure subscription: + ```sh + az account set --subscription "<subscription ID or name>" + ``` + +- Azure CLI installed. [Installation link](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) + +- Logged in with Azure credentials via CLI: + ```sh + az version + az login + ``` + +- Azure Resource Group (RG) created: + ```sh + az group create --name demoResourceGroup --location westus + az group list + az group show --name exampleGroup + ``` + +- Terraform installed. [Installation link](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) + +## Usage + +### Setup Variables + +All variables needed for customization are defined in `variables.tf`. Adjust them according to your infrastructure requirements. + +### Implementation Process + +1. Run `terraform fmt` to format the structure. +2. Execute `terraform validate` to perform a syntax check. +3. Use `terraform plan` to preview the infrastructure changes before applying. +4. Run `terraform apply` to apply the script and provision the infrastructure. +5. Use `terraform output` to view the management IP and credentials for the VyOS instance. +6. To destroy the infrastructure, execute `terraform destroy`. + +### Management + +For management, use the `VyOS_01_Public_IP_Address` and VyOS credentials from `outputs`. + +Sample command: `ssh vyos@<VyOS_01_Public_IP_Address>` + +### Note + +Ensure that you have appropriate permissions and configurations set up in your Azure environment before executing the Terraform commands. + +Feel free to modify the script to suit your specific testing needs. + +For further assistance or customization, refer to the VyOS, Terraform, and Azure documentation.
\ No newline at end of file diff --git a/Terraform/Azure/Site-to-Site-BGP/security_groups.tf b/Terraform/Azure/Site-to-Site-BGP/security_groups.tf new file mode 100644 index 0000000..200e7df --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/security_groups.tf @@ -0,0 +1,97 @@ +resource "azurerm_network_security_group" "VyOS" { + name = join("-", [var.prefix, "VyOS", "SG"]) + location = var.location + resource_group_name = var.resource_group + tags = var.tags + + # For SSH Traffic + security_rule { + name = "SSH" + priority = 101 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For Wireguard Traffic + security_rule { + name = "Wireguard" + priority = 102 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "51820" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For OpenVPN Traffic + security_rule { + name = "OpenVPN" + priority = 103 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "1194" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For ESP Traffic + security_rule { + name = "ESP" + priority = 104 + direction = "Inbound" + access = "Allow" + protocol = "Esp" + source_port_range = "*" + destination_port_range = "*" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For IKE Traffic + security_rule { + name = "IKE" + priority = 105 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "500" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For IPSEC Traffic + security_rule { + name = "IPSEC" + priority = 106 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "1701" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For NAT Traversal + security_rule { + name = "NAT_Traversal" + priority = 107 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "4500" + source_address_prefix = "*" + destination_address_prefix = "*" + } +}
\ No newline at end of file diff --git a/Terraform/Azure/Site-to-Site-BGP/variables.tf b/Terraform/Azure/Site-to-Site-BGP/variables.tf new file mode 100644 index 0000000..806aa6e --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/variables.tf @@ -0,0 +1,113 @@ +# General Variables + +variable "location" { + description = "The region where all resources will deploy" + default = "LOCATION EXAMPLE: West Europe" +} + +variable "resource_group" { + description = "The name of your Azure Resource Group." + default = "<YOUR RESOURCE GROUP>" +} + +variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_B2s" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = { + environment = "Test" + project = "VyOS sample VPN" + owner = "VyOS Networks" + created-by = "Terraform" + } +} + +variable "prefix" { + default = "VPN-Instance" +} + +variable "dns_1" { + default = "8.8.8.8" +} + +variable "dns_2" { + default = "8.8.4.4" +} + +# ----------------------------------------------------------------- +# Variables related credentials +variable "admin_username" { + description = "Administrator user name" + default = "vyos" +} + +variable "admin_password" { + description = "Administrator password" + default = "<ADMIN PASSWORD>" +} + +# ----------------------------------------------------------------- +# Variables related image selection + +variable "image_publisher" { + description = "Name of the publisher of the image (az vm image list)" + default = "sentriumsl" +} + +variable "image_offer" { + description = "Name of the offer (az vm image list)" + default = "vyos-1-2-lts-on-azure" +} + +variable "image_sku" { + description = "Image SKU to apply (az vm image list)" + default = "vyos-1-3" +} + +variable "image_version" { + description = "Version of the image to apply (az vm image list)" + default = "1.4.0" +} + +# ----------------------------------------------------- +# Variables related Virtual Networks + +# VNet 01 + +variable "vnet_01_name" { + description = "The name for your virtual network." + default = "Net-01" +} + +variable "vnet_01_address_prefix" { + description = "The address space that is used by the virtual network." + default = "10.1.0.0/16" +} + +variable "vnet_01_priv_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.1.0/24" +} + +variable "vnet_01_pub_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.11.0/24" +} + +variable "vnet_01_bgp_as_number" { + default = "65001" +} + +# On Prem Data Center + +variable "on_prem_bgp_as_number" { + default = "65002" +} + +variable "on_prem_public_ip_address" { + default = "192.0.2.1" +} diff --git a/Terraform/Azure/Site-to-Site-BGP/virtual_networks.tf b/Terraform/Azure/Site-to-Site-BGP/virtual_networks.tf new file mode 100644 index 0000000..5398da2 --- /dev/null +++ b/Terraform/Azure/Site-to-Site-BGP/virtual_networks.tf @@ -0,0 +1,107 @@ +# vNET Creation +resource "azurerm_virtual_network" "azure_vnet_01" { + name = join("-", [var.prefix, var.vnet_01_name]) + address_space = [var.vnet_01_address_prefix] + location = var.location + resource_group_name = var.resource_group + depends_on = [ + var.resource_group + ] + tags = var.tags +} + +# Net 01 Subnet Private +resource "azurerm_subnet" "azure_vnet_01_priv_subnet" { + name = join("-", [var.prefix, var.vnet_01_name, "priv"]) + resource_group_name = var.resource_group + address_prefixes = [var.vnet_01_priv_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_01.name +} + +# Net 01 Subnet Public +resource "azurerm_subnet" "azure_vnet_01_pub_subnet" { + name = join("-", [var.prefix, var.vnet_01_name, "pub"]) + resource_group_name = var.resource_group + address_prefixes = [var.vnet_01_pub_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_01.name +} + +# Public Address +resource "azurerm_public_ip" "azure_vnet_01_public_address" { + name = join("-", [var.prefix, var.vnet_01_name, "public", "IP"]) + location = var.location + resource_group_name = var.resource_group + sku = "Standard" + allocation_method = "Static" + idle_timeout_in_minutes = "30" + tags = var.tags +} + +# VyOS Route Table +resource "azurerm_route_table" "azure_vnet_01_vyos_01_route" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "route"]) + resource_group_name = var.resource_group + location = var.location + disable_bgp_route_propagation = false + tags = var.tags + + route { + name = "Default" + address_prefix = "0.0.0.0/0" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = azurerm_network_interface.azure_vnet_01_vyos_01_nic_priv.private_ip_address + } +} + +# Assosiate route table to subnet +resource "azurerm_subnet_route_table_association" "azure_vnet_vpn_net_assosiation_01" { + subnet_id = azurerm_subnet.azure_vnet_01_priv_subnet.id + route_table_id = azurerm_route_table.azure_vnet_01_vyos_01_route.id +} + +# --------------------------- Network Interface Cards ------------------------ + +# VyOS-01 Pub-NIC +resource "azurerm_network_interface" "azure_vnet_01_vyos_01_nic_pub" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "pub", "NIC"]) + location = var.location + resource_group_name = var.resource_group + enable_ip_forwarding = true + tags = var.tags + + ip_configuration { + name = "external-01" + subnet_id = azurerm_subnet.azure_vnet_01_pub_subnet.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.azure_vnet_01_public_address.id + } + + depends_on = [ + azurerm_virtual_network.azure_vnet_01 + ] +} + +# VyOS-01 Priv-NIC +resource "azurerm_network_interface" "azure_vnet_01_vyos_01_nic_priv" { + name = join("-", [var.prefix, var.vnet_01_name, "VyOS", "01", "priv", "NIC"]) + location = var.location + resource_group_name = var.resource_group + enable_ip_forwarding = true + tags = var.tags + + ip_configuration { + name = "internal-01" + subnet_id = azurerm_subnet.azure_vnet_01_priv_subnet.id + private_ip_address_allocation = "Dynamic" + } + + depends_on = [ + azurerm_virtual_network.azure_vnet_01 + ] +} + +# VyOS 01 Security Group Assosiation +resource "azurerm_network_interface_security_group_association" "azure_vnet_01_vyos_01_pub_attach" { + network_interface_id = azurerm_network_interface.azure_vnet_01_vyos_01_nic_pub.id + network_security_group_id = azurerm_network_security_group.VyOS.id +} diff --git a/Terraform/Azure/VPN-Server-WireGuard/diagram/VPN-SRV-on-Azure.png b/Terraform/Azure/VPN-Server-WireGuard/diagram/VPN-SRV-on-Azure.png Binary files differnew file mode 100644 index 0000000..25fa8bf --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/diagram/VPN-SRV-on-Azure.png diff --git a/Terraform/Azure/VPN-Server-WireGuard/files/vyos_user_data.tpl b/Terraform/Azure/VPN-Server-WireGuard/files/vyos_user_data.tpl new file mode 100644 index 0000000..0891f06 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/files/vyos_user_data.tpl @@ -0,0 +1,21 @@ +#cloud-config +vyos_config_commands: + - set system host-name 'VyOS-for-VPN-0${vyos_number}' + - set system login banner pre-login 'Welcome to the VyOS VPN Server on Azure' + - set interfaces ethernet eth0 description 'OUTSIDE' + - set system name-server '${dns_1}' + - set system name-server '${dns_2}' + - set service dns forwarding name-server '${dns_1}' + - set service dns forwarding listen-address '${wg_server_Private_IP}' + - set service dns forwarding allow-from '${wg_server_subnet_prefix}' + - set service dns forwarding no-serve-rfc1918 + - set nat source rule 10 outbound-interface name 'eth0' + - set nat source rule 10 source address '${wg_server_subnet_prefix}' + - set nat source rule 10 translation address 'masquerade' + - set interfaces wireguard wg01 address '${wg_server_Private_IP}/24' + - set interfaces wireguard wg01 description 'RoadWarrior' + - set interfaces wireguard wg01 private-key '${wg_server_PrivKey}' + - set interfaces wireguard wg01 peer Clien-01 allowed-ips '0.0.0.0/0' + - set interfaces wireguard wg01 peer Clien-01 public-key '${wg_client_PubKey}' + - set interfaces wireguard wg01 port '${wg_server_port}' + - set interfaces wireguard wg01 peer Clien-01 preshared-key '${wg_client_PresharedKey}'
\ No newline at end of file diff --git a/Terraform/Azure/VPN-Server-WireGuard/files/wireguard.tpl b/Terraform/Azure/VPN-Server-WireGuard/files/wireguard.tpl new file mode 100644 index 0000000..bccc166 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/files/wireguard.tpl @@ -0,0 +1,11 @@ +[Interface] +PrivateKey = ${wg_client_PrivKey} +Address = ${wg_client_IP}/24 +DNS = ${wg_server_Private_IP} + +[Peer] +PublicKey = ${wg_server_PublicKey} +PresharedKey = ${wg_client_PresharedKey} +Endpoint = ${wg_server_Public_IP}:${wg_server_port} +AllowedIPs = 0.0.0.0/0 +PersistentKeepalive = 15 diff --git a/Terraform/Azure/VPN-Server-WireGuard/loadbalancer.tf b/Terraform/Azure/VPN-Server-WireGuard/loadbalancer.tf new file mode 100644 index 0000000..7731df9 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/loadbalancer.tf @@ -0,0 +1,109 @@ +# Create Load Balancer +resource "azurerm_lb" "azurerm_lb_vyos_vpn_lb" { + name = join("-", [var.prefix, "VyOS", "VPN", "Pub", "LB"]) + location = var.location + resource_group_name = var.resource_group + sku = "Standard" + tags = var.tags + + frontend_ip_configuration { + name = "PublicIPAddress" + public_ip_address_id = azurerm_public_ip.azure_vnet_public_address_lb.id + } +} + +resource "azurerm_lb_backend_address_pool" "azure_lb_pool" { + name = "BackEndAddressPool" + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id +} + +resource "azurerm_lb_probe" "azure_lb_probe" { + name = "VyOS_Test" + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + port = 22 +} + +resource "azurerm_lb_rule" "azure_lb_rule_wireguard" { + name = "WireGuard" + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + protocol = "Udp" + frontend_port = var.wg_server_port + backend_port = var.wg_server_port + frontend_ip_configuration_name = "PublicIPAddress" + probe_id = azurerm_lb_probe.azure_lb_probe.id + backend_address_pool_ids = [azurerm_lb_backend_address_pool.azure_lb_pool.id] + load_distribution = "SourceIPProtocol" + enable_floating_ip = false + disable_outbound_snat = true +} + +resource "azurerm_network_interface_backend_address_pool_association" "vnet_VyOS" { + count = 2 + network_interface_id = azurerm_network_interface.azure_vnet_vpn_net_nic[count.index].id + ip_configuration_name = "ifconfig-${count.index}" + backend_address_pool_id = azurerm_lb_backend_address_pool.azure_lb_pool.id + depends_on = [azurerm_network_interface.azure_vnet_vpn_net_nic] +} + +resource "azurerm_lb_nat_rule" "azure_lb_nat_rule_dns_udp" { + resource_group_name = var.resource_group + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + name = "DNS-UDP" + protocol = "Udp" + frontend_port = 53 + backend_port = 53 + frontend_ip_configuration_name = "PublicIPAddress" +} + +resource "azurerm_lb_nat_rule" "azure_lb_nat_rule_dns_tcp" { + resource_group_name = var.resource_group + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + name = "DNS-TCP" + protocol = "Tcp" + frontend_port = 53 + backend_port = 53 + frontend_ip_configuration_name = "PublicIPAddress" +} + +resource "azurerm_lb_nat_rule" "azure_lb_nat_rule_http" { + resource_group_name = var.resource_group + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + name = "HTTP" + protocol = "Tcp" + frontend_port = 80 + backend_port = 80 + frontend_ip_configuration_name = "PublicIPAddress" +} + +resource "azurerm_lb_nat_rule" "azure_lb_nat_rule_https" { + resource_group_name = var.resource_group + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + name = "HTTPS" + protocol = "Tcp" + frontend_port = 443 + backend_port = 443 + frontend_ip_configuration_name = "PublicIPAddress" +} + +resource "azurerm_lb_nat_rule" "azure_lb_nat_rule_ssh" { + resource_group_name = var.resource_group + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + name = "SSH" + protocol = "Tcp" + frontend_port_start = 21 + frontend_port_end = 22 + backend_port = 22 + backend_address_pool_id = azurerm_lb_backend_address_pool.azure_lb_pool.id + frontend_ip_configuration_name = "PublicIPAddress" +} + +resource "azurerm_lb_outbound_rule" "azurerm_lb_outbound_WG_out" { + name = "OutboundRule" + loadbalancer_id = azurerm_lb.azurerm_lb_vyos_vpn_lb.id + protocol = "All" + backend_address_pool_id = azurerm_lb_backend_address_pool.azure_lb_pool.id + + frontend_ip_configuration { + name = "PublicIPAddress" + } +} diff --git a/Terraform/Azure/VPN-Server-WireGuard/main.tf b/Terraform/Azure/VPN-Server-WireGuard/main.tf new file mode 100644 index 0000000..22c7a63 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/main.tf @@ -0,0 +1,70 @@ + +# Create VyOS instances +resource "azurerm_virtual_machine" "azure_vpn_net_vyos" { + count = 2 + name = join("-", [var.prefix, "VyOS", "${count.index + 1}"]) + location = var.location + resource_group_name = var.resource_group + vm_size = var.vm_size + + network_interface_ids = [azurerm_network_interface.azure_vnet_vpn_net_nic[count.index].id] + delete_os_disk_on_termination = "true" + tags = var.tags + + plan { + publisher = var.image_publisher + name = var.image_sku + product = var.image_offer + } + + storage_image_reference { + # id = var.gallery + publisher = var.image_publisher + offer = var.image_offer + sku = var.image_sku + version = var.image_version + } + + storage_os_disk { + name = join("_", [var.vnet_name, "VyOS", "${count.index + 1}", "osdisk"]) + managed_disk_type = "Standard_LRS" + caching = "ReadWrite" + create_option = "FromImage" + } + + os_profile { + computer_name = join("-", [var.vnet_name, "VyOS", "${count.index + 1}"]) + admin_username = var.admin_username + admin_password = var.admin_password + custom_data = base64encode(templatefile("${path.module}/files/vyos_user_data.tpl", { + wg_server_subnet_prefix = var.wg_server_subnet_prefix, + wg_server_Private_IP = var.wg_server_Private_IP, + wg_server_port = var.wg_server_port, + wg_server_PrivKey = var.wg_server_PrivKey, + wg_client_PubKey = var.wg_client_PublicKey, + wg_client_PresharedKey = var.wg_client_PresharedKey, + dns_1 = var.dns_1, + dns_2 = var.dns_2, + vyos_number = count.index + 1 + })) + } + + os_profile_linux_config { + disable_password_authentication = false + } +} + +# Generate WireGuard client profile +data "template_file" "wireguard_config" { + template = file("${path.module}/files/wireguard.tpl") + + vars = { + wg_client_PrivKey = var.wg_client_PrivKey + wg_client_IP = var.wg_client_IP + wg_server_Private_IP = var.wg_server_Private_IP + wg_server_Public_IP = azurerm_public_ip.azure_vnet_public_address_lb.ip_address + wg_server_PublicKey = var.wg_server_PublicKey + wg_server_port = var.wg_server_port + wg_client_PresharedKey = var.wg_client_PresharedKey + } +}
\ No newline at end of file diff --git a/Terraform/Azure/VPN-Server-WireGuard/outputs.tf b/Terraform/Azure/VPN-Server-WireGuard/outputs.tf new file mode 100644 index 0000000..3edb70d --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/outputs.tf @@ -0,0 +1,30 @@ +# Management information + +output "Admin_Username" { + value = var.admin_username +} + +output "Admin_Password" { + value = var.admin_password +} + +# IP Address configuration + +output "VPN_Server_Public_IP_Address" { + value = azurerm_public_ip.azure_vnet_public_address_lb.ip_address +} + +output "VyOS_01_Private_IP_Address" { + value = azurerm_network_interface.azure_vnet_vpn_net_nic[0].private_ip_address +} + +output "VyOS_02_Private_IP_Address" { + value = azurerm_network_interface.azure_vnet_vpn_net_nic[1].private_ip_address +} + +# VPN Client Profiles + +resource "local_file" "wireguard_profile" { + filename = "${path.module}/profiles/wireguard_profile.conf" + content = data.template_file.wireguard_config.rendered +}
\ No newline at end of file diff --git a/Terraform/Azure/VPN-Server-WireGuard/provider.tf b/Terraform/Azure/VPN-Server-WireGuard/provider.tf new file mode 100644 index 0000000..09a6225 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/provider.tf @@ -0,0 +1,18 @@ +terraform { + required_version = ">=1.2" + required_providers { + azurerm = { + source = "hashicorp/azurerm" + version = ">=3.99.0" + } + } +} + +provider "azurerm" { + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } +} + diff --git a/Terraform/Azure/VPN-Server-WireGuard/readme.md b/Terraform/Azure/VPN-Server-WireGuard/readme.md new file mode 100644 index 0000000..cb1d894 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/readme.md @@ -0,0 +1,92 @@ +# VyOS Redundant VPN Server on Azure + +This Terraform module deploys a redundant VPN server (Wireguard) on Azure. All necessary parameters will be configured automatically, and you will receive management and access information from outputs. +This is the connection diagram: + + +The module consists of different files containing necessary resources and variables: + +- `provider.tf`: Each resource in the configuration must be associated with one provider configuration. Provider configurations, unlike most other concepts in Terraform, are global to an entire Terraform configuration and can be shared across module boundaries. + +- `variables.tf`: Access information, network parameters, VyOS image parameters, and virtual parameters are defined here. You may edit/change these parameters based on your requirements. **Note:** After editing IP addresses inside `variables.tf`, check `files/vyos_user_data.tpl` file as well. All necessary configurations are based on this file. + +- `security_groups.tf`: Security groups are one of the most important pillars that support vNET security. They are software-defined network firewalls defined inside a vNet that allow or deny traffic to resources based on the inbound and outbound rules. They support stateful Layer 3 (Network layer) and Layer 4 (Transport layer) filtering capabilities. + +- `virtual_networks.tf`: All network resources such as Virtual Network, Subnets, Network Interface Cards, Public IP Address, Routing Table contains in this file. + +- `loadbalacer.tf`: Resources according to the Public Load balancer are in this file. + +- `main.tf`: Contains all parameters of the VyOS VM (NVA) resources. + +- `files/vyos_user_data.tpl` : All necessary configurations of the VyOS have been defined in this file based on VyOS cli reference. + +- `files/wireguard.tpl` : WireGuard client configuration template placed here. All static values of the placeholders will be provided inside `variables.tf` file. + +- `outputs.tf`: Will contain the output definitions for the module, such as access data, Public IP Address of the Load Balancer, Private IP Address of the VyOS VMs, WireGuard client profile also will be provided `profiles` folder (after the successfull lunch). Your WireGuard client profile will be like `profiles/wireguard_profile.conf`. + +## Prerequisites + +Before applying this module, ensure you have: + +- An active Azure subscription: + ```sh + az account set --subscription "<subscription ID or name>" + ``` + +- Azure CLI installed. [Installation link](https://learn.microsoft.com/en-us/cli/azure/install-azure-cli) + +- Logged in with Azure credentials via CLI: + ```sh + az version + az login + ``` + +- Azure Resource Group (RG) created: + ```sh + az group create --name demoResourceGroup --location westus + az group list + az group show --name exampleGroup + ``` + +- Terraform installed. [Installation link](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) + +- Additionally, you will need WireGuard client software. [Installation link](https://www.wireguard.com/install/) + + +## Usage + +### Setup Variables + +All variables needed for customization are defined in `variables.tf`. Adjust them according to your infrastructure requirements. + +### Implementation Process + +1. Run `terraform fmt` to format the structure. +2. Execute `terraform validate` to perform a syntax check. +3. Use `terraform plan` to preview the infrastructure changes before applying. +4. Run `terraform apply` to apply the script and provision the infrastructure. +5. To destroy the infrastructure, execute `terraform destroy`. + +### Management + +For management, use `VPN_Server_Public_IP_Address` and VyOS credentials from `outputs`. + +Command sample: +```sh +ssh vyos@<VPN_Server_Public_IP_Address> +``` + +P.S. With the public address, you can manage only the `active` VyOS instance. If you want to manage both instances at the same time, you need to initiate a remote access VPN connection via WireGuard software (by uploading the client profile file from the profiles folder). After a successful connection, you can manage instances using `VyOS_01_Private_IP_Address` and `VyOS_02_Private_IP_Address` from `outputs`. + +```sh +ssh vyos@<VyOS_01_Private_IP_Address> +ssh vyos@<VyOS_02_Private_IP_Address> +``` + +### Note + +Ensure that you have appropriate permissions and configurations set up in your Azure environment before executing the Terraform commands. + +Feel free to modify the script to suit your specific testing needs. + +For further assistance or customization, refer to the VyOS, Terraform, and Azure documentation. diff --git a/Terraform/Azure/VPN-Server-WireGuard/security_groups.tf b/Terraform/Azure/VPN-Server-WireGuard/security_groups.tf new file mode 100644 index 0000000..ffc63ad --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/security_groups.tf @@ -0,0 +1,32 @@ +resource "azurerm_network_security_group" "azure_sg_vyos" { + name = join("-", [var.prefix, "VyOS", "SG"]) + location = var.location + resource_group_name = var.resource_group + tags = var.tags + + # For SSH Traffic + security_rule { + name = "SSH-VyOS" + priority = 101 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } + + # For Wireguard Traffic + security_rule { + name = "Wireguard" + priority = 103 + direction = "Inbound" + access = "Allow" + protocol = "Udp" + source_port_range = "*" + destination_port_range = "51820" + source_address_prefix = "*" + destination_address_prefix = "*" + } +}
\ No newline at end of file diff --git a/Terraform/Azure/VPN-Server-WireGuard/variables.tf b/Terraform/Azure/VPN-Server-WireGuard/variables.tf new file mode 100644 index 0000000..7aa95dc --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/variables.tf @@ -0,0 +1,141 @@ +# General Variables + +variable "location" { + description = "The region where all resources will deploy" + default = "LOCATION EXAMPLE: West Europe" +} + +variable "resource_group" { + description = "The name of your Azure Resource Group." + default = "<YOUR RESOURCE GROUP>" +} + +variable "tags" { + description = "A map of tags to add to all resources" + type = map(string) + default = { + environment = "Test" + project = "VyOS VPN Server" + owner = "VyOS Networks" + created-by = "Terraform" + } +} + +variable "prefix" { + default = "WG-Server" +} + +variable "dns_1" { + default = "8.8.8.8" +} + +variable "dns_2" { + default = "8.8.4.4" +} + +#------------------------------------------------------------------------------------------ +# VyOS credentials + +variable "admin_username" { + description = "Administrator user name" + default = "vyos" +} + +variable "admin_password" { + description = "Administrator password" + default = "<ADMIN PASSWORD>" +} + +#------------------------------------------------------------------------------------------ +# Variables related VyOS VM and image selection + +variable "vm_size" { + description = "Specifies the size of the virtual machine." + default = "Standard_B2s" +} + +variable "image_publisher" { + description = "Name of the publisher of the image (az vm image list)" + default = "sentriumsl" +} + +variable "image_offer" { + description = "Name of the offer (az vm image list)" + default = "vyos-1-2-lts-on-azure" +} + +variable "image_sku" { + description = "Image SKU to apply (az vm image list)" + default = "vyos-1-3" +} + +variable "image_version" { + description = "Version of the image to apply (az vm image list)" + default = "1.4.0" +} + +#------------------------------------------------------------------------------------------ +# Variables related Virtual Networks + +variable "vnet_name" { + description = "The name for your virtual network." + default = "Net-01" +} + +variable "vnet_address_prefix" { + description = "The address space that is used by the virtual network." + default = "10.1.0.0/16" +} + +variable "vnet_pub_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.1.0/24" +} + +#------------------------------------------------------------------------------------------ +# Variables related Wireguard Server + +variable "wg_server_subnet_prefix" { + description = "The address prefix to use for the subnet." + default = "10.1.2.0/24" +} + +variable "wg_server_Private_IP" { + description = "Wire Guard Server Address" + default = "10.1.2.1" +} + +variable "wg_server_port" { + description = "Wire Guard Server Port" + default = "51820" +} + +variable "wg_client_IP" { + description = "Wire Guard Client Address" + default = "10.1.2.11" +} + +variable "wg_server_PrivKey" { + description = "Generated private key for VPN server" + default = "MGRrol9mdevug6S5ksagHYXBHs0tsrLG4mCPCLLlqVY=" +} + +variable "wg_server_PublicKey" { + description = "Generated public key for VPN server" + default = "0joKaK46kKLDmeBWXWnxLf8xP64UUniTl1nfPnRsvCY=" +} + +variable "wg_client_PrivKey" { + description = "Generated private key for VPN client" + default = "KF8jW6cdE7nPjM2eVHEx/PnZV0duSAsKAslZEiqLv1s=" +} + +variable "wg_client_PublicKey" { + description = "Generated public key for VPN client" + default = "OH9NFyoUaa1hK5ko72zy+rF7yPGycqd9fqcQ0+pLiWk=" +} + +variable "wg_client_PresharedKey" { + description = "Generated preshared key for VPN client" + default = "eXdHmjDsb46xuqvqBDL+O+03Si2eauJkPt9XuhapWuE=" +}
\ No newline at end of file diff --git a/Terraform/Azure/VPN-Server-WireGuard/virtual_networks.tf b/Terraform/Azure/VPN-Server-WireGuard/virtual_networks.tf new file mode 100644 index 0000000..a1671e7 --- /dev/null +++ b/Terraform/Azure/VPN-Server-WireGuard/virtual_networks.tf @@ -0,0 +1,88 @@ +# vNET Creation +resource "azurerm_virtual_network" "azure_vnet_vpn_net" { + name = var.vnet_name + address_space = [var.vnet_address_prefix] + location = var.location + resource_group_name = var.resource_group + depends_on = [ + var.resource_group + ] + tags = var.tags +} + +# vNet Subnet Public +resource "azurerm_subnet" "azure_vnet_pub_subnet" { + name = join("-", [var.prefix, var.vnet_name, "pub"]) + resource_group_name = var.resource_group + address_prefixes = [var.vnet_pub_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_vpn_net.name +} + +# vNet Subnet Wire Guard +resource "azurerm_subnet" "azure_vnet_priv_subnet" { + name = join("-", [var.prefix, var.vnet_name, "priv-wg"]) + resource_group_name = var.resource_group + address_prefixes = [var.wg_server_subnet_prefix] + virtual_network_name = azurerm_virtual_network.azure_vnet_vpn_net.name +} + +# Public Address +resource "azurerm_public_ip" "azure_vnet_public_address_lb" { + name = join("-", [var.prefix, var.vnet_name, "VPN", "LB", "public", "IP"]) + location = var.location + resource_group_name = var.resource_group + sku = "Standard" + allocation_method = "Static" + idle_timeout_in_minutes = "30" + tags = var.tags +} + +# VyOS Route Table +resource "azurerm_route_table" "azure_vnet_vpn_net_VyOS_route" { + name = join("-", [var.prefix, var.vnet_name, "VyOS", "route"]) + resource_group_name = var.resource_group + location = var.location + disable_bgp_route_propagation = false + tags = var.tags + + route { + name = "Default" + address_prefix = "0.0.0.0/0" + next_hop_type = "VirtualAppliance" + next_hop_in_ip_address = var.wg_server_Private_IP + } +} + +# Assosiate route table to subnet +resource "azurerm_subnet_route_table_association" "azure_vnet_vpn_net_assosiation" { + subnet_id = azurerm_subnet.azure_vnet_priv_subnet.id + route_table_id = azurerm_route_table.azure_vnet_vpn_net_VyOS_route.id +} + +# Create NIC for VyOS +resource "azurerm_network_interface" "azure_vnet_vpn_net_nic" { + count = 2 + name = join("-", [var.prefix, var.vnet_name, "VyOS", "${count.index}", "NIC"]) + location = var.location + resource_group_name = var.resource_group + enable_ip_forwarding = true + tags = var.tags + + ip_configuration { + name = "ifconfig-${count.index}" + subnet_id = azurerm_subnet.azure_vnet_pub_subnet.id + private_ip_address_allocation = "Dynamic" + } + + depends_on = [ + azurerm_virtual_network.azure_vnet_vpn_net + ] +} + +# VyOS Security Group Assosiation +resource "azurerm_network_interface_security_group_association" "vpn_net_VyOS_attach" { + count = 2 + network_interface_id = azurerm_network_interface.azure_vnet_vpn_net_nic[count.index].id + network_security_group_id = azurerm_network_security_group.azure_sg_vyos.id + depends_on = [azurerm_network_security_group.azure_sg_vyos] +} |