Side2Side VPN connection between OpenStack VPN and AVM Fritz!Box

Define variables for OpenStack VPN configuration

FRITZBOX_EXTERNAL_IP=x.x.x.x                    # curl ipinfo.io/ip
FRITZBOX_NETWORK=192.168.178.0/24               # Heimnetz > Netzwerk > Netzwerkeinstellungen > IPv4-Einstellungen
PASSWORD='xxxxxxxx'                             # apg -m 32
OPENSTACK_SUBNET_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # openstack subnet list
OPENSTACK_ROUTER_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # openstack router list

Define variables

# Create ike v1 policy
openstack vpn ike policy create vpn_ike_1 \
  --ike-version v1 \
  --encryption-algorithm aes-256 \
  --auth-algorithm sha256 \
  --pfs group14
 
# Create ipsec policy
openstack vpn ipsec policy create vpn_ipsec_1 \
  --encryption-algorithm aes-256 \
  --auth-algorithm sha256 \
  --pfs group14
 
# Create service
openstack vpn service create vpn_service_1 \
  --router ${OPENSTACK_ROUTER_ID} 
 
# Create local endpoint group
openstack vpn endpoint group create vpn_endpoint_openstack \
  --type subnet \
  --value ${OPENSTACK_SUBNET_ID}
 
# Create peer endpoint group
openstack vpn endpoint group create vpn_endpoint_fritzbox \
  --type cidr \
  --value ${FRITZBOX_NETWORK}
 
# Create connection
openstack vpn ipsec site connection create vpn_connection_1 \
  --vpnservice vpn_service_1 \
  --ikepolicy vpn_ike_1 \
  --ipsecpolicy vpn_ipsec_1 \
  --peer-address ${FRITZBOX_EXTERNAL_IP} \
  --peer-id ${FRITZBOX_NETWORK} \
  --psk ${PASSWORD} \
  --local-endpoint-group vpn_endpoint_openstack \
  --peer-endpoint-group vpn_endpoint_fritzbox

Allow SSH access from VPN

Cleanup / delete OpenStack objects

PROJECT_ID=f0f745a9c79c47fdbbdd187d728f9e41
 
# Delete VMs
openstack server list --project ${PROJECT_ID}
openstack server delete ${SERVER_ID}
 
openstack volume list --project ${PROJECT_ID}
openstack volume delete ${VOLUME_ID}
 
openstack image list --private --long | grep ${PROJECT_ID}
openstack image delete ${IMAGE_ID}
 
# Delete loadbalancer
openstack loadbalancer list --project ${PROJECT_ID}
openstack loadbalancer delete --cascade ${LOADBALANCER_ID}
 
# Delete secrets
openstack secret list
openstack secret delete ${SECRET_URL}
 
# Delete VPNs
openstack vpn ipsec site connection list --long | grep ${PROJECT_ID}
openstack vpn ipsec site connection delete ${IPSEC_SITE_CONNECTION_ID}
openstack vpn endpoint group list --long | grep ${PROJECT_ID}
openstack vpn endpoint group delete ${VPN_LOCAL_ENDPOINT_GROUP_ID} ${VPN_PEER_ENDPOINT_GROUP_ID}
openstack vpn service list --long | grep ${PROJECT_ID}
openstack vpn service delete ${VPN_SERVICE_ID}
openstack vpn ipsec policy list --long | grep ${PROJECT_ID}
openstack vpn ipsec policy delete ${VPN_IPSEC_POLICY_ID}
openstack vpn ike policy list --long | grep ${PROJECT_ID}
openstack vpn ike policy delete ${VPN_IKE_POLICY_ID}
 
# Delete k8s
openstack coe cluster list 
 
# Delete floating ip
openstack floating ip list --project ${PROJECT_ID}
openstack floating ip delete ${FLOATING_IP}
 
# Delete router

OpenStack Debug VPN connection

Find the VPN server and the relevant router UUID

# get VPN connection ID
openstack vpn ipsec site connection list | grep foo
openstack vpn ipsec site connection list --long | grep <project_id>
 
