diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4946b5f --- /dev/null +++ b/Makefile @@ -0,0 +1,19 @@ +# +# Copyright (C) 2008-2014 The LuCI Team +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI for Zerotier +LUCI_DEPENDS:=+zerotier +LUCI_PKGARCH:=all + +PKG_NAME:=luci-app-zerotier +PKG_VERSION:=1.0 +PKG_RELEASE:=20 + +include ../../luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/luasrc/controller/zerotier.lua b/luasrc/controller/zerotier.lua new file mode 100644 index 0000000..0b9d551 --- /dev/null +++ b/luasrc/controller/zerotier.lua @@ -0,0 +1,22 @@ +module("luci.controller.zerotier", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/zerotier") then + return + end + + entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false + + entry({"admin", "vpn", "zerotier"}, alias("admin", "vpn", "zerotier", "general"), _("ZeroTier"), 99) + entry({"admin", "vpn", "zerotier", "general"}, cbi("zerotier/settings"), _("Base Setting"), 1) + entry({"admin", "vpn", "zerotier", "log"}, form("zerotier/info"), _("Interface Info"), 2) + + entry({"admin", "vpn", "zerotier", "status"}, call("act_status")) +end + +function act_status() + local e = {} + e.running = luci.sys.call("pgrep /usr/bin/zerotier-one >/dev/null") == 0 + luci.http.prepare_content("application/json") + luci.http.write_json(e) +end diff --git a/luasrc/model/cbi/zerotier/info.lua b/luasrc/model/cbi/zerotier/info.lua new file mode 100644 index 0000000..e392cb0 --- /dev/null +++ b/luasrc/model/cbi/zerotier/info.lua @@ -0,0 +1,15 @@ +local fs = require "nixio.fs" +local conffile = "/tmp/zero.info" + +f = SimpleForm("logview") + +t = f:field(TextValue, "conf") +t.rmempty = true +t.rows = 19 +function t.cfgvalue() + luci.sys.exec("for i in $(ifconfig | grep 'zt' | awk '{print $1}'); do ifconfig $i; done > /tmp/zero.info") + return fs.readfile(conffile) or "" +end +t.readonly = "readonly" + +return f diff --git a/luasrc/model/cbi/zerotier/settings.lua b/luasrc/model/cbi/zerotier/settings.lua new file mode 100644 index 0000000..8e6102c --- /dev/null +++ b/luasrc/model/cbi/zerotier/settings.lua @@ -0,0 +1,27 @@ +a = Map("zerotier") +a.title = translate("ZeroTier") +a.description = translate("Zerotier is an open source, cross-platform and easy to use virtual LAN") + +a:section(SimpleSection).template = "zerotier/zerotier_status" + +t = a:section(NamedSection, "sample_config", "zerotier") +t.anonymous = true +t.addremove = false + +e = t:option(Flag, "enabled", translate("Enable")) +e.default = 0 +e.rmempty = false + +e = t:option(DynamicList, "join", translate('ZeroTier Network ID')) +e.password = true +e.rmempty = false + +e = t:option(Flag, "nat", translate("Auto NAT Clients")) +e.description = translate("Allow zerotier clients access your LAN network") +e.default = 0 +e.rmempty = false + +e = t:option(DummyValue, "opennewwindow", translate("")) +e.description = translate("Create or manage your zerotier network, and auth clients who could access") + +return a diff --git a/luasrc/view/zerotier/zerotier_status.htm b/luasrc/view/zerotier/zerotier_status.htm new file mode 100644 index 0000000..9d216c5 --- /dev/null +++ b/luasrc/view/zerotier/zerotier_status.htm @@ -0,0 +1,22 @@ + + +
+

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

