OpenIKED
Overview
OpenIKED is the OpenBSD project's free implementation of the Internet Key Exchange version 2 (IKEv2) protocol. IKEv2 is the part of an IPsec VPN that authenticates the two peers to each other, negotiates the cipher suite, and installs the security associations that the kernel uses to encrypt traffic. OpenIKED drives the Linux kernel IPsec stack directly, so once a tunnel is up the data path runs in the kernel rather than in a userspace process.
This SecureAnyCloud image gives you an IKEv2 gateway that is secure by default. No key material ships inside the image, the shipped /etc/iked.conf declares no policy and accepts no connections, and a built-in self test proves a real IKEv2 negotiation on the VM.
What you get:
- OpenIKED 7.3 (Ubuntu 24.04 noble archive package
openiked) running as theopenikedsystem service - A unique gateway identity per VM: a fresh RSA 4096 IKEv2 host keypair, with private key mode
0600 root:root, and a fresh per-VM secret, both generated on the first boot of every deployed VM by openiked-firstboot.service. The daemon cannot start until this has happened, so a VM never runs with a missing or borrowed identity - A secure-by-default
/etc/iked.confwith no policy and no pre-shared key, plus commented, ready-to-copy examples that use modern proposals only. The gateway accepts and initiates nothing until you declare your own peer - IP forwarding off by default, so the appliance does not silently act as a router
openiked-ctl, a management tool for status, key fingerprint, peer import, forwarding, configuration reload and the self testopeniked-ctl selftestandopeniked-selftest.sh, which perform a genuine IKEv2 negotiation between two isolated endpoints on the VM using this VM's own host key. They check the result against the kernel's IPsec state: a keyed security association was installed, both daemons reached the established state, the peer's public key was validated and its signature verified, the negotiated cipher is the modern one, and real traffic was encrypted. A negative control proves that a peer presenting the wrong key is refused- A root-only credentials file at
/root/openiked-credentials.txtthat records the host key fingerprint and the per-VM secret - 24/7 SecureAnyCloud support
Key facts:
- Platform: Ubuntu 24.04 LTS (Azure Gen2)
- Default administrator: azureuser
- Service: openiked.service
- Configuration: /etc/iked.conf
- Private host key: /etc/iked/private/local.key (mode 0600, owner root:root)
- Public host key: /etc/iked/local.pub
- Credentials file: /root/openiked-credentials.txt (mode 0600)
- Protocol ports: UDP 500 (IKE) and UDP 4500 (IKE over NAT traversal)
- Recommended VM size: Standard_B2s
Prerequisites
Before you start, make sure you have:
- An active Microsoft Azure subscription
- Permission to create virtual machines, network security groups and public IP addresses
- An SSH key pair for the
azureuseradministrator account - A remote IPsec peer you control, reachable over the internet or over an Azure VNet
- The Azure CLI, if you prefer to deploy from the command line
Deploy from the Azure Marketplace
- Sign in to the Azure Portal and search the Marketplace for OpenIKED on Ubuntu 24.04 LTS by SecureAnyCloud.
- Select Create.
- Choose your subscription, resource group and region.
- Set the virtual machine name and select size Standard_B2s or larger.
- Set the administrator username to
azureuserand upload your SSH public key. - Under Inbound port rules, allow SSH (22) from your own address only.
- Review and create the VM.
Deploy from the Azure CLI
az group create --name openiked-rg --location eastus
az vm image terms accept --urn sac1647283583153:openiked-ubuntu-24-04:default:latest
az vm create \
--resource-group openiked-rg \
--name openiked-vm \
--image sac1647283583153:openiked-ubuntu-24-04:default:latest \
--size Standard_B2s \
--admin-username azureuser \
--generate-ssh-keys \
--public-ip-sku StandardRestrict the network security group. Allow SSH from your own address only, and allow the IKE ports from your VPN peer only. Never open UDP 500 or 4500 to the whole internet.
# SSH, from your address only az network nsg rule create --resource-group openiked-rg \
--nsg-name openiked-vmNSG --name allow-ssh \
--priority 1000 --access Allow --protocol Tcp \
--destination-port-ranges 22 --source-address-prefixes "<your-public-ip>/32"
# IKEv2 and NAT traversal, from your VPN peer only az network nsg rule create --resource-group openiked-rg \
--nsg-name openiked-vmNSG --name allow-ikev2 \
--priority 1010 --access Allow --protocol Udp \
--destination-port-ranges 500 4500 --source-address-prefixes "<peer-public-ip>/32"Connect over SSH
Connect as the azureuser administrator:
ssh azureuser@<vm-public-ip>To look up the public IP address, run:
az vm show --resource-group openiked-rg --name openiked-vm \
--show-details --query publicIps --output tsvConfirm the Daemon and the Secure Default
Check the daemon and the host key:
sudo openiked-ctl statusThe output shows that the daemon is active and enabled, that the per-VM key is present with mode 600 root:root, and that the policy count is zero. A policy count of zero is the secure default: the gateway accepts nothing until you declare a peer.
Confirm that the daemon is listening on the IKE ports:
sudo ss -ulnp | grep -E ':(500|4500)'Check that your gateway identity is unique to this VM
The host keypair was generated on the first boot of this VM. It is not in the SecureAnyCloud image, and no other deployment holds it. Inspect the fingerprint, the key files and their permissions:
sudo openiked-ctl fingerprint
sudo ls -l /etc/iked/private/local.key /etc/iked/local.pub
sudo stat -c '%a %U:%G' /etc/iked/privateThe private key has mode 0600 and is owned by root. It sits inside a directory with mode 0700. Give a peer the public key only, never the private key:
sudo openiked-ctl pubkeyProve a real IKEv2 negotiation
A running daemon and an open UDP port prove nothing about a VPN. Run the self test instead. It performs an actual IKEv2 exchange between two isolated endpoints on this VM, authenticates with this VM's own host key, and then checks the kernel's IPsec state.
sudo openiked-ctl selftestEvery line of the output is a distinct assertion:
- A keyed security association was installed in both directions, rather than an empty stub entry in the kernel.
- Both daemons reached the established state.
- The peer's public key was validated and its signature verified.
- The identities are the expected ones.
- The negotiated transform is AES 256 with HMAC SHA2 512 and ECP 256 forward secrecy.
- The kernel actually encrypted traffic.
Run the negative control
A test that can only pass proves little. The negative control repeats the exchange with the responder holding the wrong private key. It passes only if no tunnel is established.
sudo openiked-ctl selftest --negativesudo grep -E 'ikesa|childsa' /etc/iked.conf | grep '^#' | head -4 sudo sysctl -n net.ipv4.ip_forwardThe forwarding check reports 0. The appliance terminates tunnels but does not route between networks until you enable forwarding in Step 9.
Build a site-to-site tunnel
Public key authentication is the recommended method. Exchange public keys with your peer, import theirs, add a matching policy, and reload.
On this VM, print the public key and send it to your peer:
sudo openiked-ctl pubkeyCopy your peer's public key onto this VM, then import it and bind it to the peer's address:
sudo openiked-ctl import-peer <peer-public-ip> /home/azureuser/peer-local.pubAdd a policy to /etc/iked.conf. The commented Example 1 in that file is ready to copy. Replace the two network prefixes, this VM's private address and the peer's public address.
ikev2 "site-to-site" active esp \
from 10.10.0.0/16 to 10.20.0.0/16 \
local <this-vm-private-ip> peer <peer-public-ip> \
ikesa enc aes-256-gcm prf hmac-sha2-256 group ecp256 \
childsa enc aes-256 auth hmac-sha2-512 group ecp256Validate the file and reload the daemon. The reload refuses to restart the daemon if the file does not parse, so a typo cannot take your gateway down:
sudo openiked-ctl reloadWatch the tunnel come up:
sudo openiked-ctl saA note on the cipher choice. The child security association uses aes-256 with hmac-sha2-512, not AES GCM and not SHA2 256. This is deliberate.
OpenIKED 7.3 accepts childsa enc aes-256-gcm in the configuration file and reports the configuration as valid. It then silently drops the proposal, so the tunnel never establishes. It also accepts auth hmac-sha2-256, and the peers authenticate successfully. The Linux kernel interface then refuses to load the security association, and the tunnel fails at the last step.
The proposals shipped in /etc/iked.conf are the ones verified to work end to end on this image.
Complete the Azure configuration
An IPsec gateway needs three pieces of Azure configuration before it can carry traffic between networks.
1. Network security group. Allow inbound UDP 500 and UDP 4500 from your peer's address only, as shown in Step 2. Without this rule, the IKE exchange never reaches the VM.
2. IP forwarding, in two places. To route traffic between your peer's network and an Azure subnet, rather than only terminating a tunnel on this VM, enable forwarding in the guest:
sudo openiked-ctl forwarding onThen enable it on the Azure network interface itself. This is a separate setting that Azure enforces independently of the guest:
az network nic update --name <nic-name> --resource-group openiked-rg --ip-forwarding true3. A user-defined route. Azure does not learn your remote prefixes from IKEv2. Create a route table whose next hop for the remote network is this VM's private address. Then associate it with the subnets that should reach the far side:
az network route-table create --resource-group openiked-rg --name openiked-rt
az network route-table route create --resource-group openiked-rg \
--route-table-name openiked-rt --name to-remote-site \
--address-prefix 10.20.0.0/16 \
--next-hop-type VirtualAppliance --next-hop-ip-address <this-vm-private-ip>Manage the service
Manage the daemon with systemd and read its logs with journalctl:
sudo systemctl status openiked
sudo systemctl restart openiked
sudo journalctl -u openiked -n 50 --no-pagerThe openiked-ctl commands are:
- openiked-ctl status: daemon and per-VM key health, exits non-zero when unhealthy
- openiked-ctl fingerprint: SHA 256 fingerprint of this VM's public key
- openiked-ctl pubkey: print the public key to send to a peer
- openiked-ctl psk: print this VM's per-VM secret, for pre-shared key policies
- openiked-ctl sa: live IKE security associations and kernel IPsec state
- openiked-ctl import-peer <ip> <file>: trust a peer's public key
- openiked-ctl forwarding on\|off\|status: control guest IP forwarding
- openiked-ctl reload: validate, then reload the configuration
- openiked-ctl selftest [--negative]: prove a real IKEv2 negotiation
Hardening notes
- Never copy
/etc/iked/private/local.keyoff this VM. It is this gateway's identity. Share only the public key. - Prefer public key authentication over pre-shared keys. If you must use a pre-shared key, use the per-VM secret from
openiked-ctl psk, never a shared or memorable string. - Keep the NSG narrow. Open UDP 500 and 4500 to your peer's address only.
- Keep proposals modern. Do not add 3DES, DES, MD5, SHA1, or the modp768, modp1024 and modp1536 groups to a policy.
- Leave forwarding off unless you route. If this VM only terminates tunnels, keep forwarding disabled.
- Apply security updates. OpenIKED is installed from the Ubuntu archive as a normal apt package, so
unattended-upgradespatches it along with the rest of the system and it stays visible to vulnerability scanning.
Support
SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com with the offer name, your VM size and region, and the output of sudo openiked-ctl status and sudo openiked-ctl selftest.
Deploy on Azure
Launch OpenIKED on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com