diff options
Diffstat (limited to 'applications/luci-app-strongswan-ipsec')
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" ] + } + } +} |