mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-08-01 15:09:33 +08:00
172 lines
4.0 KiB
Bash
172 lines
4.0 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2023-2025 muink
|
|
#
|
|
# depends rgmac
|
|
|
|
. "${IPKG_INSTROOT}/lib/functions/network.sh"
|
|
|
|
START=99
|
|
USE_PROCD=1
|
|
# alwaysonline
|
|
[ -x "$(command -v nft)" ] && FW='fw4' || FW='fw3'
|
|
PROG='/usr/sbin/alwaysonline'
|
|
HOSTFILE='/var/hosts/alwaysonline'
|
|
USERNAME=alwaysonline
|
|
# uci
|
|
CONFIG_NAME='alwaysonline'
|
|
TYPEDSECTION='alwaysonline'
|
|
DOMAINS='domain'
|
|
|
|
config_load "$CONFIG_NAME"
|
|
|
|
|
|
find_op_ifnames() {
|
|
local ifnames ifname iface _c
|
|
|
|
ifnames="lo $($FW -q zone $($FW -q device "br-lan"))"
|
|
for _c in network_find_wan network_find_wan6; do
|
|
$_c iface 1
|
|
ifname=$($FW -q zone $($FW -q network "$iface"))
|
|
ifnames="${ifnames:+$ifnames }$ifname"
|
|
done
|
|
echo $ifnames | sed 's|\s|\n|g' | sort -u
|
|
}
|
|
|
|
gen_uhttpd_listen_ips() {
|
|
local regexp
|
|
|
|
regexp=$(find_op_ifnames | tr '\n' '|' | sed 's,^|*,,;s,|*$,,')
|
|
ip -o addr | grep -v "\bscope link\b" | sed -En -e "/^[0-9]+:\s*($regexp)\s/{s|^.*\binet6?\s+([^/]+)/.*|\1|p}" | sed '/:/{s|^|\[|;s|$|\]|}'
|
|
}
|
|
|
|
validate_section_domain() {
|
|
uci_load_validate $CONFIG_NAME $DOMAINS "$1" "$2" \
|
|
'enabled:bool:0' \
|
|
'name:hostname' \
|
|
'group:string' \
|
|
'family:or("4", "6", "both"):both' \
|
|
'overwrite:ipaddr'
|
|
}
|
|
|
|
init_hosts() {
|
|
mkdir -p "${HOSTFILE%/*}" 2>/dev/null
|
|
echo "# auto-generated config file from /etc/config/alwaysonline" > "${HOSTFILE}"
|
|
}
|
|
|
|
gen_hosts() {
|
|
[ "$2" == "0" ] || { >&2 echo "section $1 validation failed"; return 1; }
|
|
[ "$enabled" == "0" ] && return 0
|
|
|
|
local _addr4="${tun_addr4%/*}"
|
|
local _addr6="${tun_addr6%/*}"
|
|
|
|
local familys
|
|
[ "$family" == "both" ] && familys="4 6" || familys="$family"
|
|
|
|
for v in $familys; do
|
|
eval "domain_list=\"\${domain_list}\${overwrite:-\$_addr$v} \${name}\n\""
|
|
done
|
|
}
|
|
|
|
gen_eui64() {
|
|
local mac=$(rgmac)
|
|
local head=${mac:0:2}
|
|
if [ "$(( 0x$head & 2 ))" = "0" ]; then
|
|
printf "fe80::%x%s" $(( 0x$head | 2 )) "${mac:2:2}:${mac:4:2}ff:fe${mac:6:2}:${mac:8}"
|
|
else
|
|
printf "fe80::%x%s" $(( 0x$head & 0xfd )) "${mac:2:2}:${mac:4:2}ff:fe${mac:6:2}:${mac:8}"
|
|
fi
|
|
}
|
|
|
|
# set_uhttpd [host:port list]
|
|
set_uhttpd() {
|
|
local listen_http="${1:-0.0.0.0:80 [::]:80}" _v
|
|
|
|
uci -q delete uhttpd.main.listen_http
|
|
for _v in $listen_http; do
|
|
uci add_list uhttpd.main.listen_http="$_v"
|
|
done
|
|
uci commit uhttpd
|
|
}
|
|
|
|
start_instance() {
|
|
# TUN
|
|
ip tuntap add mode tun user "$USERNAME" name "$tun_name"
|
|
sleep 1s
|
|
ip link set "$tun_name" up
|
|
|
|
ip addr add "${tun_addr4}" dev "$tun_name"
|
|
ip addr add "${tun_addr6}" dev "$tun_name"
|
|
ip addr add "$(gen_eui64)/64" scope link dev "$tun_name"
|
|
|
|
procd_open_instance "$CONFIG_NAME"
|
|
procd_set_param command "$PROG" -port 80
|
|
procd_append_param command --disable-dns-server
|
|
procd_append_param command -ipv4 "${tun_addr4%/*}" -ipv6 "${tun_addr6%/*}"
|
|
procd_append_param netdev "br-lan"
|
|
procd_append_param netdev "$tun_name"
|
|
procd_set_param respawn
|
|
procd_set_param user root
|
|
procd_set_param stderr 1
|
|
procd_close_instance
|
|
}
|
|
|
|
start_service() {
|
|
local enabled tun_name tun_addr4 tun_addr6
|
|
|
|
config_get enabled global enabled 0
|
|
[ "$enabled" == "0" ] && return 1
|
|
config_get tun_name global tun_name 'awoltun0'
|
|
config_get tun_addr4 global tun_addr4 '172.25.26.1/30'
|
|
config_get tun_addr6 global tun_addr6 'fdfe:aead:2526::1/126'
|
|
config_get port global port '8083'
|
|
|
|
# DNS
|
|
init_hosts
|
|
local domain_list
|
|
config_foreach validate_section_domain "$DOMAINS" gen_hosts || return $?
|
|
sed -Ei "1a$domain_list" "$HOSTFILE"
|
|
|
|
# HTTP
|
|
/etc/init.d/uhttpd stop
|
|
set_uhttpd "$(gen_uhttpd_listen_ips | sed 's|$|:80|')"
|
|
start_instance
|
|
}
|
|
|
|
service_triggers() {
|
|
procd_add_reload_trigger "$CONFIG_NAME" 'network'
|
|
|
|
local iface=$(uci show network|grep "device='br-lan'"|cut -f2 -d'.'|head -n1)
|
|
[ -n "$iface" ] && procd_add_reload_interface_trigger "$iface"
|
|
}
|
|
|
|
reload_service() {
|
|
stop
|
|
start
|
|
}
|
|
|
|
service_started() {
|
|
# DNS
|
|
/etc/init.d/dnsmasq reload
|
|
|
|
# HTTP
|
|
/etc/init.d/uhttpd start
|
|
}
|
|
|
|
service_stopped() {
|
|
# DNS
|
|
init_hosts
|
|
/etc/init.d/dnsmasq reload
|
|
|
|
# HTTP
|
|
set_uhttpd
|
|
/etc/init.d/uhttpd restart
|
|
|
|
# TUN
|
|
local tun_name
|
|
config_get tun_name global tun_name 'awoltun0'
|
|
|
|
ip link set "$tun_name" down 2>/dev/null
|
|
ip tuntap del mode tun name "$tun_name" 2>/dev/null
|
|
}
|