From 78f10fee0003daf1430e57f1afc79ef04e56defc Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Mon, 8 Oct 2018 22:31:49 +0800 Subject: [PATCH] re-add luci IPSEC vpn server --- package/lean/luci-app-ipsec-vpnd/Makefile | 18 + .../luasrc/controller/ipsec-server.lua | 19 + .../model/cbi/ipsec-server/ipsec-server.lua | 35 ++ .../luasrc/view/ipsec/ipsec_status.htm | 22 + .../luci-app-ipsec-vpnd/po/zh-cn/ipsec.po | 34 ++ .../luci-app-ipsec-vpnd/root/etc/config/ipsec | 9 + .../luci-app-ipsec-vpnd/root/etc/init.d/ipsec | 427 ++++++++++++++++++ .../root/etc/ipsec.include | 11 + .../root/etc/uci-defaults/ipsec | 54 +++ 9 files changed, 629 insertions(+) create mode 100644 package/lean/luci-app-ipsec-vpnd/Makefile create mode 100644 package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua create mode 100644 package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua create mode 100644 package/lean/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm create mode 100644 package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po create mode 100644 package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec create mode 100755 package/lean/luci-app-ipsec-vpnd/root/etc/init.d/ipsec create mode 100755 package/lean/luci-app-ipsec-vpnd/root/etc/ipsec.include create mode 100755 package/lean/luci-app-ipsec-vpnd/root/etc/uci-defaults/ipsec diff --git a/package/lean/luci-app-ipsec-vpnd/Makefile b/package/lean/luci-app-ipsec-vpnd/Makefile new file mode 100644 index 000000000..b7a83920f --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/Makefile @@ -0,0 +1,18 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for IPSec VPN Server (IKEv1 with PSK and Xauth) +LUCI_DEPENDS:=+strongswan-minimal +strongswan-mod-xauth-generic +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=7 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature + + diff --git a/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua b/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua new file mode 100644 index 000000000..2925194c6 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/luasrc/controller/ipsec-server.lua @@ -0,0 +1,19 @@ + +module("luci.controller.ipsec-server", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/ipsec") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + entry({"admin", "vpn", "ipsec-server"}, cbi("ipsec-server/ipsec-server"), _("IPSec VPN Server"), 80).dependent=false + entry({"admin", "vpn", "ipsec-server","status"},call("act_status")).leaf=true +end + +function act_status() + local e={} + e.running=luci.sys.call("pgrep ipsec >/dev/null")==0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua b/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua new file mode 100644 index 000000000..79a47b8bf --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/luasrc/model/cbi/ipsec-server/ipsec-server.lua @@ -0,0 +1,35 @@ + +mp = Map("ipsec", translate("IPSec VPN Server")) +mp.description = translate("IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)") + +mp:section(SimpleSection).template = "ipsec/ipsec_status" + +s = mp:section(NamedSection, "ipsec", "service") +s.anonymouse = true + +enabled = s:option(Flag, "enabled", translate("Enable")) +enabled.default = 0 +enabled.rmempty = false + +clientip = s:option(Value, "clientip", translate("VPN Client IP")) +clientip.datatype = "ip4addr" +clientip.description = translate("LAN DHCP reserved started IP addresses with the same subnet mask") +clientip.optional = false +clientip.rmempty = false + +clientdns = s:option(Value, "clientdns", translate("VPN Client DNS")) +clientdns.datatype = "ip4addr" +clientdns.description = translate("DNS using in VPN tunnel.Set to the router's LAN IP is recommended") +clientdns.optional = false +clientdns.rmempty = false + +account = s:option(Value, "account", translate("Account")) +account.datatype = "string" + +password = s:option(Value, "password", translate("Password")) +password.password = true + +secret = s:option(Value, "secret", translate("Secret Pre-Shared Key")) +secret.password = true + +return mp diff --git a/package/lean/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm b/package/lean/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm new file mode 100644 index 000000000..60225b490 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/luasrc/view/ipsec/ipsec_status.htm @@ -0,0 +1,22 @@ + + +
+

+ <%:Collecting data...%> +