VPN_CONNECTION_ID=142dc25f-13bb-4fda-b093-edf13df98ed8
openstack vpn ipsec site connection show ${VPN_CONNECTION_ID}
 
VPN_SERVICE_ID=$(openstack vpn ipsec site connection show ${VPN_CONNECTION_ID} -c 'VPN Service' -f value)
openstack vpn service show ${VPN_SERVICE_ID}
 
# get router ID
ROUTER_ID=$(openstack vpn service show ${VPN_SERVICE_ID} -c Router -f value)
echo "ROUTER_ID=${ROUTER_ID}"

Find the ctl Node where the active router is running

ROUTER_PORT_ID=$(openstack port list --device-owner network:router_gateway -f value -c id --router ${ROUTER_ID})
CONTROL_NODE=$(openstack port show ${ROUTER_PORT_ID} -c binding_host_id -f value)
echo "CONTROL_NODE: ${CONTROL_NODE}"
 
echo "ssh ${CONTROL_NODE} sudo ip netns exec qrouter-${ROUTER_ID} ip a s"

Connect to that ctl node and "jump" in its neutron-l3-agent docker container

Xiaomi Mi A2 Lite (daisy)

Enable USB-Debugging and unlock phone

# Connect phone to Wifi
Settings > About Phone > Build number > tap 7x times to become developer
Settings > System > Advanced > Developer Options > OEM unclocking
Settings > System > Advanced > Developer Options > USB Debugging > OK

Unlock phone

# Connect phone to computer
adb devices
# Accept "Allow access with your computer RSA key" on phone
adb reboot bootloader
fastboot oem unlock

Boot bootloader

Power Off phone
Hold volume_down + power
 
OPTIONAL: Recovery phone with original Xiaomi image to update firmware

Flash custom image
https://arrowos.net/download
# ArrowOS download: https://get.mirror1.arrowos.net/download.php?token=oD03QRrG9umnU1Egj6VspKXNwaiIlcYSOqbfCdyP4x8WzMtT7kL2hHZFJAv5&version=arrow-11.0&variant=community&device=daisy
#OpenGA apps: https://netix.dl.sourceforge.net/project/opengapps/arm64/test/20210130/open_gapps-arm64-11.0-pico-20210130-TEST.zip
NikGapps: https://sourceforge.net/projects/nikgapps/files/Releases/NikGapps-SL/18-Feb-2023/NikGapps-core-arm64-12.1-20230218-signed.zip/download

Terraform: Create LoadBalancer in OpenStack

provider "openstack" {
  cloud = "lab-admin"
  use_octavia = true
}
 
# data "template_file" "user_data" {
#   template = file("user-data.txt")
# }
 
data "template_file" "user_data" {
  template = <<EOF
#cloud-config
package_update: true
packages:
 - nginx
runcmd:
 - hostname -f | sudo tee /var/www/html/index.nginx-debian.html
 - id > /tmp/debug
EOF
}
 
variable "http_instance_names" {
  type = set(string)
  default = ["www1", "www2"]
}
 
resource "openstack_compute_instance_v2" "http" {
  for_each    = var.http_instance_names
  name        = each.key
 #name = "www${count.index + 1}"
 #count = 2
 image_name = "Ubuntu 20.04 minimal"
 flavor_name = "m1.small"
 key_pair = "lab-key"
 security_groups = ["default"]
 user_data = data.template_file.user_data.rendered
 
 network {
   name = "demo-net"
 }
}
 
data "openstack_networking_network_v2" "network_1" {
  name = "demo-net"
}
 
data "openstack_networking_subnet_v2" "subnet_1" {
  name = "demo-subnet"
  network_id = data.openstack_networking_network_v2.network_1.id
}
 
# Create loadbalancer
resource "openstack_lb_loadbalancer_v2" "http" {
  name          = "demo-lb1"
  vip_subnet_id = data.openstack_networking_subnet_v2.subnet_1.id
}