Skip to content

strongswan: update init script and migrate to /etc/config/swanctl - #30504

Open
feckert wants to merge 25 commits into
openwrt:masterfrom
TDT-AG:pr/20260911-strongswan
Open

feckert wants to merge 25 commits into
openwrt:masterfrom
TDT-AG:pr/20260911-strongswan

Conversation

@feckert

@feckert feckert commented Sep 11, 2026

Copy link
Copy Markdown
Member

📦 Package Details

Maintainer: @pprindeville ?

Summary:

  • Switch from /etc/config/ipsec to /etc/config/swanctl. The old implementation was based on stroke and was simply mapped to swanctl. The change is necessary to support more complex setups via UCI. This section now focuses on the swanctl interface.

  • Align uci option names with swanctl.conf keys: All uci option names are renamed to match their swanctl.conf counterparts, and the init script is updated to read them directly. A uci-defaults upgrade script handles the migration automatically on package upgrade.

Section Old UCI option New UCI option swanctl.conf key
child rekeytime rekey_time <child>.rekey_time
child lifetime life_time <child>.life_time
child rekeybytes rekey_bytes <child>.rekey_bytes
child lifebytes life_bytes <child>.life_bytes
child rekeypackets rekey_packets <child>.rekey_packets
child lifepackets life_packets <child>.life_packets
child startaction start_action <child>.start_action
child closeaction close_action <child>.close_action
child dpdaction dpd_action <child>.dpd_action
remote rekeytime rekey_time <conn>.rekey_time
remote overtime over_time <conn>.over_time
remote dpddelay dpd_delay <conn>.dpd_delay
  • Unified child sections: tunnel/transport section types merged into a single child type distinguished by a new mode option; remote list tunnel and list transport references merged into list child. Future modes (e.g. beet) only require extending allowed mode values.

  • custom_proposal option: new use_custom_proposal flag and custom_proposal value to define raw IKE/IPsec proposals instead of the individual encryption/hash/dh_group/prf options.

  • Separate syslog plugin section: globals debug option moved to a dedicated ipsec plugin syslog section, enabling per-subsystem log levels and split into daemon/auth logging facilities (default -1, silent).

  • plugins-packaged-separately: enable the strongSwan 6.0.5 configure option so missing optional plugins only emit a note instead of error-level output when building/running pki or swanctl.


🧪 Run Testing Details

  • OpenWrt Version: master
  • OpenWrt Target/Subtarget: x86_64
  • OpenWrt Device: APUe

✅ Formalities

  • I have reviewed the CONTRIBUTING.md file for detailed contributing guidelines.

@feckert feckert changed the title strongswan: strongswan: update init script Sep 11, 2026
openwrt-ai

This comment was marked as resolved.

@feckert
feckert force-pushed the pr/20260911-strongswan branch 2 times, most recently from c7fcb1e to 22ff0d9 Compare September 14, 2026 07:21
@feckert
feckert requested a review from openwrt-ai September 14, 2026 08:12
@feckert
feckert force-pushed the pr/20260911-strongswan branch from 22ff0d9 to d1117e2 Compare September 14, 2026 10:10
openwrt-ai

This comment was marked as resolved.

@feckert
feckert force-pushed the pr/20260911-strongswan branch from d1117e2 to 02457ae Compare September 15, 2026 07:35
@feckert
feckert requested a review from openwrt-ai September 15, 2026 12:43
openwrt-ai

This comment was marked as resolved.

@feckert
feckert force-pushed the pr/20260911-strongswan branch from 02457ae to e8701f0 Compare September 16, 2026 06:55
@feckert
feckert requested a review from openwrt-ai September 16, 2026 07:02
openwrt-ai

This comment was marked as resolved.

@feckert
feckert force-pushed the pr/20260911-strongswan branch 3 times, most recently from 43aee8a to f338bc7 Compare September 18, 2026 13:16
@feckert feckert changed the title strongswan: update init script strongswan: update init script and migrate to /etc/config/swanctl Sep 18, 2026
openwrt-ai

This comment was marked as resolved.

OpenWrt ships the plugins in multiple packages that are not all
installed by default. When running tools like 'pki' or 'swanctl',
this currently produces error-level log output for plugins that
are simply not installed, which can alarm users unnecessarily.

Enable the new configure option 'plugins-packaged-separately'
(default: no), added in strongSwan 6.0.5, which sets it to 'yes'.
This lowers the log level of the corresponding messages and adds
a note that the missing plugins may be available in other
packages.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
…d modes

