summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-strongswan-ipsec
diff options
context:
space:
mode:
authorNicholas Smith <nicholas@nbembedded.com>2023-09-05 20:03:18 +1000
committerNicholas Smith <nicholas@nbembedded.com>2023-09-06 08:59:45 +1000
commit6c0f603f027b1ba615c7c8cb851625f50e25ef22 (patch)
tree170ed169d96815ad34df3178e14bce3a100cd738 /applications/luci-app-strongswan-ipsec
parent49cc27c670ba991938cad38b3962c2641f743249 (diff)
luci-app-strongswan-ipsec: add package
Signed-off-by: Nicholas Smith <nicholas@nbembedded.com>
Diffstat (limited to 'applications/luci-app-strongswan-ipsec')
-rw-r--r--applications/luci-app-strongswan-ipsec/Makefile15
-rw-r--r--applications/luci-app-strongswan-ipsec/htdocs/luci-static/resources/view/ipsec.js168
-rw-r--r--applications/luci-app-strongswan-ipsec/root/etc/config/ipsec46
-rw-r--r--applications/luci-app-strongswan-ipsec/root/usr/share/luci/menu.d/luci-app-strongswan-ipsec.json15
-rw-r--r--applications/luci-app-strongswan-ipsec/root/usr/share/rpcd/acl.d/luci-app-strongswan-ipsec.json11
5 files changed, 255 insertions, 0 deletions
diff --git a/applications/luci-app-strongswan-ipsec/Makefile b/applications/luci-app-strongswan-ipsec/Makefile
new file mode 100644
index 0000000000..5dbbe2124f
--- /dev/null
+++ b/applications/luci-app-strongswan-ipsec/Makefile
@@ -0,0 +1,15 @@
+# Copyright 2021 Nicholas Smith (nicholas@nbembedded.com)
+# This is free software, licensed under the GNU General Public License v2.
+
+include $(TOPDIR)/rules.mk
+
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_MAINTAINER:=Nicholas Smith <nicholas@nbembedded.com>
+
+LUCI_TITLE:=LuCI support for IPSec via Strongswan
+LUCI_DESCRIPTION:=Allows configuration of Strongswan IPSec settings
+LUCI_DEPENDS:=+strongswan-ipsec
+
+include ../../luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/applications/luci-app-strongswan-ipsec/htdocs/luci-static/resources/view/ipsec.js b/applications/luci-app-strongswan-ipsec/htdocs/luci-static/resources/view/ipsec.js
new file mode 100644
index 0000000000..53acf71e8e
--- /dev/null
+++ b/applications/luci-app-strongswan-ipsec/htdocs/luci-static/resources/view/ipsec.js
@@ -0,0 +1,168 @@
+'use strict';
+'require view';
+'require form';
+'require tools.widgets as widgets';
+
+return view.extend({
+ render: function() {
+ var m, s, o;
+
+ m = new form.Map('ipsec',
+ _('IPsec Configuration'),
+ _("Configure IPsec for secure VPN connections."));
+
+ // IPsec General Settings
+ s = m.section(form.TypedSection, 'ipsec', _('IPsec General Settings'));
+ s.anonymous = true;
+
+ o = s.option(widgets.ZoneSelect, 'zone', _('Zone'), _('Firewall zone that has to match the defined firewall zone'));
+ o.default = 'lan';
+ o.multiple = true;
+
+ o = s.option(widgets.NetworkSelect, 'listen', _('Listen Interfaces'), _('Interfaces that accept VPN traffic'));
+ o.datatype = 'interface';
+ o.placeholder = _('Select an interface or leave empty for all interfaces');
+ o.default = 'wan';
+ o.multiple = true;
+
+ o = s.option(form.Value, 'debug', _('Debug Level'), _('Logs written to /var/log/charon.log'));
+ o.default = '0';
+ o.datatype = "uinteger";
+
+ // Remote Configuration
+ s = m.section(form.TypedSection, 'remote', _('Remote Configuration'));
+ s.anonymous = false;
+
+ o = s.option(form.Flag, 'enabled', _('Enabled'), _('Configuration is enabled or not'));
+
+ o = s.option(form.Value, 'gateway', _('Gateway (Remote Endpoint)'), _('Public IP address or FQDN name of the tunnel remote endpoint'));
+ o.datatype = 'or(hostname,ipaddr)';
+
+ o = s.option(form.Value, 'local_gateway', _('Local Gateway'), _('IP address or FQDN of the tunnel local endpoint'));
+ o.datatype = 'or(hostname,ipaddr)';
+
+ o = s.option(form.Value, 'local_sourceip', _('Local Source IP'), _('Virtual IP(s) to request in IKEv2 configuration payloads requests'));
+ o.datatype = 'ipaddr';
+
+ o = s.option(form.Value, 'local_ip', _('Local IP'), _('Local address(es) to use in IKE negotiation'));
+ o.datatype = 'ipaddr';
+
+ o = s.option(form.Value, 'local_identifier', _('Local Identifier'), _('Local identifier for IKE (phase 1)'));
+ o.datatype = 'string';
+ o.placeholder = "C=US, O=Acme Corporation, CN=headquarters"
+
+ o = s.option(form.Value, 'remote_identifier', _('Remote Identifier'), _('Remote identifier for IKE (phase 1)'));
+ o.datatype = 'string';
+ o.placeholder = "C=US, O=Acme Corporation, CN=soho"
+
+ o = s.option(form.ListValue, 'authentication_method', _('Authentication Method'), _('IKE authentication (phase 1).'));
+ o.value('psk', "Pre-shared Key");
+ o.value('pubkey', "Public Key");
+ o.required = true;
+
+ o = s.option(form.Value, 'pre_shared_key', _('Pre-Shared Key'), _('The pre-shared key for the tunnel if authentication is psk'));
+ o.datatype = 'string';
+ o.password = true;
+ o.depends('authentication_method', 'psk');
+
+ o = s.option(form.Flag, 'mobike', _('MOBIKE'), _('MOBIKE (IKEv2 Mobility and Multihoming Protocol)'));
+ o.default = '1';
+
+ o = s.option(form.ListValue, 'fragmentation', _('IKE Fragmentation'), _('Use IKE fragmentation (yes, no, force, accept)'));
+ o.value('yes');
+ o.value('no');
+ o.value('force');
+ o.value('accept')
+ o.default = 'yes';
+
+ o = s.option(form.ListValue, 'crypto_proposal', _('Crypto Proposal'), _('List of IKE (phase 1) proposals to use for authentication'));
+ o.value('encryption_algorithm');
+ o.value('hash_algorithm');
+ o.value('dh_group');
+ o.value('prf_algorithm');
+
+ o = s.option(form.Value, 'tunnel', _('Tunnel'), _('Name of ESP/AH (phase 2) section'));
+ o.required = true
+
+ o = s.option(form.Value, 'authentication_method', _('Authentication Method'), _('IKE authentication (phase 1)'));
+ o.datatype = 'string';
+
+ s = m.section(form.TypedSection, 'ipsec', _('IPsec General Settings'));
+ s.anonymous = true;
+
+ o = s.option(form.ListValue, 'encryption_algorithm', _('Encryption Algorithm'), _('Encryption method (aes128, aes192, aes256, 3des)'));
+ o.value('aes128');
+ o.value('aes192');
+ o.value('aes256');
+ o.value('3des');
+ o.required = true
+
+ o = s.option(form.ListValue, 'hash_algorithm', _('Hash Algorithm'), _('Hash algorithm (md5, sha1, sha2, ...)'));
+ o.value('md5');
+ o.value('sha1');
+ o.value('sha2');
+ o.value('sha256');
+ o.value('sha384');
+ o.value('sha512');
+ o.value('sha3_256');
+ o.value('sha3_384');
+ o.value('sha3_512');
+ o.value('blake2s256');
+ o.value('blake2b512');
+ o.value('blake2s256');
+ o.value('blake2b512');
+ o.value('whirlpool');
+ o.value('tiger');
+ o.required = true
+
+ o = s.option(form.ListValue, 'dh_group', _('Diffie-Hellman Group'), _('Diffie-Hellman exponentiation (modp768, modp1024, ...)'));
+ o.value('modp768');
+ o.value('modp1024');
+ o.value('modp1536');
+ o.value('modp2048');
+ o.value('modp3072');
+ o.value('modp4096');
+ o.required = true
+
+ o = s.option(form.ListValue, 'prf_algorithm', _('PRF Algorithm'), _('Pseudo-Random Functions to use with IKE'));
+ o.value('prf_hmac_md5');
+ o.value('prfmd5')
+ o.value('prfsha1')
+ o.value('prfsha256')
+ o.value('pfsha384')
+ o.value('prfsha512')
+
+ // Tunnel Configuration
+ s = m.section(form.TypedSection, 'tunnel', _('Tunnel Configuration'));
+ s.anonymous = false;
+
+ o = s.option(form.Value, 'local_subnet', _('Local Subnet'), _('Local network(s)'));
+ o.placeholder = "192.168.1.1/24"
+ o.required = true
+
+ o = s.option(form.Value, 'remote_subnet', _('Remote Subnet'), _('Remote network(s)'));
+ o.placeholder = "192.168.2.1/24"
+ o.required = true
+
+ o = s.option(form.Value, 'local_nat', _('Local NAT'), _('NAT range for tunnels with overlapping IP addresses'));
+ o.datatype = 'subnet';
+
+ o = s.option(form.ListValue, 'crypto_proposal', _('Crypto Proposal (Phase 2)'), _('List of ESP (phase two) proposals'));
+ o.value('encryption_algorithm');
+ o.value('hash_algorithm');
+ o.value('dh_group');
+ o.value('prf_algorithm');
+ o.required = true
+
+ o = s.option(form.ListValue, 'startaction', _('Start Action'), _('Action on initial configuration load'));
+ o.value('none');
+ o.value('start');
+ o.value('route');
+ o.default = 'route';
+
+ o = s.option(form.Value, 'updown', _('Up/Down Script Path'), _('Path to script to run on CHILD_SA up/down events'));
+ o.datatype = 'filepath';
+
+ return m.render();
+ }
+});
diff --git a/applications/luci-app-strongswan-ipsec/root/etc/config/ipsec b/applications/luci-app-strongswan-ipsec/root/etc/config/ipsec
new file mode 100644
index 0000000000..20ef4dd84d
--- /dev/null
+++ b/applications/luci-app-strongswan-ipsec/root/etc/config/ipsec
@@ -0,0 +1,46 @@
+config 'ipsec'
+ # useful so traffic isn't sourced from internal addresses,
+ # which would then requiring NATting and port 4500, etc.
+ list 'interface' 'wan'
+ option 'zone' 'lan'
+
+config 'remote' 'acme'
+ option 'enabled' '0'
+ # address of wan device
+ option 'local_ip' '6.6.6.6'
+ # peer has routable DHCP'd address which changes
+ option 'gateway' 'acme.example.com'
+ option 'authentication_method' 'psk'
+ option 'local_identifier' 'C=US, O=Acme Corporation, CN=headquarters'
+ option 'remote_identifier' 'C=US, O=Acme Corporation, CN=soho'
+ option 'local_cert' 'headquarters.crt'
+ option 'local_key' 'headquarters.key'
+ option 'ca_cert' 'acme.crt'
+ option 'rekeytime' '4h'
+ option 'keyingretries' '0'
+ option 'mobike' '0'
+ option 'fragmentation' '1'
+ list 'crypto_proposal' 'ike_proposal'
+ list 'tunnel' 'tun_soho'
+
+config 'crypto_proposal' 'ike_proposal'
+ option 'encryption_algorithm' 'aes256gcm'
+ # no hash_algorithm allowed with AEAD
+ option 'dh_group' 'modp3072'
+ option prf_algorithm 'prfsha512'
+
+# we don't specify subnets because we're going to use XFRM-interfaced based routes instead
+config 'tunnel' 'tun_soho'
+ list 'local_subnet' '0.0.0.0/0'
+ list 'remote_subnet' '0.0.0.0/0'
+ option 'if_id' '357'
+ option 'rekeytime' '1h'
+ # other end is behind NAT or we'd use 'route' to initiate
+ option 'startaction' 'none'
+ option 'closeaction' 'none'
+ list 'crypto_proposal' 'esp_proposal'
+
+config 'crypto_proposal' 'esp_proposal'
+ option 'encryption_algorithm' 'aes256gcm'
+ # no hash_algorithm with allowed with AEAD
+ option 'dh_group' 'modp3072' \ No newline at end of file
diff --git a/applications/luci-app-strongswan-ipsec/root/usr/share/luci/menu.d/luci-app-strongswan-ipsec.json b/applications/luci-app-strongswan-ipsec/root/usr/share/luci/menu.d/luci-app-strongswan-ipsec.json
new file mode 100644
index 0000000000..8fc3e9c8c2
--- /dev/null
+++ b/applications/luci-app-strongswan-ipsec/root/usr/share/luci/menu.d/luci-app-strongswan-ipsec.json
@@ -0,0 +1,15 @@
+{
+ "admin/vpn/strongswan-ipsec": {
+ "title": "Strongswan IPSec",
+ "order": 90,
+ "action": {
+ "type": "view",
+ "path": "strongswan-ipsec"
+ },
+ "depends": {
+ "acl": [
+ "luci-app-strongswan-ipsec"
+ ]
+ }
+ }
+}
diff --git a/applications/luci-app-strongswan-ipsec/root/usr/share/rpcd/acl.d/luci-app-strongswan-ipsec.json b/applications/luci-app-strongswan-ipsec/root/usr/share/rpcd/acl.d/luci-app-strongswan-ipsec.json
new file mode 100644
index 0000000000..3b940b8281
--- /dev/null
+++ b/applications/luci-app-strongswan-ipsec/root/usr/share/rpcd/acl.d/luci-app-strongswan-ipsec.json
@@ -0,0 +1,11 @@
+{
+ "luci-app-strongswan-ipsec": {
+ "description": "Grant access to luci-app-strongswan-ipsec",
+ "read": {
+ "uci": [ "ipsec" ]
+ },
+ "write": {
+ "uci": [ "ipsec" ]
+ }
+ }
+}