include $(TOPDIR)/rules.mk
PKG_NAME:=nebula
-PKG_VERSION:=1.6.0
+PKG_VERSION:=1.6.1
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/slackhq/nebula/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=b16638b99d80a4ae6373f7757a0064dc0defd3f9e165617e7b5c3be9e64d3605
+PKG_HASH:=9c343d998d2eab9473c3bf73d434b8a382d90b1f73095dd1114ecaf2e1c0970f
PKG_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
PKG_LICENSE:=MIT
SECTION:=net
CATEGORY:=Network
TITLE:=nebula
- URL:=https://github.com/slackhq/nebula
+ URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=$(GO_ARCH_DEPENDS) +kmod-tun
endef
SECTION:=net
CATEGORY:=Network
TITLE:=nebula-cert
- URL:=https://github.com/slackhq/nebula
+ URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=$(GO_ARCH_DEPENDS)
endef
+define Package/nebula-proto
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=nebula-proto
+ URL:=https://docs.openwrt.melmac.net/nebula/
+ DEPENDS:=nebula
+ PKGARCH:=all
+endef
+
+define Package/nebula-service
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=nebula-service
+ URL:=https://docs.openwrt.melmac.net/nebula/
+ DEPENDS:=nebula
+ CONFLICTS:=nebula-proto
+ PKGARCH:=all
+endef
+
+define Build/Compile
+ $(call GoPackage/Build/Compile)
+endef
+
define Package/nebula/description
Nebula is a scalable overlay networking tool with a focus on performance, simplicity
and security. It lets you seamlessly connect computers anywhere in the world.
+ This package contains only nebula binary. Unless you want to start nebula manually,
+ you may want to also install *either* 'nebula-service' *or* 'nebula-proto' package.
endef
define Package/nebula-cert/description
-$(call Package/nebula/description)
+ Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+ and security. It lets you seamlessly connect computers anywhere in the world.
This package contains only nebula-cert binary.
endef
+define Package/nebula-proto/description
+ Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+ and security. It lets you seamlessly connect computers anywhere in the world.
+ This package contains only OpenWrt protocol/interface support for nebula.
+endef
+
+define Package/nebula-service/description
+ Nebula is a scalable overlay networking tool with a focus on performance, simplicity
+ and security. It lets you seamlessly connect computers anywhere in the world.
+ This package contains only OpenWrt-specific init.d script for nebula.
+endef
+
define Package/nebula/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
- $(INSTALL_DIR) $(1)/etc/init.d $(1)/usr/sbin $(1)/usr/share/doc/nebula $(1)/lib/upgrade/keep.d
- $(INSTALL_BIN) ./files/nebula.init $(1)/etc/init.d/nebula
- $(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/nebula
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula $(1)/usr/sbin/nebula
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
+ $(INSTALL_DIR) $(1)/usr/share/doc/nebula
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula $(1)/usr/sbin/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE $(1)/usr/share/doc/nebula/LICENSE
$(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula
endef
define Package/nebula-cert/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
- $(INSTALL_DIR) $(1)/usr/sbin $(1)/usr/share/doc/nebula-cert $(1)/lib/upgrade/keep.d
- $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula-cert $(1)/usr/sbin/nebula-cert
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
+ $(INSTALL_DIR) $(1)/usr/share/doc/nebula-cert
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula-cert $(1)/usr/sbin/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/LICENSE $(1)/usr/share/doc/nebula-cert/LICENSE
$(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula-cert
endef
+define Package/nebula-proto/install
+ $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
+ $(INSTALL_DIR) $(1)/lib/netifd/proto
+ $(INSTALL_BIN) ./files/nebula.proto $(1)/lib/netifd/proto/nebula.sh
+ $(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/lib/netifd/proto/nebula.sh
+endef
+
+define Package/nebula-service/install
+ $(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/nebula.init $(1)/etc/init.d/nebula
+ $(SED) "s|^\(readonly PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/nebula
+endef
+
$(eval $(call GoBinPackage,nebula))
$(eval $(call BuildPackage,nebula))
$(eval $(call GoBinPackage,nebula-cert))
$(eval $(call BuildPackage,nebula-cert))
+
+$(eval $(call BuildPackage,nebula-proto))
+
+$(eval $(call BuildPackage,nebula-service))
#!/bin/sh /etc/rc.common
# Copyright 2021 Stan Grishin (stangri@melmac.ca)
-# shellcheck disable=SC2039,SC3043
-PKG_VERSION='dev-test'
+# shellcheck disable=SC3043,SC3060
# shellcheck disable=SC2034
START=80
# shellcheck disable=SC2034
USE_PROCD=1
-if type extra_command 1>/dev/null 2>&1; then
- extra_command 'version' 'Show version information'
-else
-# shellcheck disable=SC2034
- EXTRA_COMMANDS='version'
-fi
-
+readonly PKG_VERSION='dev-test'
+readonly packageName='nebula-service'
+readonly serviceName="$packageName $PKG_VERSION"
+readonly sharedMemoryOutput="/dev/shm/$packageName-output"
readonly PROG=/usr/sbin/nebula
+readonly _OK_='\033[0;32m\xe2\x9c\x93\033[0m'
+readonly _FAIL_='\033[0;31m\xe2\x9c\x97\033[0m'
+
+extra_command 'version' 'Show version information'
version() { echo "Version: $PKG_VERSION"; }
+output() {
+ local msg memmsg logmsg
+ [ -t 1 ] && printf "%b" "$@"
+ msg="${1//$serviceName /service }";
+ if [ "$(printf "%b" "$msg" | wc -l)" -gt 0 ]; then
+ [ -s "$sharedMemoryOutput" ] && memmsg="$(cat "$sharedMemoryOutput")"
+ logmsg="$(printf "%b" "${memmsg}${msg}" | sed 's/\x1b\[[0-9;]*m//g')"
+ logger -t "$packageName" "$(printf "%b" "$logmsg")"
+ rm -f "$sharedMemoryOutput"
+ else
+ printf "%b" "$msg" >> "$sharedMemoryOutput"
+ fi
+}
+output_ok() { output "$_OK_"; }
+output_okn() { output "${_OK_}\\n"; }
+output_fail() { output "$_FAIL_"; }
+output_failn() { output "${_FAIL_}\\n"; }
+
+# https://gist.github.com/pkuczynski/8665367
+# shellcheck disable=SC2086,SC2155
+parse_yaml() {
+ local prefix=$2
+ local s='[[:space:]]*' w='[a-zA-Z0-9_-]*' fs="$(echo @|tr @ '\034'|tr -d '\015')"
+ sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
+ -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" |
+ awk "-F$fs" '{
+ indent = length($1)/2;
+ vname[indent] = $2;
+ for (i in vname) {if (i > indent) {delete vname[i]}}
+ if (length($3) > 0) {
+ vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
+ printf("%s%s%s=\"%s\"\n", "'$prefix'", vn, $2, $3);
+ }
+ }'
+}
+
start_instance() {
- local cfg="$1" port name="${1##*/}"
- port="$(grep -A2 "^listen:" "$cfg" | grep "port: " | awk '{print $2}')"
- procd_open_instance
- procd_set_param command ${PROG} -config "${cfg}"
- procd_set_param stderr 1
- procd_set_param stdout 1
- procd_set_param respawn
- procd_open_data
- json_add_array firewall
- json_add_object ''
- json_add_string type 'rule'
- json_add_string name "Allow-$name"
- json_add_string src 'wan'
- json_add_string dest_port "$port"
- json_add_string proto 'udp'
- json_add_string target 'ACCEPT'
- json_close_object
- json_close_array
- procd_close_data
- procd_close_instance
+ local config_file="$1"
+ local yaml_listen_host yaml_listen_port
+ if [ ! -x "$PROG" ]; then
+ echo "Nebula binary not found! Please install 'nebula' package."
+ output_fail
+ return 1
+ fi
+ if [ ! -s "$config_file" ]; then
+ output_fail
+ return 1
+ fi
+ if ! eval "$(parse_yaml "$config_file" "yaml_")"; then
+ output_fail
+ return 1
+ else
+ procd_open_instance
+ procd_set_param command ${PROG} -config "${config_file}"
+ procd_set_param stderr 1
+ procd_set_param stdout 1
+ procd_set_param respawn
+ procd_open_data
+ json_add_array firewall
+ json_add_object ""
+ json_add_string type rule
+ json_add_string name "${config_file##*/}"
+ json_add_string src "*"
+ json_add_string dest_ip "${yaml_listen_host:-0.0.0.0}"
+ json_add_string dest_port "${yaml_listen_port:-4242}"
+ json_add_string proto udp
+ json_add_string target ACCEPT
+ json_close_object
+ json_close_array
+ procd_close_data
+ procd_close_instance
+ output_ok
+ fi
}
start_service() {
local f
+ output "Starting $packageName instances "
for f in /etc/nebula/*.yml; do
- [ -s "$f" ] && start_instance "$f"
+ start_instance "$f"
done
+ output '\n'
}
service_started() { procd_set_config_changed firewall; }
--- /dev/null
+#!/bin/sh
+# Copyright 2021 Stan Grishin (stangri@melmac.ca)
+# shellcheck disable=SC1091,SC2039,SC2034,SC3043
+readonly PKG_VERSION='dev-test'
+readonly PROG=/usr/sbin/nebula
+readonly packageName='nebula-proto'
+
+[ -x "$PROG" ] || { log "Main nebula executable '/usr/sbin/nebula' not found"; exit 1; }
+
+[ -n "$INCLUDE_ONLY" ] || {
+ . /lib/functions.sh
+ . /lib/functions/network.sh
+ . ../netifd-proto.sh
+ init_proto "$@"
+}
+
+log() { logger -t "$packageName" "$*"; }
+# https://gist.github.com/pkuczynski/8665367
+# shellcheck disable=SC2086,SC2155
+parse_yaml() {
+ local prefix=$2
+ local s='[[:space:]]*' w='[a-zA-Z0-9_-]*' fs="$(echo @|tr @ '\034'|tr -d '\015')"
+ sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
+ -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" |
+ awk "-F$fs" '{
+ indent = length($1)/2;
+ vname[indent] = $2;
+ for (i in vname) {if (i > indent) {delete vname[i]}}
+ if (length($3) > 0) {
+ vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
+ printf("%s%s%s=\"%s\"\n", "'$prefix'", vn, $2, $3);
+ }
+ }'
+}
+
+proto_nebula_init_config() {
+ available=1
+ no_device=1
+ proto_config_add_string "config_file"
+}
+
+proto_nebula_setup() {
+ local interface="$1" config_file address addresses
+ local yaml_listen_host yaml_listen_port yaml_tun_dev
+
+ config_load network
+ config_get config_file "${interface}" "config_file"
+ proto_init_update "${interface}" 1
+
+ [ -s "$config_file" ] || { log "Config file not found or empty!"; return 1; }
+ eval "$(parse_yaml "$config_file" "yaml_")"
+ [ "$yaml_tun_dev" = "$interface" ] || { log "Tunnel device in config file (${yaml_tun_dev}) doesn't match interface name (${interface})!"; return 1; }
+
+ log "Setting up ${interface} from $(basename "$config_file")."
+ proto_run_command "$interface" "$PROG" -config "$config_file"
+ proto_add_data
+ json_add_array firewall
+ json_add_object ""
+ json_add_string type rule
+ json_add_string name "$interface"
+ json_add_string src "*"
+ json_add_string dest_ip "${yaml_listen_host:-0.0.0.0}"
+ json_add_string dest_port "${yaml_listen_port:-4242}"
+ json_add_string proto udp
+ json_add_string target ACCEPT
+ json_close_object
+ json_close_array
+ proto_close_data
+ addresses="$(ip -4 a list dev "$interface" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')"
+ log "Running ${interface} from $(basename "$config_file") with addresses: ${addresses}."
+ for address in ${addresses}; do
+ case "${address}" in
+ *:*/*)
+ proto_add_ipv6_address "${address%%/*}" "${address##*/}"
+ ;;
+ *.*/*)
+ proto_add_ipv4_address "${address%%/*}" "${address##*/}"
+ ;;
+ *:*)
+ proto_add_ipv6_address "${address%%/*}" "128"
+ ;;
+ *.*)
+ proto_add_ipv4_address "${address%%/*}" "32"
+ ;;
+ esac
+ done
+
+ proto_send_update "$interface"
+}
+
+proto_nebula_teardown() {
+ local interface="$1"
+ proto_kill_command "${interface}"
+ log "Killed interface ${interface}."
+}
+
+[ -n "$INCLUDE_ONLY" ] || {
+ add_protocol nebula
+}
#!/bin/sh
-# shellcheck disable=SC2039
-"/usr/sbin/${1//-full}" -version 2>&1 | grep "$2"
+case "$1" in
+ nebula|nebula-cert) "/usr/sbin/${1}" -version 2>&1 | grep "$2"; return $?;;
+ nebula-proto) grep 'readonly PKG_VERSION=' /lib/netifd/proto/nebula.sh 2>&1 | grep "$2"; return $?;;
+# nebula-service) "/etc/init.d/nebula" version 2>&1 | grep "$2"; return $?;;
+ nebula-service) return 0;;
+esac