+
\ No newline at end of file diff --git a/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po b/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po new file mode 100644 index 000000000..0bf6b62aa --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/po/zh-cn/ipsec.po @@ -0,0 +1,34 @@ +msgid "IPSec VPN Server" +msgstr "IPSec VPN 服务器" + +msgid "IPSec VPN connectivity using the native built-in VPN Client on iOS or Andriod (IKEv1 with PSK and Xauth)" +msgstr "使用iOS 或者 Andriod (IKEv1 with PSK and Xauth) 原生内置 IPSec VPN 客户端进行连接" + +msgid "VPN Client IP" +msgstr "VPN客户端地址段" + +msgid "LAN DHCP reserved started IP addresses with the same subnet mask" +msgstr "VPN客户端使用DHCP保留空余IP的起始地址,必须和路由器LAN同一个子网掩码,例如 192.168.0.10/24" + +msgid "VPN Client DNS" +msgstr "VPN客户端DNS服务器" + +msgid "DNS using in VPN tunnel.Set to the router's LAN IP is recommended" +msgstr "指定VPN客户端的DNS地址。推荐设置为路由器的LAN IP,例如 192.168.0.1" + +msgid "Account" +msgstr "账户" + +msgid "Secret Pre-Shared Key" +msgstr "PSK密钥" + +msgid "IPSec VPN Server status" +msgstr "IPSec VPN 服务器运行状态" + +msgid "Disable from startup" +msgstr "禁止开机启动" + +msgid "Enable on startup" +msgstr "允许开机启动" + + diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec b/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec new file mode 100644 index 000000000..93c21f278 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/config/ipsec @@ -0,0 +1,9 @@ + +config service 'ipsec' + option clientdns '192.168.0.1' + option account 'lean' + option secret 'myopenwrt' + option enabled '0' + option password '12345678' + option clientip '192.168.0.10/24' + diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/init.d/ipsec b/package/lean/luci-app-ipsec-vpnd/root/etc/init.d/ipsec new file mode 100755 index 000000000..5a4c6a217 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/init.d/ipsec @@ -0,0 +1,427 @@ +#!/bin/sh /etc/rc.common + +START=90 +STOP=10 + +USE_PROCD=1 +PROG=/usr/lib/ipsec/starter + +. $IPKG_INSTROOT/lib/functions.sh +. $IPKG_INSTROOT/lib/functions/network.sh + +IPSEC_SECRETS_FILE=/etc/ipsec.secrets +IPSEC_CONN_FILE=/etc/ipsec.conf +STRONGSWAN_CONF_FILE=/etc/strongswan.conf + +IPSEC_VAR_SECRETS_FILE=/var/ipsec/ipsec.secrets +IPSEC_VAR_CONN_FILE=/var/ipsec/ipsec.conf +STRONGSWAN_VAR_CONF_FILE=/var/ipsec/strongswan.conf + +WAIT_FOR_INTF=0 + +file_reset() { + : > "$1" +} + +xappend() { + local file="$1" + shift + + echo "${@}" >> "${file}" +} + +remove_include() { + local file="$1" + local include="$2" + + sed -i "\_${include}_d" "${file}" +} + +remove_includes() { + remove_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" + remove_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" + remove_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +do_include() { + local conf="$1" + local uciconf="$2" + local backup=`mktemp -t -p /tmp/ ipsec-init-XXXXXX` + + [ ! -f "${conf}" ] && rm -rf "${conf}" + touch "${conf}" + + cat "${conf}" | grep -v "${uciconf}" > "${backup}" + mv "${backup}" "${conf}" + xappend "${conf}" "include ${uciconf}" + file_reset "${uciconf}" +} + +ipsec_reset() { + do_include "${IPSEC_CONN_FILE}" "${IPSEC_VAR_CONN_FILE}" +} + +ipsec_xappend() { + xappend "${IPSEC_VAR_CONN_FILE}" "$@" +} + +swan_reset() { + do_include "${STRONGSWAN_CONF_FILE}" "${STRONGSWAN_VAR_CONF_FILE}" +} + +swan_xappend() { + xappend "${STRONGSWAN_VAR_CONF_FILE}" "$@" +} + +secret_reset() { + do_include "${IPSEC_SECRETS_FILE}" "${IPSEC_VAR_SECRETS_FILE}" +} + +secret_xappend() { + xappend "${IPSEC_VAR_SECRETS_FILE}" "$@" +} + +warning() { + echo "WARNING: $@" >&2 +} + +add_crypto_proposal() { + local encryption_algorithm + local hash_algorithm + local dh_group + + config_get encryption_algorithm "$1" encryption_algorithm + config_get hash_algorithm "$1" hash_algorithm + config_get dh_group "$1" dh_group + + [ -n "${encryption_algorithm}" ] && \ + crypto="${crypto:+${crypto},}${encryption_algorithm}${hash_algorithm:+-${hash_algorithm}}${dh_group:+-${dh_group}}" +} + +set_crypto_proposal() { + local conf="$1" + local proposal + + crypto="" + + config_get crypto_proposal "$conf" crypto_proposal "" + for proposal in $crypto_proposal; do + add_crypto_proposal "$proposal" + done + + [ -n "${crypto}" ] && { + local force_crypto_proposal + + config_get_bool force_crypto_proposal "$conf" force_crypto_proposal + + [ "${force_crypto_proposal}" = "1" ] && crypto="${crypto}!" + } + + crypto_proposal="${crypto}" +} + +config_conn() { + # Generic ipsec conn section shared by tunnel and transport + local mode + local local_subnet + local local_nat + local local_sourceip + local local_updown + local local_firewall + local remote_subnet + local remote_sourceip + local remote_updown + local remote_firewall + local ikelifetime + local lifetime + local margintime + local keyingtries + local dpdaction + local dpddelay + local inactivity + local keyexchange + + config_get mode "$1" mode "route" + config_get local_subnet "$1" local_subnet "" + config_get local_nat "$1" local_nat "" + config_get local_sourceip "$1" local_sourceip "" + config_get local_updown "$1" local_updown "" + config_get local_firewall "$1" local_firewall "" + config_get remote_subnet "$1" remote_subnet "" + config_get remote_sourceip "$1" remote_sourceip "" + config_get remote_updown "$1" remote_updown "" + config_get remote_firewall "$1" remote_firewall "" + config_get ikelifetime "$1" ikelifetime "3h" + config_get lifetime "$1" lifetime "1h" + config_get margintime "$1" margintime "9m" + config_get keyingtries "$1" keyingtries "3" + config_get dpdaction "$1" dpdaction "none" + config_get dpddelay "$1" dpddelay "30s" + config_get inactivity "$1" inactivity + config_get keyexchange "$1" keyexchange "ikev2" + + [ -n "$local_nat" ] && local_subnet=$local_nat + + ipsec_xappend "conn $config_name-$1" + ipsec_xappend " left=%any" + ipsec_xappend " right=$remote_gateway" + + [ -n "$local_sourceip" ] && ipsec_xappend " leftsourceip=$local_sourceip" + [ -n "$local_subnet" ] && ipsec_xappend " leftsubnet=$local_subnet" + + [ -n "$local_firewall" ] && ipsec_xappend " leftfirewall=$local_firewall" + [ -n "$remote_firewall" ] && ipsec_xappend " rightfirewall=$remote_firewall" + + ipsec_xappend " ikelifetime=$ikelifetime" + ipsec_xappend " lifetime=$lifetime" + ipsec_xappend " margintime=$margintime" + ipsec_xappend " keyingtries=$keyingtries" + ipsec_xappend " dpdaction=$dpdaction" + ipsec_xappend " dpddelay=$dpddelay" + + [ -n "$inactivity" ] && ipsec_xappend " inactivity=$inactivity" + + if [ "$auth_method" = "psk" ]; then + ipsec_xappend " leftauth=psk" + ipsec_xappend " rightauth=psk" + + [ "$remote_sourceip" != "" ] && ipsec_xappend " rightsourceip=$remote_sourceip" + [ "$remote_subnet" != "" ] && ipsec_xappend " rightsubnet=$remote_subnet" + + ipsec_xappend " auto=$mode" + else + warning "AuthenticationMethod $auth_method not supported" + fi + + [ -n "$local_identifier" ] && ipsec_xappend " leftid=$local_identifier" + [ -n "$remote_identifier" ] && ipsec_xappend " rightid=$remote_identifier" + [ -n "$local_updown" ] && ipsec_xappend " leftupdown=$local_updown" + [ -n "$remote_updown" ] && ipsec_xappend " rightupdown=$remote_updown" + ipsec_xappend " keyexchange=$keyexchange" + + set_crypto_proposal "$1" + [ -n "${crypto_proposal}" ] && ipsec_xappend " esp=$crypto_proposal" + [ -n "${ike_proposal}" ] && ipsec_xappend " ike=$ike_proposal" +} + +config_tunnel() { + config_conn "$1" + + # Specific for the tunnel part + ipsec_xappend " type=tunnel" +} + +config_transport() { + config_conn "$1" + + # Specific for the transport part + ipsec_xappend " type=transport" +} + +config_remote() { + local enabled + local gateway + local pre_shared_key + local auth_method + + config_name=$1 + + config_get_bool enabled "$1" enabled 0 + [ $enabled -eq 0 ] && return + + config_get gateway "$1" gateway + config_get pre_shared_key "$1" pre_shared_key + config_get auth_method "$1" authentication_method + config_get local_identifier "$1" local_identifier "" + config_get remote_identifier "$1" remote_identifier "" + + [ "$gateway" = "any" ] && remote_gateway="%any" || remote_gateway="$gateway" + + [ -z "$local_identifier" ] && { + local ipdest + + [ "$remote_gateway" = "%any" ] && ipdest="1.1.1.1" || ipdest="$remote_gateway" + local_gateway=`ip route get $ipdest | awk -F"src" '/src/{gsub(/ /,"");print $2}'` + } + + [ -n "$local_identifier" ] && secret_xappend -n "$local_identifier " || secret_xappend -n "$local_gateway " + [ -n "$remote_identifier" ] && secret_xappend -n "$remote_identifier " || secret_xappend -n "$remote_gateway " + + secret_xappend ": PSK \"$pre_shared_key\"" + + set_crypto_proposal "$1" + ike_proposal="$crypto_proposal" + + config_list_foreach "$1" tunnel config_tunnel + + config_list_foreach "$1" transport config_transport + + ipsec_xappend "" +} + +config_ipsec() { + local debug + local rtinstall_enabled + local routing_tables_ignored + local routing_table + local routing_table_id + local interface + local device_list + + ipsec_reset + secret_reset + swan_reset + + ipsec_xappend "# generated by /etc/init.d/ipsec" + ipsec_xappend "version 2" + ipsec_xappend "" + + secret_xappend "# generated by /etc/init.d/ipsec" + + config_get debug "$1" debug 0 + config_get_bool rtinstall_enabled "$1" rtinstall_enabled 1 + [ $rtinstall_enabled -eq 1 ] && install_routes=yes || install_routes=no + + # prepare extra charon config option ignore_routing_tables + for routing_table in $(config_get "$1" "ignore_routing_tables"); do + if [ "$routing_table" -ge 0 ] 2>/dev/null; then + routing_table_id=$routing_table + else + routing_table_id=$(sed -n '/[ \t]*[0-9]\+[ \t]\+'$routing_table'[ \t]*$/s/[ \t]*\([0-9]\+\).*/\1/p' /etc/iproute2/rt_tables) + fi + + [ -n "$routing_table_id" ] && append routing_tables_ignored "$routing_table_id" + done + + local interface_list=$(config_get "$1" "interface") + if [ -z "$interface_list" ]; then + WAIT_FOR_INTF=0 + else + for interface in $interface_list; do + network_get_device device $interface + [ -n "$device" ] && append device_list "$device" "," + done + [ -n "$device_list" ] && WAIT_FOR_INTF=0 || WAIT_FOR_INTF=1 + fi + + swan_xappend "# generated by /etc/init.d/ipsec" + swan_xappend "charon {" + swan_xappend " load_modular = yes" + swan_xappend " install_routes = $install_routes" + [ -n "$routing_tables_ignored" ] && swan_xappend " ignore_routing_tables = $routing_tables_ignored" + [ -n "$device_list" ] && swan_xappend " interfaces_use = $device_list" + swan_xappend " plugins {" + swan_xappend " include /etc/strongswan.d/charon/*.conf" + swan_xappend " }" + swan_xappend " syslog {" + swan_xappend " identifier = ipsec" + swan_xappend " daemon {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " auth {" + swan_xappend " default = $debug" + swan_xappend " }" + swan_xappend " }" + swan_xappend "}" +} + +prepare_env() { + mkdir -p /var/ipsec + remove_includes + config_load ipsec + config_foreach config_ipsec ipsec + config_foreach config_remote remote +} + +service_running() { + ipsec status > /dev/null 2>&1 +} + +reload_service() { + local bool vt_enabled=`uci get ipsec.@service[0].enabled 2>/dev/null` + [ "$vt_enabled" = 0 ] && /etc/init.d/ipsec stop && return + running && { + prepare_env + [ $WAIT_FOR_INTF -eq 0 ] && { + ipsec rereadall + ipsec reload + return + } + } + [ "$vt_enabled" = 1 ] && start +} + +check_ipsec_interface() { + local intf + + for intf in $(config_get "$1" interface); do + procd_add_interface_trigger "interface.*" "$intf" /etc/init.d/ipsec reload + done +} + +service_triggers() { + procd_add_reload_trigger "ipsec" + config load "ipsec" + config_foreach check_ipsec_interface ipsec +} + +start_service() { + local vt_enabled=`uci get ipsec.@service[0].enabled 2>/dev/null` + local vt_clientip=`uci get ipsec.@service[0].clientip` + local vt_clientdns=`uci get ipsec.@service[0].clientdns` + local vt_account=`uci get ipsec.@service[0].account` + local vt_password=`uci get ipsec.@service[0].password 2>/dev/null` + local vt_secret=`uci get ipsec.@service[0].secret 2>/dev/null` + + [ "$vt_enabled" = 0 ] && /etc/init.d/ipsec stop && return + + cat > /etc/ipsec.conf < /etc/ipsec.secrets </dev/null +iptables -D FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT 2>/dev/null +iptables -D INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT 2>/dev/null +iptables -D OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT 2>/dev/null + +iptables -I FORWARD -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I FORWARD -m policy --dir out --pol ipsec --proto esp -j ACCEPT +iptables -I INPUT -m policy --dir in --pol ipsec --proto esp -j ACCEPT +iptables -I OUTPUT -m policy --dir out --pol ipsec --proto esp -j ACCEPT + +echo 1 > /proc/sys/net/ipv4/conf/br-lan/proxy_arp diff --git a/package/lean/luci-app-ipsec-vpnd/root/etc/uci-defaults/ipsec b/package/lean/luci-app-ipsec-vpnd/root/etc/uci-defaults/ipsec new file mode 100755 index 000000000..b9eb66fb8 --- /dev/null +++ b/package/lean/luci-app-ipsec-vpnd/root/etc/uci-defaults/ipsec @@ -0,0 +1,54 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete firewall.ipsecd + set firewall.ipsecd=include + set firewall.ipsecd.type=script + set firewall.ipsecd.path=/etc/ipsec.include + set firewall.ipsecd.reload=1 + commit firewall +EOF + +uci -q batch <<-EOF >/dev/null + delete firewall.ike + add firewall rule + rename firewall.@rule[-1]="ike" + set firewall.@rule[-1].name="ike" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="udp" + set firewall.@rule[-1].dest_port="500" + delete firewall.ipsec + add firewall rule + rename firewall.@rule[-1]="ipsec" + set firewall.@rule[-1].name="ipsec" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="udp" + set firewall.@rule[-1].dest_port="4500" + delete firewall.ah + add firewall rule + rename firewall.@rule[-1]="ah" + set firewall.@rule[-1].name="ah" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="ah" + delete firewall.esp + add firewall rule + rename firewall.@rule[-1]="esp" + set firewall.@rule[-1].name="esp" + set firewall.@rule[-1].target="ACCEPT" + set firewall.@rule[-1].src="wan" + set firewall.@rule[-1].proto="esp" + commit firewall +EOF + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@ipsec[-1] + add ucitrack ipsec + set ucitrack.@ipsec[-1].init=ipsec + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0