Migrate the uci section types 'tunnel' and 'transport' in
'/etc/config/ipsec' into a single 'child' section type, distinguished
by a new 'mode' option ('tunnel' or 'transport') for now. Existing 'mode'
values are preserved.

The 'remote' sections keep their type, but their 'list tunnel' and
'list transport' references (which point to the renamed child
sections by name) are merged into a single 'list child'.

Rationale:
* 'tunnel' and 'transport' sections already share the same set of
  options (local_subnet, remote_subnet, crypto_proposal, etc.) and
  only ever differed by IPsec mode. Modeling that as data (a 'mode'
  option) instead of as two separate section types removes
  duplicated schema/parsing logic and mirrors how 'swanctl.conf' itself
  expresses mode on a single 'children' entry.
* Adding further modes (e.g. 'beet') in the future only requires
  extending the allowed values of 'mode', not introducing another
  section type and duplicating its option set.

The existing configuration is also migrated to the new uci layout using a
uci-defaults script.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Previously, the debug option for strongswan logging was configured directly
in the globals section of the ipsec. So every subsystem does have the same
log level. To improve modularity and maintainability, this change relocates
the debug configuration to a dedicated named 'ipsec plugin' section 'syslog'.

Rationale:
* Clearer separation of concerns (logging vs. core srongswan settings)
* Better alignment with strongswan plugin-based architecture

Key improvements:
* Enables separate log level configuration for individual strongswan
  subsystems  (dmn, mgr, job ... ), allowing finer control over debug
  verbosity.
* Split logging facilities into 'daemon' and 'auth' for more granular
  log filtering and debugging. The subsystems ike, chd, enc and esp
  moved to the 'auth' faciltiy all other subsystems are moved to the daemon
  facility.
* The default logging level for the 'auth' and 'daemon' facility is set to
  '-1', which means ‘absolutely silent’.

The existing configuration is also migrated to the new uci layout using a
uci-defaults script.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
This introduces the 'use_custom_proposal' flag, allowing users to manually
define their own IKE/IPsec proposals in 'custom_proposal' instead of relying
on uci config options 'encryption_alorithm', 'hash_alorithm',
'dh_group' and for ike also on 'prf_algorithem'.

This is particularly useful for:
* Advanced users who need specific algorithm combinations
* Compatibility with non-standard or legacy peers
* Fine-tuning security parameters for specialized use cases

Note: Enabling this option requires careful configuration, as incorrect
proposals may break compatibility or cause connection failures. Upgrades
with custom proposals are not officially supported. Since we don't know
what the user has configured.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
@feckert
feckert force-pushed the pr/20260911-strongswan branch from 0a7716f to cff561d Compare September 21, 2026 09:03
openwrt-ai

This comment was marked as resolved.

The swanctl only supports clear(default), trap and restart, with no
equivalent for the legacy 'none' and 'start' value.

The upgrade script is reenameing the uci option 'dpdaction' to 'dpd_action'
to match the 'swanctl.conf' '<child>.dpd_action' key.

The value 'hold' is remapped to 'trap'. This was previously done in
the swanctl init script.

Not setting 'dpd_action' means 'clear'. Therefore, setting 'dpd_action=clear'
(default) and setting 'dpddelay=0' is equivalent to the old 'dpdaction=none'.
This is not automatically upgraded.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'closeaction' to 'close_action' via upgrade script to
match the 'swanctl.conf' '<child>.close_action' key.

Unlike 'dpd_action', 'close_action' has a direct 'none' equivalent, so
all legacy values are migrated:
* clear   -> none
* hold    -> trap
* restart -> start
* none    -> none

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'startaction' to 'start_action' via upgrade script to
match the 'swanctl.conf' '<child>.start_action' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'rekeytime' to 'rekey_time' in child via upgrade script to
match the 'swanctl.conf' '<child>.rekey_time' key.

The migration function 'migrate_option' in 'uci-defaults' is designed to
be generic, since 'rekeytime' is not the only option that does not conform
to the swanctl naming scheme and should also be migrated.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'lifetime' to 'life_time' in child via upgrade script to
match the 'swanctl.conf' '<child>.life_time' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'rekeybytes' to 'rekey_bytes' in child via upgrade script to
match the 'swanctl.conf' '<child>.rekey_bytes' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'lifebytes' to 'life_bytes' in child via upgrade script to
match the 'swanctl.conf' '<child>.life_bytes' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'rekeypackets' to 'rekey_packets' in child via upgrade script to
match the 'swanctl.conf' '<child>.rekey_packets' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'lifepackets' to 'life_packets' in child via upgrade script to
match the 'swanctl.conf' '<child>.life_packets' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'rekeytime' to 'rekey_time' in remote via upgrade script to
match the 'swanctl.conf' '<conn>.rekey_time' key.

