mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-14 20:34:19 +08:00
305 lines
10 KiB
Bash
305 lines
10 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2018 Dengfeng Liu
|
|
|
|
# After aw-bpf (START=98) so dns_ringbuf_portal is pinned for wildcard trust.
|
|
START=99
|
|
USE_PROCD=1
|
|
NAME=wifidogx
|
|
PROG="/usr/bin/${NAME}"
|
|
CONFIGFILE="/tmp/wifidogx.conf"
|
|
|
|
handle_gateway() {
|
|
local section="$1"
|
|
local gateway_name gateway_channel gateway_id
|
|
local gateway_subnetv4
|
|
local gateway_auth_enabled
|
|
|
|
config_get gateway_name "$section" gateway_name
|
|
config_get gateway_channel "$section" gateway_channel
|
|
config_get gateway_id "$section" gateway_id
|
|
config_get gateway_auth_enabled "$section" gateway_auth_enabled 1
|
|
|
|
|
|
if [ -z "$gateway_name" ] || [ -z "$gateway_channel" ] ; then
|
|
echo "gateway_name and gateway_channel are required for $section" >&2
|
|
return
|
|
fi
|
|
|
|
# Get gateway_id from gateway_name if not set
|
|
if [ -z "$gateway_id" ]; then
|
|
gateway_id=$(ifconfig "$gateway_name" | awk '/HWaddr/ {print toupper($5)}' | tr -d ':')
|
|
if [ -z "$gateway_id" ]; then
|
|
echo "Failed to get gateway_id for $gateway_name" >&2
|
|
return
|
|
fi
|
|
uci set wifidogx."$section".gateway_id="$gateway_id"
|
|
uci commit wifidogx
|
|
fi
|
|
# according to the gateway_name to get the subnetv4
|
|
local gateway_ipv4=$(ifconfig "$gateway_name" | awk '/inet addr:/ {print $2}' | cut -d: -f2)
|
|
local gateway_maskv4=$(ifconfig "$gateway_name" | awk '/Mask:/ {print $4}' | cut -d: -f2)
|
|
[ -z "$gateway_ipv4" ] && echo "Failed to get gateway_ipv4 for $gateway_name" >&2 && return
|
|
[ -z "$gateway_maskv4" ] && echo "Failed to get gateway_maskv4 for $gateway_name" >&2 && return
|
|
|
|
# change the gateway_ip4/gateway_maskv4 to CIDR format
|
|
local mask_bits=0
|
|
local mask_value=$(printf '%d' "0x$(echo $gateway_maskv4 | tr '.' ' ' | awk '{printf "%02x%02x%02x%02x",$1,$2,$3,$4}')")
|
|
while [ $mask_value -ne 0 ]; do
|
|
mask_bits=$((mask_bits + (mask_value & 1)))
|
|
mask_value=$((mask_value >> 1))
|
|
done
|
|
gateway_subnetv4="$gateway_ipv4/$mask_bits"
|
|
|
|
uci set wifidogx."$section".gateway_subnetv4="$gateway_subnetv4"
|
|
uci commit wifidogx
|
|
|
|
printf "GatewaySetting {\n\tGatewayAuthEnabled %s\n\tGatewayInterface %s\n\tGatewayChannel %s\n\tGatewayID %s\n\tGatewaySubnetV4 %s\n}\n" \
|
|
"${gateway_auth_enabled}" "${gateway_name}" "${gateway_channel}" "${gateway_id}" "${gateway_subnetv4}" >> "$CONFIGFILE"
|
|
}
|
|
|
|
add_white_list_entries() {
|
|
local list_type="$1"
|
|
local uci_field="$2"
|
|
local target_variable="$3"
|
|
|
|
list_type=$(uci get wifidogx.common."$list_type")
|
|
for group in $list_type; do
|
|
group_list=$(uci get wifidogx."$group"."$uci_field")
|
|
if [ -n "$group_list" ]; then
|
|
eval "$target_variable=\"\${$target_variable} \$group_list\""
|
|
fi
|
|
done
|
|
}
|
|
|
|
prepare_common_settings() {
|
|
printf "CheckInterval %s\nClientTimeout %s\nJsFilter %s\nWiredPassed %s\nBypassAppleCNA %s\n" \
|
|
"$check_interval" "$client_timeout" "$js_filter" "$wired_passed" "$apple_cna" >> "$CONFIGFILE"
|
|
|
|
printf "EnableAntiNat %s\n" "$enable_anti_nat" >> "$CONFIGFILE"
|
|
printf "TTLValues %s\n" "$ttl_values" >> "$CONFIGFILE"
|
|
printf "DisablePortalAuth %s\n" "$disable_portal_auth" >> "$CONFIGFILE"
|
|
printf "EnablePrivilegedOps %s\n" "$enable_privileged_ops" >> "$CONFIGFILE"
|
|
[ -n "$privileged_ops_secret" ] && printf "PrivilegedOpsSecret %s\n" "$privileged_ops_secret" >> "$CONFIGFILE"
|
|
|
|
[ -n "$anti_nat_permit_macs" ] && printf "AntiNatPermitMACs %s\n" "$anti_nat_permit_macs" >> "$CONFIGFILE"
|
|
|
|
process_trusted_list() {
|
|
local list="$1"
|
|
local config_name="$2"
|
|
|
|
if [ -n "$list" ]; then
|
|
# Clean up whitespace and remove duplicates
|
|
list=$(echo "$list" | sed -e 's/^[[:space:]]*//;s/[[:space:]]*$//;s/[[:space:]]\+/ /g' \
|
|
| tr ' ' '\n' | sort -u | tr '\n' ',' | sed 's/,$//')
|
|
printf "%s %s\n" "$config_name" "$list" >> "$CONFIGFILE"
|
|
fi
|
|
}
|
|
|
|
process_trusted_list "$trusted_domains" "TrustedDomains"
|
|
process_trusted_list "$trusted_macs" "TrustedMACList"
|
|
process_trusted_list "$trusted_wildcard_domains" "TrustedWildcardDomains"
|
|
}
|
|
|
|
prepare_device_info() {
|
|
# Check if any device info fields are set
|
|
if [ -n "$ap_device_id" ] || [ -n "$ap_mac_address" ] || [ -n "$ap_longitude" ] || [ -n "$ap_latitude" ] || [ -n "$location_id" ]; then
|
|
printf "DeviceInfo {\n" >> "$CONFIGFILE"
|
|
|
|
[ -n "$ap_device_id" ] && printf "\tApDeviceId %s\n" "$ap_device_id" >> "$CONFIGFILE"
|
|
[ -n "$ap_mac_address" ] && printf "\tApMacAddress %s\n" "$ap_mac_address" >> "$CONFIGFILE"
|
|
[ -n "$ap_longitude" ] && printf "\tApLongitude %s\n" "$ap_longitude" >> "$CONFIGFILE"
|
|
[ -n "$ap_latitude" ] && printf "\tApLatitude %s\n" "$ap_latitude" >> "$CONFIGFILE"
|
|
[ -n "$location_id" ] && printf "\tLocationId %s\n" "$location_id" >> "$CONFIGFILE"
|
|
|
|
printf "}\n" >> "$CONFIGFILE"
|
|
fi
|
|
}
|
|
|
|
prepare_auth_server_settings() {
|
|
# 获取选中的认证服务器配置
|
|
local selected_auth_server
|
|
selected_auth_server=$(uci get wifidogx.common.selected_auth_server 2>/dev/null)
|
|
|
|
# 如果是云认证或旁路模式,需要验证选中的认证服务器
|
|
if [ "$auth_server_mode" = "cloud" ] || [ "$auth_server_mode" = "bypass" ]; then
|
|
if [ -z "$selected_auth_server" ]; then
|
|
echo "Error: selected_auth_server is required for $auth_server_mode mode" >&2
|
|
return 1
|
|
fi
|
|
|
|
local auth_server_hostname auth_server_port auth_server_path
|
|
|
|
uci_validate_section "$NAME" "auth" "$selected_auth_server" \
|
|
'auth_server_hostname:string:192.168.1.1' \
|
|
'auth_server_port:port:80' \
|
|
'auth_server_path:string:/wifidog/'
|
|
|
|
export auth_server_hostname
|
|
export auth_server_port
|
|
export auth_server_path
|
|
fi
|
|
|
|
case "$auth_server_mode" in
|
|
cloud|bypass)
|
|
printf "AuthServerMode 0\n" >> "$CONFIGFILE"
|
|
printf "DeviceID %s\nAuthServer {\n\tHostname %s\n\tHTTPPort %s\n\tPath %s\n}\n" \
|
|
"$device_id" "$auth_server_hostname" "$auth_server_port" "$auth_server_path" >> "$CONFIGFILE"
|
|
;;
|
|
local)
|
|
printf "AuthServerMode 2\n" >> "$CONFIGFILE"
|
|
[ -n "$device_id" ] && printf "DeviceID %s\n" "$device_id" >> "$CONFIGFILE"
|
|
[ -n "$auth_server_offline_file" ] && printf "AuthServerOfflineFile %s\n" "$auth_server_offline_file" >> "$CONFIGFILE"
|
|
[ -n "$local_portal" ] && printf "LocalPortal %s\n" "$local_portal" >> "$CONFIGFILE"
|
|
;;
|
|
esac
|
|
|
|
[ -n "$internet_offline_file" ] && printf "InternetOfflineFile %s\n" "$internet_offline_file" >> "$CONFIGFILE"
|
|
}
|
|
|
|
prepare_longconn_settings() {
|
|
local long_conn_mode ws_server_hostname ws_server_port ws_server_path
|
|
local mqtt_server_hostname mqtt_server_port mqtt_username mqtt_password
|
|
local selected_long_conn
|
|
|
|
selected_long_conn=$(uci get wifidogx.common.selected_long_conn 2>/dev/null)
|
|
[ -z "$selected_long_conn" ] && return
|
|
|
|
if ! uci -q get wifidogx."$selected_long_conn" >/dev/null; then
|
|
echo "Long connection: selected section $selected_long_conn does not exist" >&2
|
|
return
|
|
fi
|
|
|
|
uci_validate_section "$NAME" "longconn" "$selected_long_conn" \
|
|
'long_conn_mode:or("ws","wss","mqtt","mqtts"):ws' \
|
|
'ws_server_hostname:string' \
|
|
'ws_server_port:port:443' \
|
|
'ws_server_path:string:/ws/wifidogx' \
|
|
'mqtt_server_hostname:string' \
|
|
'mqtt_server_port:port:1883' \
|
|
'mqtt_username:string' \
|
|
'mqtt_password:string'
|
|
|
|
case "$long_conn_mode" in
|
|
ws|wss)
|
|
if [ -z "$ws_server_hostname" ]; then
|
|
echo "Long connection: ws_server_hostname is required" >&2
|
|
return
|
|
fi
|
|
local ws_ssl
|
|
ws_ssl=$([ "$long_conn_mode" = "wss" ] && echo 1 || echo 0)
|
|
printf "WebSocket {\n\tWSServer %s\n\tWSServerPort %s\n\tWSServerPath %s\n\tWSServerSSL %s\n}\n" \
|
|
"$ws_server_hostname" "$ws_server_port" "$ws_server_path" "$ws_ssl" >> "$CONFIGFILE"
|
|
;;
|
|
mqtt|mqtts)
|
|
if [ -z "$mqtt_server_hostname" ]; then
|
|
echo "Long connection: mqtt_server_hostname is required" >&2
|
|
return
|
|
fi
|
|
local mqtt_ssl
|
|
mqtt_ssl=$([ "$long_conn_mode" = "mqtts" ] && echo 1 || echo 0)
|
|
printf "mqtt {\n\tserveraddr %s\n\tserverport %s\n\tmqttUseSSL %s\n\tmqttUsername %s\n\tmqttPassword %s\n}\n" \
|
|
"$mqtt_server_hostname" "$mqtt_server_port" "$mqtt_ssl" "${mqtt_username:-}" "${mqtt_password:-}" >> "$CONFIGFILE"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
prepare_external_interface() {
|
|
[ -z "$external_interface" ] && echo "No ExternalInterface " >&2 && return
|
|
local external_interface_name
|
|
|
|
if [ "$external_interface" = "wwan" ]; then
|
|
external_interface_name=$(ubus call network.interface."$external_interface" status | jsonfilter -e '@.device')
|
|
else
|
|
external_interface_name=$(uci get network."$external_interface".device)
|
|
fi
|
|
|
|
[ -z "$external_interface_name" ] && echo "Failed to get device name for $external_interface" >&2 && return
|
|
|
|
printf "ExternalInterface %s\n" "$external_interface_name" >> "$CONFIGFILE"
|
|
}
|
|
|
|
prepare_wifidog_conf() {
|
|
[ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE"
|
|
local auth_server_mode_value='"cloud", "bypass", "local"'
|
|
|
|
# 获取选中的认证服务器
|
|
local selected_auth_server
|
|
selected_auth_server=$(uci get wifidogx.common.selected_auth_server 2>/dev/null)
|
|
|
|
|
|
uci_validate_section "$NAME" "$NAME" common \
|
|
'enabled:bool:0' \
|
|
"auth_server_mode:or($auth_server_mode_value)" \
|
|
'selected_auth_server:string' \
|
|
'selected_long_conn:string' \
|
|
'log_level:integer:7' \
|
|
'device_id:string' \
|
|
'check_interval:integer:60' \
|
|
'client_timeout:integer:5' \
|
|
'wired_passed:bool:1' \
|
|
'apple_cna:bool:0' \
|
|
'trusted_domains:list(host)' \
|
|
'trusted_wildcard_domains:list(string)' \
|
|
'trusted_macs:list(string)' \
|
|
'app_white_list:list(string)' \
|
|
'mac_white_list:list(string)' \
|
|
'wildcard_white_list:list(string)' \
|
|
'js_filter:bool:1' \
|
|
'auth_server_offline_file:string' \
|
|
'internet_offline_file:string' \
|
|
'local_portal:string' \
|
|
'external_interface:string' \
|
|
'enable_anti_nat:bool:0' \
|
|
'enable_privileged_ops:bool:0' \
|
|
'privileged_ops_secret:string:chawrt@2026' \
|
|
'ttl_values:string:64,128' \
|
|
'anti_nat_permit_macs:string' \
|
|
'disable_portal_auth:bool:1' \
|
|
'ap_device_id:string' \
|
|
'ap_mac_address:string' \
|
|
'ap_longitude:string' \
|
|
'ap_latitude:string' \
|
|
'location_id:string'
|
|
|
|
[ -n "$app_white_list" ] && add_white_list_entries "app_white_list" "domain_name" "trusted_domains"
|
|
[ -n "$mac_white_list" ] && add_white_list_entries "mac_white_list" "mac_address" "trusted_macs"
|
|
[ -n "$wildcard_white_list" ] && add_white_list_entries "wildcard_white_list" "wildcard_domain" "trusted_wildcard_domains"
|
|
|
|
prepare_external_interface
|
|
prepare_auth_server_settings
|
|
prepare_longconn_settings
|
|
prepare_device_info
|
|
config_foreach handle_gateway gateway
|
|
prepare_common_settings
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "wifidogx"
|
|
}
|
|
|
|
start_service() {
|
|
config_load "$NAME"
|
|
|
|
prepare_wifidog_conf
|
|
|
|
if [ "$enabled" -eq 0 ]; then
|
|
echo "wifidogx is disabled, exit..." >&2
|
|
return
|
|
fi
|
|
|
|
procd_open_instance
|
|
procd_set_param command "$PROG" -c "$CONFIGFILE" -s -f -d "$log_level"
|
|
procd_set_param respawn
|
|
procd_set_param file /etc/config/wifidogx
|
|
procd_close_instance
|
|
}
|
|
|
|
status_service() {
|
|
/usr/bin/wdctlx status
|
|
}
|
|
|
|
reload_service() {
|
|
stop
|
|
start
|
|
}
|