b77be1254a6f5f1162726b0f09f90aed026a527a
[feed/packages.git] / net / nebula / files / nebula.proto
1 #!/bin/sh
2 # Copyright 2021-2023 Stan Grishin (stangri@melmac.ca)
3 # shellcheck disable=SC1091,SC2039,SC2034,SC3043
4 readonly PKG_VERSION='dev-test'
5 readonly PROG=/usr/sbin/nebula
6 readonly packageName='nebula-proto'
7
8 [ -x "$PROG" ] || { log "Main nebula executable '/usr/sbin/nebula' not found"; exit 1; }
9
10 [ -n "$INCLUDE_ONLY" ] || {
11 . /lib/functions.sh
12 . /lib/functions/network.sh
13 . ../netifd-proto.sh
14 init_proto "$@"
15 }
16
17 log() { logger -t "$packageName" "$*"; }
18 # https://gist.github.com/pkuczynski/8665367
19 # shellcheck disable=SC2086,SC2155
20 yaml_parse() {
21 local prefix=$2
22 local s='[[:space:]]*' w='[a-zA-Z0-9_-]*' fs="$(echo @|tr @ '\034'|tr -d '\015')"
23 sed -ne "s|^\($s\)\($w\)$s:$s\"\(.*\)\"$s\$|\1$fs\2$fs\3|p" \
24 -e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" "$1" |
25 awk "-F$fs" '{
26 indent = length($1)/2;
27 vname[indent] = $2;
28 for (i in vname) {if (i > indent) {delete vname[i]}}
29 if (length($3) > 0) {
30 vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
31 printf("%s%s%s=\"%s\"\n", "'$prefix'", vn, $2, $3);
32 }
33 }'
34 }
35
36 proto_nebula_init_config() {
37 available=1
38 no_device=1
39 proto_config_add_string "config_file"
40 }
41
42 proto_nebula_setup() {
43 local interface="$1" config_file address addresses
44 local yaml_listen_host yaml_listen_port yaml_tun_dev
45
46 config_load network
47 config_get config_file "${interface}" "config_file"
48 proto_init_update "${interface}" 1
49
50 [ -s "$config_file" ] || { log "Config file not found or empty!"; return 1; }
51 eval "$(yaml_parse "$config_file" "yaml_")"
52 [ "$yaml_tun_dev" = "$interface" ] || { log "Tunnel device in config file (${yaml_tun_dev}) doesn't match interface name (${interface})!"; return 1; }
53
54 log "Setting up ${interface} from $(basename "$config_file")."
55 proto_run_command "$interface" "$PROG" -config "$config_file"
56 # TODO: if lighthouse, open local port 4242
57 # TODO: else get local subnet from local_range variable, if not,
58 # TODO: iterate over each lighthouse/hosts and append /24
59 # TODO: ip route add "$yaml_local_range" "$yaml_tun_dev"
60 proto_add_data
61 json_add_array firewall
62 json_add_object ""
63 json_add_string type rule
64 json_add_string name "$interface"
65 json_add_string src "*"
66 json_add_string dest_ip "${yaml_listen_host:-0.0.0.0}"
67 json_add_string dest_port "${yaml_listen_port:-4242}"
68 json_add_string proto udp
69 json_add_string target ACCEPT
70 json_close_object
71 json_close_array
72 proto_close_data
73 addresses="$(ip -4 a list dev "$interface" 2>/dev/null | grep inet | awk '{print $2}' | awk -F "/" '{print $1}')"
74 log "Running ${interface} from $(basename "$config_file") with addresses: ${addresses}."
75 for address in ${addresses}; do
76 case "${address}" in
77 *:*/*)
78 proto_add_ipv6_address "${address%%/*}" "${address##*/}"
79 ;;
80 *.*/*)
81 proto_add_ipv4_address "${address%%/*}" "${address##*/}"
82 ;;
83 *:*)
84 proto_add_ipv6_address "${address%%/*}" "128"
85 ;;
86 *.*)
87 proto_add_ipv4_address "${address%%/*}" "32"
88 ;;
89 esac
90 done
91
92 proto_send_update "$interface"
93 }
94
95 proto_nebula_teardown() {
96 local interface="$1"
97 proto_kill_command "${interface}"
98 log "Killed interface ${interface}."
99 }
100
101 [ -n "$INCLUDE_ONLY" ] || {
102 add_protocol nebula
103 }