The new migration function 'migrate_option_remote_values' in 'uci-defaults'
is designed to be generic, since 'rekeytime' is not the only option that
does not conform to the swanctl naming scheme for conn and should also be
migrated.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'overtime' to 'over_time' in child via upgrade script to
match the 'swanctl.conf' '<con>.over_time' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Rename uci option 'dpddelay' to 'dpd_delay' in remote via upgrade script to
match the 'swanctl.conf' '<conn>.dpd_delay' key.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
The section type in the config and in 'swanctl.init' was overlooked, when
migrating the IPsec type to globals.

Fixes: e5c5a23 ("strongswan: do not use config_foreach named section globals")

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Add a new uci 'shunt' section type for pass/drop policies, independent
of 'remote' connections since shunts have no peer, auth, or
proposals. Renders each into its own 'connections{}' entry in
swanctl.conf.

Supports mode (pass/drop), local_ts/remote_ts (list), priority,
interface.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
…outes_xfrmi

Strongswan can optionally install routes via XFRM interfaces if the
'charon.plugins.kernel-netlink.install_routes_xfrmi' option is enabled.

This change makes this configurable via uci.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Previously a service reload only reloaded the IPsec connection
definitions from '/var/swanctl/swanctl.conf', leaving changes to
'/var/ipsec/strongswan.conf' to require a full restart.

Extend the reload action to also pick up changes to strongswan.conf
for a running service by executing 'swanctl --reload-settings' on
reload as well.

Note that 'swanctl --reload-settings' reloads '/var/ipsec/strongswan.conf'
at runtime, but not all settings (esp. plugin load directives, kernel/socket
options) are picked up by charon. A full daemon restart is still required
for such changes to apply. A note about this was added as well at this
point.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
The migration of the legacy '/etc/config/ipsec' UCI configuration to
the new '/etc/config/swanctl' format cannot be performed fully
automatically: it rewrites the user's configuration and must be
triggered and acknowledged by the user.

Remove the automatic migration hook that was installed as an
uci-defaults script (executed once on first boot or installation) and
instead ship the migration utility as a regular binary at
'/usr/libexec/strongswan/migrate-ipsec-to-swanctl'. From now on the
migration is only run on demand.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
strongSwan's native configuration format is 'swanctl.conf', which the
swanctl init script already generates from UCI. The old 'ipsec' UCI
configuration is being phased out, so switch the shipped UCI default
to the new config file.

Rename the default UCI config file from '/etc/config/ipsec' to
'/etc/config/swanctl' and adapt the swanctl init script accordingly:
- load the 'swanctl' config instead of 'ipsec'
- use 'swanctl' as the procd reload trigger
- rename the service trigger callback 'service_trigger_ipsec' to
  'service_trigger_swanctl'

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Now that the ipsec-to-swanctl migration is no longer executed
automatically on boot, expose it through the init script so it can be
invoked on demand via '/etc/init.d/swanctl migrate'.

Also harden the migration script:
- abort with an error if '/etc/config/ipsec' does not exist, i.e. the
  migration has already been carried out
- make a copy of '/etc/config/swanctl' to '/etc/config/swanctl.bak' if
  the file already exists
- create a backup of the original configuration file '/etc/config/ipsec'
  to '/etc/config/ipsec.bak' before starting
- move the migrated file '/etc/config/ipsec' to its final location
  '/etc/config/swanctl'.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Until the user runs the migration, the legacy '/etc/config/ipsec'
configuration must keep working. Restore support for the old UCI
format in the swanctl init script by adding a parallel legacy
rendering path:

- add 'legacy_config_*' helpers that translate the legacy ipsec
  sections ('ipsec'/'globals', 'remote', 'tunnel', 'transport',
  'pools', 'mschapv2_secrets') into swanctl.conf syntax, including the
  existing start/close/dpd action and lifetime translations
- as long as '/etc/config/ipsec' exists, prepare_env() and
  service_triggers() use the legacy generation path and keep reloading
  on 'ipsec' changes; once the migration has moved the file away, the
  new swanctl path is used

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
Update 'PKG_RELEASE' to '8'.

Signed-off-by: Florian Eckert <fe@dev.tdt.de>
@feckert
feckert force-pushed the pr/20260911-strongswan branch from cff561d to 5a6ec39 Compare September 22, 2026 07:41
Comment thread net/strongswan/files/swanctl.init
Comment thread net/strongswan/files/swanctl.init
Comment thread net/strongswan/Makefile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants