| b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame] | 1 | #!/bin/sh /etc/rc.common | 
|  | 2 |  | 
|  | 3 | USE_PROCD=1 | 
|  | 4 |  | 
|  | 5 | START=30 | 
|  | 6 | STOP=51 | 
|  | 7 |  | 
|  | 8 | stubby="/usr/sbin/stubby" | 
|  | 9 | stubby_init="/etc/init.d/stubby" | 
|  | 10 | stubby_config_dir="/var/etc/stubby" | 
|  | 11 | stubby_config="$stubby_config_dir/stubby.yml" | 
|  | 12 | stubby_pid_file="/var/run/stubby.pid" | 
|  | 13 | stubby_manual_config="/etc/stubby/stubby.yml" | 
|  | 14 |  | 
|  | 15 | boot() | 
|  | 16 | { | 
|  | 17 | stubby_boot=1 | 
|  | 18 | rc_procd start_service | 
|  | 19 | } | 
|  | 20 |  | 
|  | 21 | generate_config() | 
|  | 22 | { | 
|  | 23 | local round_robin | 
|  | 24 | local tls_authentication | 
|  | 25 | local tls_query_padding_blocksize | 
|  | 26 | local edns_client_subnet_private | 
|  | 27 | local idle_timeout | 
|  | 28 | local appdata_dir | 
|  | 29 | local trust_anchors_backoff_time | 
|  | 30 | local tls_connection_retries | 
|  | 31 | local tls_backoff_time | 
|  | 32 | local timeout | 
|  | 33 | local dnssec_return_status | 
|  | 34 | local dnssec_trust_anchors | 
|  | 35 | local listen_addresses_section=0 | 
|  | 36 | local dns_transport_list_section=0 | 
|  | 37 | local upstream_recursive_servers_section=0 | 
|  | 38 | local command_line_arguments | 
|  | 39 | local log_level | 
|  | 40 | local tls_cipher_list | 
|  | 41 | local tls_ciphersuites | 
|  | 42 | local tls_min_version | 
|  | 43 | local tls_max_version | 
|  | 44 |  | 
|  | 45 | # Generate configuration. See: https://github.com/getdnsapi/stubby/blob/develop/stubby.yml.example | 
|  | 46 | echo "# Autogenerated configuration from uci data" | 
|  | 47 | echo "resolution_type: GETDNS_RESOLUTION_STUB" | 
|  | 48 |  | 
|  | 49 | config_get round_robin "global" round_robin_upstreams "1" | 
|  | 50 | echo "round_robin_upstreams: $round_robin" | 
|  | 51 |  | 
|  | 52 | config_get appdata_dir "global" appdata_dir "/var/lib/stubby" | 
|  | 53 | echo "appdata_dir: \"$appdata_dir\"" | 
|  | 54 |  | 
|  | 55 | config_get trust_anchors_backoff_time "global" trust_anchors_backoff_time "2500" | 
|  | 56 | echo "trust_anchors_backoff_time: $trust_anchors_backoff_time" | 
|  | 57 |  | 
|  | 58 | config_get tls_connection_retries "global" tls_connection_retries "" | 
|  | 59 | if [ -n "$tls_connection_retries" ]; then | 
|  | 60 | echo "tls_connection_retries: $tls_connection_retries" | 
|  | 61 | fi | 
|  | 62 |  | 
|  | 63 | config_get tls_backoff_time "global" tls_backoff_time "" | 
|  | 64 | if [ -n "$tls_backoff_time" ]; then | 
|  | 65 | echo "tls_backoff_time: $tls_backoff_time" | 
|  | 66 | fi | 
|  | 67 |  | 
|  | 68 | config_get timeout "global" timeout "" | 
|  | 69 | if [ -n "$timeout" ]; then | 
|  | 70 | echo "timeout: $timeout" | 
|  | 71 | fi | 
|  | 72 |  | 
|  | 73 | config_get_bool tls_authentication "global" tls_authentication "1" | 
|  | 74 | if [ "$tls_authentication" = "1" ]; then | 
|  | 75 | echo "tls_authentication: GETDNS_AUTHENTICATION_REQUIRED" | 
|  | 76 | else | 
|  | 77 | echo "tls_authentication: GETDNS_AUTHENTICATION_NONE" | 
|  | 78 | fi | 
|  | 79 |  | 
|  | 80 | config_get_bool dnssec_return_status "global" dnssec_return_status "0" | 
|  | 81 | if [ "$dnssec_return_status" = "1" ]; then | 
|  | 82 | echo "dnssec_return_status: GETDNS_EXTENSION_TRUE" | 
|  | 83 | fi | 
|  | 84 |  | 
|  | 85 | config_get dnssec_trust_anchors "global" dnssec_trust_anchors "" | 
|  | 86 | if [ -n "$dnssec_trust_anchors" ]; then | 
|  | 87 | echo "dnssec_trust_anchors: \"$dnssec_trust_anchors\"" | 
|  | 88 | fi | 
|  | 89 |  | 
|  | 90 | config_get tls_query_padding_blocksize "global" tls_query_padding_blocksize "128" | 
|  | 91 | echo "tls_query_padding_blocksize: $tls_query_padding_blocksize" | 
|  | 92 |  | 
|  | 93 | config_get_bool edns_client_subnet_private "global" edns_client_subnet_private "1" | 
|  | 94 | echo "edns_client_subnet_private: $edns_client_subnet_private" | 
|  | 95 |  | 
|  | 96 | config_get idle_timeout "global" idle_timeout "10000" | 
|  | 97 | echo "idle_timeout: $idle_timeout" | 
|  | 98 |  | 
|  | 99 | config_get tls_cipher_list "global" tls_cipher_list "" | 
|  | 100 | if [ -n "$tls_cipher_list" ]; then | 
|  | 101 | echo "tls_cipher_list: \"$tls_cipher_list\"" | 
|  | 102 | fi | 
|  | 103 |  | 
|  | 104 | config_get tls_ciphersuites "global" tls_ciphersuites "" | 
|  | 105 | if [ -n "$tls_ciphersuites" ]; then | 
|  | 106 | echo "tls_ciphersuites: \"$tls_ciphersuites\"" | 
|  | 107 | fi | 
|  | 108 |  | 
|  | 109 | config_get tls_min_version "global" tls_min_version "" | 
|  | 110 | if [ -n "$tls_min_version" ]; then | 
|  | 111 | echo "tls_min_version: GETDNS_TLS${tls_min_version/\./_}" | 
|  | 112 | fi | 
|  | 113 |  | 
|  | 114 | config_get tls_max_version "global" tls_max_version "" | 
|  | 115 | if [ -n "$tls_max_version" ]; then | 
|  | 116 | echo "tls_max_version: GETDNS_TLS${tls_max_version/\./_}" | 
|  | 117 | fi | 
|  | 118 |  | 
|  | 119 | handle_listen_address_value() | 
|  | 120 | { | 
|  | 121 | local value="$1" | 
|  | 122 |  | 
|  | 123 | if [ "$listen_addresses_section" = 0 ]; then | 
|  | 124 | echo "listen_addresses:" | 
|  | 125 | listen_addresses_section=1 | 
|  | 126 | fi | 
|  | 127 | echo "  - $value" | 
|  | 128 | } | 
|  | 129 | config_list_foreach "global" listen_address handle_listen_address_value | 
|  | 130 |  | 
|  | 131 | handle_dns_transport_list_value() | 
|  | 132 | { | 
|  | 133 | local value="$1" | 
|  | 134 |  | 
|  | 135 | if [ "$dns_transport_list_section" = 0 ]; then | 
|  | 136 | echo "dns_transport_list:" | 
|  | 137 | dns_transport_list_section=1 | 
|  | 138 | fi | 
|  | 139 | echo "  - $value" | 
|  | 140 | } | 
|  | 141 | config_list_foreach "global" dns_transport handle_dns_transport_list_value | 
|  | 142 |  | 
|  | 143 | handle_resolver() | 
|  | 144 | { | 
|  | 145 | local config=$1 | 
|  | 146 | local address | 
|  | 147 | local tls_auth_name | 
|  | 148 | local tls_port | 
|  | 149 | local tls_pubkey_pinset_section=0 | 
|  | 150 | local tls_cipher_list | 
|  | 151 | local tls_ciphersuites | 
|  | 152 | local tls_min_version | 
|  | 153 | local tls_max_version | 
|  | 154 |  | 
|  | 155 | if [ "$upstream_recursive_servers_section" = 0 ]; then | 
|  | 156 | echo "upstream_recursive_servers:" | 
|  | 157 | upstream_recursive_servers_section=1 | 
|  | 158 | fi | 
|  | 159 | config_get address "$config" address | 
|  | 160 | echo "  - address_data: $address" | 
|  | 161 |  | 
|  | 162 | config_get tls_auth_name "$config" tls_auth_name | 
|  | 163 | echo "    tls_auth_name: \"$tls_auth_name\"" | 
|  | 164 |  | 
|  | 165 | config_get tls_port "$config" tls_port "" | 
|  | 166 | if [ -n "$tls_port" ]; then | 
|  | 167 | echo "    tls_port: $tls_port" | 
|  | 168 | fi | 
|  | 169 |  | 
|  | 170 | config_get tls_cipher_list "$config" tls_cipher_list "" | 
|  | 171 | if [ -n "$tls_cipher_list" ]; then | 
|  | 172 | echo "    tls_cipher_list: \"$tls_cipher_list\"" | 
|  | 173 | fi | 
|  | 174 |  | 
|  | 175 | config_get tls_ciphersuites "$config" tls_ciphersuites "" | 
|  | 176 | if [ -n "$tls_ciphersuites" ]; then | 
|  | 177 | echo "    tls_ciphersuites: \"$tls_ciphersuites\"" | 
|  | 178 | fi | 
|  | 179 |  | 
|  | 180 | config_get tls_min_version "$config" tls_min_version "" | 
|  | 181 | if [ -n "$tls_min_version" ]; then | 
|  | 182 | echo "    tls_min_version: GETDNS_TLS${tls_min_version/\./_}" | 
|  | 183 | fi | 
|  | 184 |  | 
|  | 185 | config_get tls_max_version "$config" tls_max_version "" | 
|  | 186 | if [ -n "$tls_max_version" ]; then | 
|  | 187 | echo "    tls_max_version: GETDNS_TLS${tls_max_version/\./_}" | 
|  | 188 | fi | 
|  | 189 |  | 
|  | 190 | handle_resolver_spki() | 
|  | 191 | { | 
|  | 192 | local val="$1" | 
|  | 193 | local digest="${val%%/*}" | 
|  | 194 | local value="${val#*/}" | 
|  | 195 |  | 
|  | 196 | if [ "$tls_pubkey_pinset_section" = 0 ]; then | 
|  | 197 | echo "    tls_pubkey_pinset:" | 
|  | 198 | tls_pubkey_pinset_section=1 | 
|  | 199 | fi | 
|  | 200 | echo "      - digest: \"$digest\"" | 
|  | 201 | echo "        value: $value" | 
|  | 202 | } | 
|  | 203 | config_list_foreach "$config" spki handle_resolver_spki | 
|  | 204 | } | 
|  | 205 |  | 
|  | 206 | config_foreach handle_resolver resolver | 
|  | 207 | } > "$config_file_tmp" | 
|  | 208 |  | 
|  | 209 | start_service() { | 
|  | 210 | local config_file_tmp | 
|  | 211 | local manual | 
|  | 212 | local log_level | 
|  | 213 | local command_line_arguments | 
|  | 214 |  | 
|  | 215 | mkdir -p "$stubby_config_dir" | 
|  | 216 |  | 
|  | 217 | config_load "stubby" | 
|  | 218 |  | 
|  | 219 | config_get_bool manual "global" manual "0" | 
|  | 220 |  | 
|  | 221 | if [ "$manual" = "1" ]; then | 
|  | 222 | cp "$stubby_manual_config" "$stubby_config" | 
|  | 223 | else | 
|  | 224 | config_file_tmp="$stubby_config.$$" | 
|  | 225 | generate_config | 
|  | 226 | mv "$config_file_tmp" "$stubby_config" | 
|  | 227 | fi | 
|  | 228 | chown stubby:stubby "$stubby_config" | 
|  | 229 | chmod 0400 "$stubby_config" | 
|  | 230 |  | 
|  | 231 | config_get command_line_arguments "global" command_line_arguments "" | 
|  | 232 |  | 
|  | 233 | config_get log_level "global" log_level "" | 
|  | 234 |  | 
|  | 235 | if [ "$("$stubby_init" enabled; printf "%u" $?)" -eq 0 ]; then | 
|  | 236 | if [ -n "$stubby_boot" ]; then | 
|  | 237 | local trigger | 
|  | 238 | trigger="$(uci_get stubby global trigger)" | 
|  | 239 | if [ "$trigger" != "timed" ]; then | 
|  | 240 | return 0 | 
|  | 241 | fi | 
|  | 242 | fi | 
|  | 243 | procd_open_instance "stubby" | 
|  | 244 | procd_set_param command "$stubby" -C "$stubby_config" | 
|  | 245 | if [ -n "$log_level" ]; then | 
|  | 246 | procd_append_param command -v "$log_level" | 
|  | 247 | fi | 
|  | 248 | if [ -n "$command_line_arguments" ]; then | 
|  | 249 | procd_append_param command "$command_line_arguments" | 
|  | 250 | fi | 
|  | 251 | procd_set_param respawn | 
|  | 252 | procd_set_param file "$stubby_config" | 
|  | 253 | procd_set_param stdout 1 | 
|  | 254 | procd_set_param stderr 1 | 
|  | 255 | procd_set_param pidfile "$stubby_pid_file" | 
|  | 256 | procd_set_param user stubby | 
|  | 257 | procd_close_instance | 
|  | 258 | fi | 
|  | 259 | } | 
|  | 260 |  | 
|  | 261 | service_triggers() | 
|  | 262 | { | 
|  | 263 | local trigger | 
|  | 264 | local delay | 
|  | 265 |  | 
|  | 266 | trigger="$(uci_get stubby global trigger)" | 
|  | 267 | delay="$(uci_get stubby global triggerdelay "2")" | 
|  | 268 |  | 
|  | 269 | PROCD_RELOAD_DELAY=$((${delay:-2} * 1000)) | 
|  | 270 |  | 
|  | 271 | for trigger_item in $trigger | 
|  | 272 | do | 
|  | 273 | procd_add_interface_trigger "interface.*.up" "$trigger_item" "$stubby_init" start | 
|  | 274 | done | 
|  | 275 |  | 
|  | 276 | procd_add_reload_trigger "stubby" | 
|  | 277 | } |