---
title: strongSwan
description: Connect strongSwan to Cloudflare WAN.
image: https://edgetunnel-b2h.pages.dev/zt-preview.png
---

> Documentation Index  
> Fetch the complete documentation index at: https://edgetunnel-b2h.pages.dev/cloudflare-wan/llms.txt  
> Use this file to discover all available pages before exploring further. 

[Skip to content](#%5Ftop) 

# strongSwan

This tutorial explains how to set up strongSwan along with Cloudflare WAN (formerly Magic WAN). You will learn how to configure strongSwan, configure an IPsec tunnel, and create Policy-Based Routing (PBR).

## 1\. Configure health checks

Configure the [bidirectional health checks](https://edgetunnel-b2h.pages.dev/cloudflare-wan/configuration/how-to/configure-tunnel-endpoints/#add-tunnels) target for Cloudflare WAN. For this tutorial, use `172.64.240.252` as the target IP address, and `type` as the request.

This can be set up [with the API](https://edgetunnel-b2h.pages.dev/api/resources/magic%5Ftransit/subresources/ipsec%5Ftunnels/methods/update/). For example:

```bash
curl --request PUT \
https://api.cloudflare.com/client/v4/accounts/{account_id}/magic/ipsec_tunnels/{tunnel_id} \
--header "X-Auth-Email: <EMAIL>" \
--header "X-Auth-Key: <API_KEY>" \
--header "Content-Type: application/json" \
--data '{
  "health_check": {
    "enabled": true,
    "target": "172.64.240.252",
    "type": "request",
    "rate": "mid"
  }
}'
```

## 2\. Configure strongSwan

1. [Install strongSwan ↗](https://docs.strongswan.org/docs/5.9/install/install.html). For example, open the console and run:

```sh
sudo apt-get install strongswan -y
```

1. Open `/etc/strongswan.conf` and add the following settings:

```txt
charon {
    load_modular = yes
    install_routes = no
    install_virtual_ip = no


    plugins {
        include strongswan.d/charon/*.conf
    }
}


include strongswan.d/*.conf
```

## 3\. Configure the IPsec file

1. Open `/etc/ipsec.conf` and add the following settings:

```txt
# ipsec.conf - strongSwan IPsec configuration file
config setup
    charondebug="all"
    uniqueids = yes


conn %default
    ikelifetime=24h
    rekey=yes
    reauth=no
    keyexchange=ikev2
    authby=secret
    dpdaction=restart
    closeaction=restart


# Sample VPN connections
conn cloudflare-ipsec
    auto=start
    type=tunnel
    fragmentation=no
    leftauth=psk
    # Private IP of the VM
    left=%any
    # Tunnel ID from dashboard, in this example FQDN is used
    leftid=<YOUR_TUNNEL_ID>.<YOUR_ACCOUNT_ID>.ipsec.cloudflare.com
    leftsubnet=0.0.0.0/0
    # Cloudflare Anycast IP
    right=<YOUR_CLOUDFLARE_ANYCAST_IP>
    rightid=<YOUR_CLOUDFLARE_ANYCAST_IP>
    rightsubnet=0.0.0.0/0
    rightauth=psk
    ike=aes256-sha256-ecp384!
    esp=aes256-sha256-ecp384!
    replay_window=0
    mark_in=42
    mark_out=42
    leftupdown=/etc/strongswan.d/ipsec-vti.sh
```

1. Create a virtual tunnel interface (VTI) with the IP configured as the target for Cloudflare's health checks (`172.64.240.252`) to route IPsec packets. Open `/etc/strongswan.d/`.
2. Create a script called `ipsec-vti.sh` and add the following:

```txt
#!/bin/bash


set -o nounset
set -o errexit


VTI_IF="vti0"


case "${PLUTO_VERB}" in
    up-client)
        ip tunnel add "${VTI_IF}" local "${PLUTO_ME}" remote "${PLUTO_PEER}" mode vti \
        key "${PLUTO_MARK_OUT%%/*}"
        ip link set "${VTI_IF}" up
        ip addr add 172.64.240.252/32 dev vti0
        sysctl -w "net.ipv4.conf.${VTI_IF}.disable_policy=1"
        sysctl -w "net.ipv4.conf.${VTI_IF}.rp_filter=0"
        sysctl -w "net.ipv4.conf.all.rp_filter=0"
        ip rule add from 172.64.240.252 lookup viatunicmp
        ip route add default dev vti0 table viatunicmp
        ;;
    down-client)
        ip tunnel del "${VTI_IF}"
        ip rule del from 172.64.240.252 lookup viatunicmp
        ip route del default dev vti0 table viatunicmp
        ;;
esac
echo "executed"
```

## 4\. Add policy-based routing

Create Policy-Based Routing (PBR) to redirect returning traffic through the IPsec tunnel. Without it, the ICMP replies to the health probes sent by Cloudflare will be returned through the Internet, instead of the same IPsec tunnel.

This tutorial uses [iproute2 ↗](https://en.wikipedia.org/wiki/Iproute2) to route IP packets from `172.64.240.252` to the tunnel interface.

1. Open `/etc/iproute2/`.
2. Edit the `rt_tables` file to add a routing table number and name. In this example, use `viatunicmp` as the name and `200` as the number for the routing table.

```txt
#
# reserved values
#
255 local
254 main
253 default
0   unspec
200 viatunicmp
#
# local
#
#1  inr.ruhep
```

1. Add a rule to match the routing table. This rule instructs the system to use routing table `viatunicmp` if the packet's source address is `172.64.240.252`:

```sh
ip rule add from 172.64.240.252 lookup viatunicmp
```

1. Add a route to the `viatunicmp` routing table. This is the default route through the interface `vti0` in the `viatunicmp` table.

```sh
ip route add default dev vti0 table viatunicmp
```

1. Start IPsec. You can also `stop`, `restart`, and show the `status` for the IPsec connection:

```bash
ipsec start
```

```bash
Security Associations (1 up, 0 connecting):
cloudflare-ipsec[1]: ESTABLISHED 96 minutes ago, <IPSEC_TUNNEL_IDENTIFIER>.ipsec.cloudflare.com]...162.159.67.88[162.159.67.88]
cloudflare-ipsec{4}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c4e20a95_i c5373d00_o
cloudflare-ipsec{4}:   0.0.0.0/0 === 0.0.0.0/0
```

## 5\. Check connection status

Use tcpdump to investigate the status of health checks originated from Cloudflare.

```sh
sudo tcpdump -i <OUTGOING_INTERFACE> esp and host <TUNNEL_CLOUDFLARE_ENDPOINT_IP>
```

In this example, the outgoing Internet interface shows that the IPsec encrypted packets (ESP) from Cloudflare's health check probes (both the request and response) are going through the IPsec tunnel.

![tcpdump shows the IPsec encrypted packets from Cloudflare's health probes](https://edgetunnel-b2h.pages.dev/_astro/ipsec.CuiOceRh_Z15hfTY.webp) 

Run tcpdump on `vti0` to check the decrypted packets.

```sh
sudo tcpdump -i vti0 host 172.64.240.252
```

![If you run tcpdump on vti0 you can check for decrypted packets](https://edgetunnel-b2h.pages.dev/_astro/tcpdump.CaDJay4I_ID4bt.webp)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://edgetunnel-b2h.pages.dev/cloudflare-wan/configuration/third-party/strongswan/#page","headline":"strongSwan · Cloudflare WAN docs","description":"Connect strongSwan to Cloudflare WAN.","url":"https://edgetunnel-b2h.pages.dev/cloudflare-wan/configuration/third-party/strongswan/","inLanguage":"en","image":"https://edgetunnel-b2h.pages.dev/zt-preview.png","dateModified":"2026-04-21","publisher":{"@type":"Organization","name":"Cloudflare","url":"https://www.cloudflare.com/"},"isPartOf":{"@type":"WebSite","@id":"https://edgetunnel-b2h.pages.dev/#website","name":"Cloudflare Docs","url":"https://edgetunnel-b2h.pages.dev/"}}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"/directory/","name":"Directory"}},{"@type":"ListItem","position":2,"item":{"@id":"/cloudflare-wan/","name":"Cloudflare WAN"}},{"@type":"ListItem","position":3,"item":{"@id":"/cloudflare-wan/configuration/","name":"Configuration"}},{"@type":"ListItem","position":4,"item":{"@id":"/cloudflare-wan/configuration/third-party/","name":"Third-party integration"}},{"@type":"ListItem","position":5,"item":{"@id":"/cloudflare-wan/configuration/third-party/strongswan/","name":"strongSwan"}}]}
```
