stubby: add uci support to init file
[feed/packages.git] / net / stubby / files / stubby.init
old mode 100644 (file)
new mode 100755 (executable)
index 19743f1..af75770
@@ -5,19 +5,212 @@ USE_PROCD=1
 START=50
 STOP=51
 
-PROG=/usr/sbin/stubby
+PROG="/usr/sbin/stubby"
+
+stubby="/usr/sbin/stubby"
+stubby_init="/etc/init.d/stubby"
+stubby_config_dir="/var/etc/stubby"
+stubby_config="$stubby_config_dir/stubby.yml"
+stubby_pid_file="/var/run/stubby.pid"
+stubby_manual_config="/etc/stubby/stubby.yml"
+
+boot()
+{
+    stubby_boot=1
+    rc_procd start_service
+}
+
+generate_config()
+{
+    local config_file="$1"
+    local round_robin
+    local tls_authentication
+    local tls_query_padding_blocksize
+    local edns_client_subnet_private
+    local idle_timeout
+    local appdata_dir
+    local tls_connection_retries
+    local tls_backoff_time
+    local timeout
+    local dnssec_return_status
+    local dnssec_trust_anchors
+    local listen_addresses_section=0
+    local dns_transport_list_section=0
+    local upstream_recursive_servers_section=0
+    local stubby_args
+    local command_line_arguments
+    local log_level
+
+    # Generate configuration. See: https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example
+    echo "# Autogenerated configuration from uci data" > "$config_file"
+    echo "resolution_type: GETDNS_RESOLUTION_STUB" >> "$config_file"
+
+    config_get round_robin "global" round_robin_upstreams "1"
+    echo "round_robin_upstreams: $round_robin" >> "$config_file"
+
+    config_get appdata_dir "global" appdata_dir "/var/lib/stubby"
+    echo "appdata_dir: \"$appdata_dir\"" >> "$config_file"
+
+    config_get tls_connection_retries "global" tls_connection_retries ""
+    if [ -n "$tls_connection_retries" ]; then
+        echo "tls_connection_retries: $tls_connection_retries" >> "$config_file"
+    fi
+
+    config_get tls_backoff_time "global" tls_backoff_time ""
+    if [ -n "$tls_backoff_time" ]; then
+        echo "tls_backoff_time: $tls_backoff_time" >> "$config_file"
+    fi
+
+    config_get timeout "global" timeout ""
+    if [ -n "$timeout" ]; then
+        echo "timeout: $timeout" >> "$config_file"
+    fi
+
+    config_get_bool tls_authentication "global" tls_authentication "1"
+    if [ "$tls_authentication" = "1" ]; then
+        echo "tls_authentication: GETDNS_AUTHENTICATION_REQUIRED" >> "$config_file"
+    else
+        echo "tls_authentication: GETDNS_AUTHENTICATION_NONE" >> "$config_file"
+    fi
+
+    config_get_bool dnssec_return_status "global" dnssec_return_status "0"
+    if [ "$dnssec_return_status" = "1" ]; then
+        echo "dnssec_return_status: GETDNS_EXTENSION_TRUE" >> "$config_file"
+    fi
+
+    config_get dnssec_trust_anchors "global" dnssec_trust_anchors ""
+    if [ -n "$dnssec_trust_anchors" ]; then
+        echo "dnssec_trust_anchors: \"$dnssec_trust_anchors\"" >> "$config_file"
+    fi
+
+    config_get tls_query_padding_blocksize "global" tls_query_padding_blocksize "128"
+    echo "tls_query_padding_blocksize: $tls_query_padding_blocksize" >> "$config_file"
+
+    config_get_bool edns_client_subnet_private "global" edns_client_subnet_private "1"
+    echo "edns_client_subnet_private: $edns_client_subnet_private" >> "$config_file"
+
+    config_get idle_timeout "global" idle_timeout "10000"
+    echo "idle_timeout: $idle_timeout" >> "$config_file"
+
+    handle_listen_address_value()
+    {
+        local value="$1"
+
+        if [ "$listen_addresses_section" = 0 ]; then
+            echo "listen_addresses:" >> "$config_file"
+            listen_addresses_section=1
+        fi
+        echo "  - $value" >> "$config_file"
+    }
+    config_list_foreach "global" listen_address handle_listen_address_value
+
+    handle_dns_transport_list_value()
+    {
+        local value="$1"
+
+        if [ "$dns_transport_list_section" = 0 ]; then
+            echo "dns_transport_list:" >> "$config_file"
+            dns_transport_list_section=1
+        fi
+        echo "  - $value" >> "$config_file"
+    }
+    config_list_foreach "global" dns_transport handle_dns_transport_list_value
+
+    handle_resolver()
+    {
+        local config=$1
+        local address
+        local tls_auth_name
+        local spki
+        local tls_pubkey_pinset_section=0
+
+        if [ "$upstream_recursive_servers_section" = 0 ]; then
+            echo "upstream_recursive_servers:" >> "$config_file"
+            upstream_recursive_servers_section=1
+        fi
+        config_get address "$config" address
+        config_get tls_auth_name "$config" tls_auth_name
+        echo "  - address_data: $address" >> "$config_file"
+        echo "    tls_auth_name: \"$tls_auth_name\"" >> "$config_file"
+
+        handle_resolver_spki()
+        {
+            local val="$1"
+            local digest="${val%/*}"
+            local value="${val#*/}"
+
+            if [ "$tls_pubkey_pinset_section" = 0 ]; then
+                echo "    tls_pubkey_pinset:" >> "$config_file"
+                tls_pubkey_pinset_section=1
+            fi
+            echo "      - digest: \"$digest\"" >> "$config_file"
+            echo "        value: $value" >> "$config_file"
+        }
+        config_list_foreach "$config" spki handle_resolver_spki
+    }
+
+    config_foreach handle_resolver resolver
+}
 
 start_service() {
-  procd_open_instance stubby
-  procd_set_param command /usr/sbin/stubby
+    local config_file_tmp
+    local manual
+    local log_level
+    local command_line_arguments
+    local stubby_args
+
+    mkdir -p "$stubby_config_dir"
+
+    config_load "stubby"
 
-  procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+    config_get_bool manual "global" manual "0"
 
-  procd_set_param file /etc/stubby/stubby.yml
+    if [ "$manual" = "1" ]; then
+        cp "$stubby_manual_config" "$stubby_config"
+    else
+        config_file_tmp="$stubby_config.$$"
+        generate_config "$config_file_tmp"
+        mv "$config_file_tmp" "$stubby_config"
+    fi
 
-  procd_set_param stdout 1
-  procd_set_param stderr 1
-  procd_set_param user stubby
-  procd_close_instance
+    stubby_args=""
+    config_get command_line_arguments "global" command_line_arguments ""
+    if [ -n "$command_line_arguments" ]; then
+        stubby_args="$command_line_arguments"
+    fi
+
+    config_get log_level "global" log_level ""
+    if [ -n "$log_level" ]; then
+        stubby_args="$stubby_args -v$log_level"
+    fi
+
+    if [ $("${stubby_init}" enabled; printf "%u" ${?}) -eq 0 ]; then
+        if [ -n "${stubby_boot}" ]; then
+            local trigger="$(uci_get stubby global trigger)"
+            if [ "${trigger}" != "timed" ]; then
+                return 0
+            fi
+        fi
+        procd_open_instance "stubby"
+        procd_set_param command "$stubby" "$stubby_args" -C "$stubby_config"
+        procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5}
+        procd_set_param file "$stubby_config"
+        procd_set_param stdout 1
+        procd_set_param stderr 1
+        procd_set_param pidfile "$stubby_pid_file"
+        procd_set_param user stubby
+        procd_close_instance
+    fi
 }
 
+service_triggers()
+{
+    local trigger="$(uci_get stubby global trigger)"
+    local delay="$(uci_get stubby global triggerdelay "2")"
+
+    if [ "${trigger}" != "none" ] && [ "${trigger}" != "timed" ]; then
+        PROCD_RELOAD_DELAY=$((${delay:-2} * 1000))
+        procd_add_interface_trigger "interface.*.up" "${trigger}" "${stubby_init}" start
+    fi
+    procd_add_reload_trigger "stubby"
+}