Merge pull request #19586 from stangri/master-nebula

nebula: implement netifd support
This commit is contained in:
Stan Grishin 2022-10-17 10:21:19 -07:00 committed by GitHub
commit 406050d1e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 258 additions and 43 deletions

View file

@ -4,12 +4,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=nebula PKG_NAME:=nebula
PKG_VERSION:=1.6.0 PKG_VERSION:=1.6.1
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/slackhq/nebula/tar.gz/v$(PKG_VERSION)? 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_MAINTAINER:=Stan Grishin <stangri@melmac.ca>
PKG_LICENSE:=MIT PKG_LICENSE:=MIT
@ -33,7 +33,7 @@ define Package/nebula
SECTION:=net SECTION:=net
CATEGORY:=Network CATEGORY:=Network
TITLE:=nebula TITLE:=nebula
URL:=https://github.com/slackhq/nebula URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=$(GO_ARCH_DEPENDS) +kmod-tun DEPENDS:=$(GO_ARCH_DEPENDS) +kmod-tun
endef endef
@ -41,40 +41,98 @@ define Package/nebula-cert
SECTION:=net SECTION:=net
CATEGORY:=Network CATEGORY:=Network
TITLE:=nebula-cert TITLE:=nebula-cert
URL:=https://github.com/slackhq/nebula URL:=https://docs.openwrt.melmac.net/nebula/
DEPENDS:=$(GO_ARCH_DEPENDS) DEPENDS:=$(GO_ARCH_DEPENDS)
endef 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 define Package/nebula/description
Nebula is a scalable overlay networking tool with a focus on performance, simplicity 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. 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 endef
define Package/nebula-cert/description 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. This package contains only nebula-cert binary.
endef 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 define Package/nebula/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) $(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_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/nebula.init $(1)/etc/init.d/nebula $(INSTALL_DIR) $(1)/lib/upgrade/keep.d
$(SED) "s|^\(PKG_VERSION\).*|\1='$(PKG_VERSION)-$(PKG_RELEASE)'|" $(1)/etc/init.d/nebula $(INSTALL_DIR) $(1)/usr/share/doc/nebula
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula $(1)/usr/sbin/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) $(PKG_BUILD_DIR)/LICENSE $(1)/usr/share/doc/nebula/LICENSE
$(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula $(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula
endef endef
define Package/nebula-cert/install define Package/nebula-cert/install
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR)) $(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_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/nebula-cert $(1)/usr/sbin/nebula-cert $(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) $(PKG_BUILD_DIR)/LICENSE $(1)/usr/share/doc/nebula-cert/LICENSE
$(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula-cert $(INSTALL_DATA) ./files/nebula.upgrade $(1)/lib/upgrade/keep.d/nebula-cert
endef 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 GoBinPackage,nebula))
$(eval $(call BuildPackage,nebula)) $(eval $(call BuildPackage,nebula))
$(eval $(call GoBinPackage,nebula-cert)) $(eval $(call GoBinPackage,nebula-cert))
$(eval $(call BuildPackage,nebula-cert)) $(eval $(call BuildPackage,nebula-cert))
$(eval $(call BuildPackage,nebula-proto))
$(eval $(call BuildPackage,nebula-service))

View file

@ -1,52 +1,106 @@
#!/bin/sh /etc/rc.common #!/bin/sh /etc/rc.common
# Copyright 2021 Stan Grishin (stangri@melmac.ca) # Copyright 2021 Stan Grishin (stangri@melmac.ca)
# shellcheck disable=SC2039,SC3043 # shellcheck disable=SC3043,SC3060
PKG_VERSION='dev-test'
# shellcheck disable=SC2034 # shellcheck disable=SC2034
START=80 START=80
# shellcheck disable=SC2034 # shellcheck disable=SC2034
USE_PROCD=1 USE_PROCD=1
if type extra_command 1>/dev/null 2>&1; then readonly PKG_VERSION='dev-test'
extra_command 'version' 'Show version information' readonly packageName='nebula-service'
else readonly serviceName="$packageName $PKG_VERSION"
# shellcheck disable=SC2034 readonly sharedMemoryOutput="/dev/shm/$packageName-output"
EXTRA_COMMANDS='version'
fi
readonly PROG=/usr/sbin/nebula 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"; } 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() { start_instance() {
local cfg="$1" port name="${1##*/}" local config_file="$1"
port="$(grep -A2 "^listen:" "$cfg" | grep "port: " | awk '{print $2}')" 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_open_instance
procd_set_param command ${PROG} -config "${cfg}" procd_set_param command ${PROG} -config "${config_file}"
procd_set_param stderr 1 procd_set_param stderr 1
procd_set_param stdout 1 procd_set_param stdout 1
procd_set_param respawn procd_set_param respawn
procd_open_data procd_open_data
json_add_array firewall json_add_array firewall
json_add_object '' json_add_object ""
json_add_string type 'rule' json_add_string type rule
json_add_string name "Allow-$name" json_add_string name "${config_file##*/}"
json_add_string src 'wan' json_add_string src "*"
json_add_string dest_port "$port" json_add_string dest_ip "${yaml_listen_host:-0.0.0.0}"
json_add_string proto 'udp' json_add_string dest_port "${yaml_listen_port:-4242}"
json_add_string target 'ACCEPT' json_add_string proto udp
json_add_string target ACCEPT
json_close_object json_close_object
json_close_array json_close_array
procd_close_data procd_close_data
procd_close_instance procd_close_instance
output_ok
fi
} }
start_service() { start_service() {
local f local f
output "Starting $packageName instances "
for f in /etc/nebula/*.yml; do for f in /etc/nebula/*.yml; do
[ -s "$f" ] && start_instance "$f" start_instance "$f"
done done
output '\n'
} }
service_started() { procd_set_config_changed firewall; } service_started() { procd_set_config_changed firewall; }

View file

@ -0,0 +1,99 @@
#!/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
}

View file

@ -1,4 +1,8 @@
#!/bin/sh #!/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