luci-app-ipsec-vpnd
LuCI 界面,给运行在 OpenWrt / ImmortalWrt 上的 strongSwan IPsec VPN 服务做配置管理。
IKEv1 + PSK + Xauth(账号密码),目标用户是家用 / 小公司路由器场景——LAN 后面的客户端用用户名密码拨号,拿到一个独立虚拟网段的 IP。
维护者说明:本项目维护者本人既在自家路由器上跑,也把编译好的 .apk/.ipk 同步发到 community / 朋友分发渠道。下面“构建”与“安装”分别对应这两种使用方式。
功能
- VPN 服务启停(uhttpd → LuCI → procd 守护进程控制 strongSwan 的
starter) - 账号 / 密码 / PSK 配置 写在
/etc/config/ipsec-vpnd,运行时被 init 脚本翻译成 strongSwan 的ipsec.conf+ipsec.secrets - 首次安装自动初始化:建
network.VPN设备(绑ipsec0)+firewall.ike/ipsec/ah/esp入站规则 +firewall.VPNzone + 端口转发;只跑一次,/etc/config/ipsec-vpnd里的initialized标记防止升级时覆盖用户后续自定义 - 和系统自带的
ipsec服务冲突处理:每次启动前都stop && disable系统那个,防止 charon 抢 UDP/500、4500 - 菜单位置:
VPN → IPSec VPN Server(order 30)
界面与配置项
UCI 路径 ipsec-vpnd.@ipsec[0],字段:
| 字段 | 默认 | 说明 |
|---|---|---|
enabled |
0 |
总开关 |
clientip |
10.9.8.10/24 |
客户端地址池(CIDR),用 strongSwan 的 rightsourceip 推给拨号端 |
clientdns |
10.9.8.1 |
推给客户端的 DNS(即 VPN 网关 IP) |
account |
vpnuser |
Xauth 用户名 |
password |
changeme |
Xauth 密码 |
secret |
changeme |
IKE PSK 预共享密钥 |
VPN 客户端拨号后会拿到 clientip 池里一个地址,clientdns 指向 VPN 网关(路由器上的 ipsec0 IP,初始化脚本里按 LAN 前两段、第三段 +1 自动算出来)。
依赖
Makefile 里 LUCI_DEPENDS 列的运行时依赖:
+strongswan-minimal
+strongswan-mod-xauth-generic
+strongswan-mod-kernel-libipsec
+strongswan-mod-des
+kmod-tun
**这是 IPsec VPN 服务能起来的前提。**安装本包前请确认这些包在固件里都有,否则 LuCI 界面能开,但服务起不来。
关于 ImmortalWrt 25.12 系列(重要)
ImmortalWrt 25.12.0 / 25.12.1 的官方软件源在全架构上都没带 strongswan(OpenWrt 上游 25.12 源有,ImmortalWrt 24.10 源也有,唯独 ImmortalWrt 25.12 系列缺)。如果你的固件就是 ImmortalWrt 25.12 系列且只挂着官方源,opkg install luci-app-ipsec-vpnd 会卡在依赖解析。
可行方案(任选):
- 换 OpenWrt 上游源:
/etc/opkg/distfeeds.conf里加src/gz openwrt_core https://downloads.openwrt.org/releases/25.12.1/targets/.../packages/ - 换同版本但带 strongswan 的 ImmortalWrt fork 源
- 用 szwjp/luci 这种社区源,里头把 strongswan 也带上了
安装
普通用户(装现成的 .apk)
从本仓库的 Actions → Build → 最新一次成功 run → Artifacts → ipsec-vpnd-packages 下载 luci-app-ipsec-vpnd_*.apk 和 luci-i18n-ipsec-vpnd-zh-cn_*.apk(中文界面,可选),用 scp / WinSCP 推到路由器:
opkg install luci-app-ipsec-vpnd_*.apk
opkg install luci-i18n-ipsec-vpnd-zh-cn_*.apk # 可选
第一次安装会跑 uci-defaults/luci-ipsec-vpnd 一次性初始化(建 network/firewall/zone + 删系统 ipsec 服务),然后 LuCI 刷新一下就能在 VPN → IPSec VPN Server 看到。
或者从 release 装(GitHub Actions 自动把每次 main 提交 publish 到 IPSec VPND Latest Build release):
opkg install https://github.com/szwjp/luci-app-ipsec-vpnd/releases/download/luci-app-ipsec-vpnd/luci-app-ipsec-vpnd_27.906.25.12-r1_all.apk
自己构建(社区分发 / 自己做 firmware)
走仓库的 GitHub Actions Build workflow:push 到 main 触发(或手动 dispatch),会在 GitHub Actions 里产 luci-app-ipsec-vpnd-*.apk + luci-i18n-ipsec-vpnd-zh-cn-*.apk 两个 apk 和对应的 ipk,并通过 softprops/action-gh-release publish 到 latest release。本地要复现的话:
# Ubuntu 20.04+,装上 apk-tools / meson / ninja / fakeroot
sudo apt-get install -y build-essential meson ninja-build fakeroot
# 用仓库自带的 .github/build-pkg.sh
fakeroot bash .github/build-pkg.sh apk 1 # 出 luci-app-ipsec-vpnd_*.apk + luci-i18n-ipsec-vpnd-zh-cn-*.apk
fakeroot bash .github/build-pkg.sh ipk 1 # 出同名 .ipk
ls -l *.apk *.ipk
build-pkg.sh 用了仓库里那个专为本包定制的最小工具链(apk-tools 自编译 + po2lmo 自编译 + ipkg-build),不依赖完整 OpenWrt SDK 编译环境;这就是为什么 build.yml 跑得很快(~40s)。所有 actions 都用 Node 24 版(actions/checkout@v5 / actions/upload-artifact@v6 / softprops/action-gh-release@v3)。
CI
.github/workflows/ 下两个 workflow:
build.yml(生产 workflow):push 到 main / PR / 手动 dispatch 触发。9 步全绿、零 annotation,~40s 出包并 publish 到 release。是这个项目的命脉。cleanup-old-workflow.yml(工具 workflow):手动 dispatch,按你给的天数阈值删actions/runs里的 completed run,防止 Actions 列表太长。文件名带.yml后缀(之前没有后缀,GitHub Actions 静默忽略——这种坑踩过一次记到 memory 里了)。
目录结构
.
├── Makefile # OpenWrt 包定义:LUCI_TITLE / LUCI_DEPENDS / PKG_*
├── htdocs/luci-static/resources/view/ipsec-vpnd.js
│ # LuCI web UI(cbid 表格 + 启停按钮)
├── po/
│ ├── templates/ipsec-vpnd.pot # gettext 模板
│ └── zh_Hans/ipsec-vpnd.po # 简体中文翻译
├── root/
│ ├── etc/config/ipsec-vpnd # UCI 默认配置(服务默认 enabled=0)
│ ├── etc/init.d/ipsec-vpnd # procd init:写 ipsec.conf/secrets、启 starter
│ ├── etc/uci-defaults/luci-ipsec-vpnd
│ │ # 首次安装一次性:建 network.VPN + firewall
│ ├── usr/share/luci/menu.d/luci-app-ipsec-vpnd.json
│ │ # LuCI 菜单注册(VPN → IPSec VPN Server)
│ └── usr/share/rpcd/acl.d/luci-app-ipsec-vpnd.json
│ # rpcd ACL:放行 luci-app-ipsec-vpnd 读写 /etc/config/ipsec-vpnd
├── .github/workflows/
│ ├── build.yml
│ └── cleanup-old-workflow.yml
├── LICENSE # Apache-2.0
└── README.md # 本文件
维护
- 上游:fork 自 ImmortalWrt LuCI
applications/luci-app-ipsec-vpnd - 当前 main:自维护分支,修了上游一些配置假设(详见 commit 历史)
- 同步:fix 在 main 上验证后通过 PR 回上游
- 不要把生成的
.apk/.ipk提交到仓库(.gitignore已过滤)
故障排查
| 现象 | 排查 |
|---|---|
| LuCI 菜单看不到 IPSec VPN Server | LuCI → 系统 → 软件包,确认 luci-app-ipsec-vpnd 已装;刷新 LuCI 缓存(rm -f /tmp/luci-indexcache) |
| 服务起不来,日志说 "starter: no such file" | strongswan-minimal 没装;装上 |
| 客户端拨不上,日志说 "no IKE config" | 看 /etc/config/ipsec-vpnd 的 enabled 是不是 1;看 init 日志(logread | grep ipsec) |
| 系统自带 ipsec 又被启起来抢端口 | 升级 strongswan 包后可能要再跑一次 uci-defaults/luci-ipsec-vpnd——本包 init 脚本每次启动前都会重新 stop+disable 系统那个,但只在服务 enabled 时跑 |
| ImmortalWrt 25.12 装不上(缺依赖) | 见上面“关于 ImmortalWrt 25.12 系列” |
| GitHub Actions 出包失败 | 看 Build workflow 的 step 日志;常见坑在 actions/cache 没命中、host 工具链 apt 装失败这些 |
许可证
Apache-2.0。详见 LICENSE。