# strongSwan: IPsec VPNs configured through swanctl and vici

> strongSwan is an open source IPsec VPN built around the charon daemon, with the modern swanctl command replacing the legacy ipsec/stroke interface. This covers its configuration model, a first site-to-site setup, and where it stops being the right tool.

**strongswan/strongswan** — strongSwan - IPsec-based VPN

- Repository: https://github.com/strongswan/strongswan
- Website: https://strongswan.org
- Stars: 2,993 · Forks: 938
- Language: C
- License: NOASSERTION
- Published: 2026-09-24 · Updated: 2026-09-24 · Language: en
- Canonical page: https://hysenlabs.com/projects/strongswan-strongswan

## What strongSwan solves, and who it is actually for

strongSwan is an IPsec-based VPN solution. The repository describes it that way in one line, and the rest of the README is configuration rather than architecture. The problem it addresses is connecting networks and hosts over IPsec with authentication you control, typically through certificates issued by your own CA rather than a vendor's. The README's quickstart uses a fictitious strongSwan CA whose strongswanCert.pem must be present on all VPN endpoints so peers can authenticate each other. That detail tells you who the project is for: operators who can distribute a CA certificate to every endpoint. It is not aimed at someone who wants to click a button and get a tunnel. It is aimed at the person who already knows what a security association is and wants the configuration to say exactly which identities, which subnets and which traffic selectors are involved. The README presents three scenarios: site-to-site between two gateways, host-to-host between two single hosts, and roadwarrior where a gateway serves an arbitrary number of remote clients with dynamic IP addresses. Those three shapes cover most enterprise IPsec deployments, and the documentation is organised around them rather than around features.

## charon, vici and swanctl: how configuration reaches the daemon

The mechanism is split into a daemon and a control interface. Certificates and private keys are loaded into the charon daemon with swanctl --load-creds, and connections defined in swanctl.conf are loaded with swanctl --load-conns. swanctl talks to charon over vici, the Versatile IKE Configuration Interface, which the README links to at src/libcharon/plugins/vici/README.md. The older ipsec command uses the stroke interface and is described as deprecated; its documentation lives in README_LEGACY.md. That split matters when you read third-party guides, because a lot of material online still describes the ipsec.conf and ipsec.secrets files that belong to the legacy path. The swanctl.conf format is hierarchical: a connections block contains named connections, each with local and remote authentication settings and one or more children blocks. A child carries the traffic selectors, local_ts and remote_ts, plus a start_action. In the site-to-site example the child sets start_action = trap, which means the tunnel is set up automatically with the first plaintext payload packet that wants to go through it. In the roadwarrior example the client side uses start_action = start. The identities are subjectDistinguishedNames from the end entity certificates, which is why the remote id in the README reads as a full DN string rather than a hostname.

## Installing strongSwan and loading a first site-to-site tunnel

The README does not contain installation instructions; it points to the documentation site at docs.strongswan.org, the legacy wiki, and the man pages, and the repository carries an INSTALL file and an autogen.sh script for building from source. Distribution packages exist for the platforms named in the project's own search traffic, but the README does not give package names or versions, so treat the commands below as the post-install configuration steps the README does document. The layout places credentials under /etc/swanctl: the CA certificate in x509ca, end entity certificates in x509, and private keys in private. The paths for gateway moon are shown below. Once those files are in place, the two swanctl commands from the README load them.

```bash
/etc/swanctl/x509ca/strongswanCert.pem
/etc/swanctl/x509/moonCert.pem
/etc/swanctl/private/moonKey.pem
```

A connection is declared in swanctl.conf. The site-to-site example names the connection net-net, points remote_addrs at the peer gateway, and uses pubkey authentication on both sides with the local certificate named explicitly. The child defines the two subnets and the trap action.

```yaml
connections {
    net-net {
        remote_addrs = 192.168.0.2

        local {
            auth = pubkey
            certs = moonCert.pem
        }
        remote {
            auth = pubkey
            id = "C=CH, O=strongSwan, CN=sun.strongswan.org"
        }
        children {
            net-net {
                local_ts  = 10.1.0.0/16
                remote_ts = 10.2.0.0/16
                start_action = trap
            }
        }
    }
}
```

Load the credentials first, then the connections. The order matters in practice because a connection referencing a certificate that charon has not loaded cannot authenticate.

```bash
swanctl --load-creds
swanctl --load-conns
```

On the peer gateway sun the same structure is mirrored: remote_addrs becomes 192.168.0.1, the certificate becomes sunCert.pem, the remote id becomes the DN of moon, and the two traffic selectors swap so that local_ts is 10.2.0.0/16 and remote_ts is 10.1.0.0/16. After both sides load, the first packet from either subnet toward the other should trigger the tunnel because of start_action = trap.

## The roadwarrior case exposes where configuration gets thin

The roadwarrior example is the most interesting one because it shows how little the gateway needs to say. On the gateway, the connection named rw sets a local identity of moon.strongswan.org with the gateway certificate, leaves the remote authentication as pubkey without naming an identity, and defines a child with only local_ts = 10.1.0.0/16. There is no remote_ts, because the client's address is unknown. On the client, the connection is named home, remote_addrs is the gateway hostname, and the local block carries both the certificate and an explicit id of carol@strongswan.org. The child sets local_ts = 10.1.0.0/16 and start_action = start. That asymmetry is deliberate and it is the part most likely to confuse a first-time reader: the gateway accepts any identity signed by the CA, while the client pins the gateway by hostname. The README notes that for remote_addrs the hostname moon.strongswan.org was chosen and will be resolved by DNS. What the README does not cover here is revocation, address pool assignment, or what happens when a client's identity needs to be restricted. Those are real operational questions for a roadwarrior deployment, and the quickstart leaves them to the man pages and the documentation site. That is a fair division for a quickstart, but it means the roadwarrior section alone is not enough to run a production gateway.