+
diff --git a/po/zh-cn/zerotier.po b/po/zh-cn/zerotier.po new file mode 100644 index 0000000..dd3cd71 --- /dev/null +++ b/po/zh-cn/zerotier.po @@ -0,0 +1,17 @@ +msgid "Zerotier is an open source, cross-platform and easy to use virtual LAN" +msgstr "Zerotier 是一个开源,跨平台,而且适合内网穿透互联的傻瓜配置虚拟 VPN LAN" + +msgid "Auto NAT Clients" +msgstr "自动允许客户端 NAT" + +msgid "Allow zerotier clients access your LAN network" +msgstr "允许 Zerotier 的拨入客户端访问路由器 LAN 资源(需要在 Zerotier 管理页面设定到 LAN 网段的路由表)" + +msgid "Create or manage your zerotier network, and auth clients who could access" +msgstr "点击跳转到 Zerotier 官网管理平台,新建或者管理网络,并允许客户端接入访问你私人网路(新接入的节点默认不允许访问)" + +msgid "Base Setting" +msgstr "基本设置" + +msgid "Interface Info" +msgstr "接口信息" diff --git a/root/etc/init.d/zerotier b/root/etc/init.d/zerotier new file mode 100755 index 0000000..666d675 --- /dev/null +++ b/root/etc/init.d/zerotier @@ -0,0 +1,113 @@ +#!/bin/sh /etc/rc.common + +START=99 + +USE_PROCD=1 + +PROG=/usr/bin/zerotier-one +CONFIG_PATH=/var/lib/zerotier-one + +service_triggers() { + procd_add_reload_trigger "zerotier" + procd_add_interface_trigger "interface.*.up" wan /etc/init.d/zerotier restart +} + +section_enabled() { + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +start_instance() { + local cfg="$1" + local port secret config_path + local ARGS="" + + if ! section_enabled "$cfg"; then + echo "disabled in config" + return 1 + fi + + [ -d /etc/config/zero ] || mkdir -p /etc/config/zero + config_path=/etc/config/zero + + config_get_bool port $cfg 'port' + config_get secret $cfg 'secret' + + # Remove existing link or folder + rm -rf $CONFIG_PATH + + # Create link from CONFIG_PATH to config_path + if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then + if [ ! -d "$config_path" ]; then + echo "ZeroTier config_path does not exist: $config_path" + return + fi + + ln -s $config_path $CONFIG_PATH + fi + + mkdir -p $CONFIG_PATH/networks.d + + if [ -n "$port" ]; then + ARGS="$ARGS -p$port" + fi + + if [ "$secret" = "generate" ]; then + echo "Generate secret - please wait..." + local sf="/tmp/zt.$cfg.secret" + + zerotier-idtool generate "$sf" > /dev/null + [ $? -ne 0 ] && return 1 + + secret="$(cat $sf)" + rm "$sf" + + uci set zerotier.$cfg.secret="$secret" + uci commit zerotier + fi + + if [ -n "$secret" ]; then + echo "$secret" > $CONFIG_PATH/identity.secret + # make sure there is not previous identity.public + rm -f $CONFIG_PATH/identity.public + fi + + add_join() { + # an (empty) config file will cause ZT to join a network + touch $CONFIG_PATH/networks.d/$1.conf + } + + config_list_foreach $cfg 'join' add_join + + procd_open_instance + procd_set_param command $PROG $ARGS $CONFIG_PATH + procd_set_param stderr 1 + procd_close_instance +} + +start_service() { + config_load 'zerotier' + config_foreach start_instance 'zerotier' + touch /tmp/zero.log && /etc/zerotier.start > /tmp/zero.log 2>&1 & +} + +stop_instance() { + rm -f /tmp/zero.log + local cfg="$1" + + /etc/zerotier.stop > /tmp/zero.log 2>&1 & + + # Remove existing link or folder + rm -f $CONFIG_PATH/networks.d/*.conf + rm -rf $CONFIG_PATH +} + +stop_service() { + config_load 'zerotier' + config_foreach stop_instance 'zerotier' +} + +reload_service() { + stop + start +} diff --git a/root/etc/uci-defaults/40_luci-zerotier b/root/etc/uci-defaults/40_luci-zerotier new file mode 100755 index 0000000..6168245 --- /dev/null +++ b/root/etc/uci-defaults/40_luci-zerotier @@ -0,0 +1,18 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@zerotier[-1] + add ucitrack zerotier + set ucitrack.@zerotier[-1].init=zerotier + commit ucitrack + + delete firewall.zerotier + set firewall.zerotier=include + set firewall.zerotier.type=script + set firewall.zerotier.path=/etc/zerotier.start + set firewall.zerotier.reload=1 + commit firewall +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/root/etc/zerotier.start b/root/etc/zerotier.start new file mode 100755 index 0000000..b43e5f9 --- /dev/null +++ b/root/etc/zerotier.start @@ -0,0 +1,28 @@ +#!/bin/sh + +zero_enable="$(uci get zerotier.sample_config.enabled)" + +[ "${zero_enable}" -ne "1" ] && exit 0 + +[ -f "/tmp/zero.log" ] && { + while [ "$(ifconfig | grep 'zt' | awk '{print $1}')" = "" ] + do + sleep 1 + done +} + +nat_enable="$(uci get zerotier.sample_config.nat)" +zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" +echo "${zt0}" > "/tmp/zt.nif" + +[ "${nat_enable}" -eq "1" ] && { + for i in ${zt0} + do + ip_segment="" + iptables -I FORWARD -i "$i" -j ACCEPT + iptables -I FORWARD -o "$i" -j ACCEPT + iptables -t nat -I POSTROUTING -o "$i" -j MASQUERADE + ip_segment="$(ip route | grep "dev $i proto kernel" | awk '{print $1}')" + iptables -t nat -I POSTROUTING -s "${ip_segment}" -j MASQUERADE + done +} diff --git a/root/etc/zerotier.stop b/root/etc/zerotier.stop new file mode 100755 index 0000000..cbe7ec4 --- /dev/null +++ b/root/etc/zerotier.stop @@ -0,0 +1,15 @@ +#!/bin/sh + +zt0="$(ifconfig | grep 'zt' | awk '{print $1}')" +[ -z "${zt0}" ] && zt0="$(cat "/tmp/zt.nif")" + +for i in ${zt0} +do + ip_segment="" + iptables -D FORWARD -i "$i" -j ACCEPT 2>/dev/null + iptables -D FORWARD -o "$i" -j ACCEPT 2>/dev/null + iptables -t nat -D POSTROUTING -o "$i" -j MASQUERADE 2>/dev/null + ip_segment="$(ip route | grep "dev $i proto" | awk '{print $1}')" + iptables -t nat -D POSTROUTING -s "${ip_segment}" -j MASQUERADE 2>/dev/null + echo "zt interface $i is stopped!" +done diff --git a/root/etc/zerotier/zerotier.log b/root/etc/zerotier/zerotier.log new file mode 100644 index 0000000..e69de29