## Where strongSwan is the wrong choice

The clearest limitation is platform coverage. The README documents no Windows client, and the search traffic around this project includes people asking how to install strongSwan on Windows and for a strongSwan VPN client for Windows. The repository does contain Android build files, Android.common.mk.in and Android.mk, so an Android path is visible in the layout. Windows is not. If your user population is on Windows desktops and you need the same client everywhere, strongSwan's own documented surface does not give you that, and you would be looking at a different client speaking IPsec to a strongSwan gateway rather than strongSwan on the endpoint. The second limitation is configuration cost. Everything in the README is file-based and identity-based: certificates on disk, DNs as identifiers, traffic selectors written by hand. There is no described mechanism for pushing configuration to clients. A deployment of a handful of gateways is manageable; a large and changing client population means you are managing certificate distribution yourself. The pki tool is named as the way to generate private keys and certificates, and the README says its use will be explained in a later section, so the project does expect you to run your own CA rather than depend on an external one.

## How it compares with libreswan

libreswan is the alternative that appears in the search data for this project, and the difference is mostly about which control interface you live in. Both are IPsec implementations in C. strongSwan's modern path is swanctl over vici, with a hierarchical configuration file and a daemon, charon, that loads credentials and connections through separate commands. The legacy ipsec command and stroke interface still exist but are marked deprecated in the README, which means the project has committed to the vici model going forward. If you are evaluating the two, the question to ask is not which one implements IPsec, because both do, but which configuration model your team can maintain and which one your existing runbooks, automation and monitoring already assume. Migration between them is not a configuration file rename; the connection semantics and the identity handling differ enough that the README's own examples would need rewriting. The README does not describe libreswan's configuration format, so the comparison stops at the interface boundary. What can be said from this repository is that strongSwan's documented direction is swanctl and vici, and any new deployment should start there rather than with the deprecated ipsec command.

## Maintenance, releases and licence

The last push to the master branch was on 2026-09-23, and the repository is not archived. Release 6.1.0 was published on 2026-09-07, with 6.0.7 on 2026-06-08 and 6.0.6 on 2026-04-22 before it. The cadence visible in those three releases is roughly one minor release and two patch releases across six months, which is a reasonable basis for planning upgrades but says nothing about how disruptive a given upgrade will be. The repository carries a ChangeLog and a NEWS file at the top level, and those are where the project records what changed; the README itself does not describe an upgrade procedure or a compatibility policy between releases, so anyone running strongSwan in production should read ChangeLog before moving between versions rather than assuming configuration files carry over unchanged. On licensing, the repository has both a LICENSE and a COPYING file at the top level, and the GitHub metadata reports the licence as NOASSERTION, meaning no standard licence identifier was detected. That is a signal to read the two files directly rather than assume a well-known licence applies. Whether the terms fit your distribution or embedding plans is a question for your own legal review, and the file contents are the only authority on it.

## Conclusion

Adopt strongSwan when the endpoints are under your control and you need certificate-based IPsec between gateways or from a roadwarrior to a gateway; the swanctl.conf model is explicit and the pki tool lets you issue your own CA. Do not adopt it if you need a Windows client, because the README documents no such client and the repository ships Android build files instead. Before committing, verify the licence terms in LICENSE and COPYING, confirm that your distribution packages swanctl and the vici plugin rather than only the legacy ipsec command, and decide whether start_action = trap or start_action = start matches how your traffic arrives.

## FAQ

### What is strongSwan?

strongSwan is an open source IPsec-based VPN solution. Its modern configuration path uses the swanctl command talking to the charon daemon over the vici interface, with connections and credentials defined under /etc/swanctl.

### Who owns strongSwan?

The README does not identify an owner or a governing organisation. The repository lists an AUTHORS file and a CONTRIBUTING.md at the top level, which is where contributor information would be recorded.

### Can strongSwan be used on Windows?

The README documents no Windows client, and the repository's visible platform build files are Android.common.mk.in and Android.mk. Windows is not covered in the README.

### how to use strongswan

Place the CA certificate under /etc/swanctl/x509ca, the end entity certificate under /etc/swanctl/x509 and the private key under /etc/swanctl/private, define a connection in swanctl.conf, then run swanctl --load-creds followed by swanctl --load-conns.

### How do I install strongSwan plugins?

The README does not describe plugin installation. It links to the documentation site at docs.strongswan.org, the legacy wiki and the man pages for more detailed information, and the repository carries an INSTALL file.

## Sources

- [Issues](https://github.com/strongswan/strongswan/issues)
- [Project website](https://strongswan.org)
- [README](https://github.com/strongswan/strongswan/blob/master/README.md)
- [Releases](https://github.com/strongswan/strongswan/releases)
- [strongswan/strongswan on GitHub](https://github.com/strongswan/strongswan)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/strongswan-strongswan
