Adapting the Scripts
This commit is contained in:
@@ -7,7 +7,7 @@ service_path="/data/adb/box/scripts/box.service"
|
||||
iptables_path="/data/adb/box/scripts/box.iptables"
|
||||
data_box="/data/adb/box"
|
||||
run_path="/data/adb/box/run"
|
||||
now=$(date +"%R")
|
||||
now=$(date +"%I:%M %p")
|
||||
|
||||
events=$1
|
||||
monitor_dir=$2
|
||||
|
||||
@@ -5,17 +5,17 @@ scripts_dir=$(dirname "${scripts}")
|
||||
source /data/adb/box/settings.ini
|
||||
|
||||
# Variabel yang digunakan
|
||||
table="223"
|
||||
fwmark="223"
|
||||
pref="100"
|
||||
table='0x69'
|
||||
fwmark='0x69'
|
||||
pref='0x64'
|
||||
# disable / enable quic using iptables rules
|
||||
quic="enable"
|
||||
|
||||
# Looking for value from "fake-ip-range: / listen: / enhanced-mode: / tun-device:" block in YAML / JSON configuration file
|
||||
case "${bin_name}" in
|
||||
"clash")
|
||||
clash_fake_ip_range=$(busybox awk '!/^ *#/ && /fake-ip-range:/ { print $2; found=1; exit } END { if (!found) print "198.18.0.1/16" }' "${clash_config}" 2>/dev/null)
|
||||
clash_enhanced_mode=$(busybox awk '!/^ *#/ && /enhanced-mode: / { print $2;found=1; exit } END{ if(!found) print "fake-ip" }' "${clash_config}" 2>/dev/null)
|
||||
fake_ip_range=$(busybox awk '!/^ *#/ && /fake-ip-range:/ { print $2; found=1; exit } END { if (!found) print "198.18.0.1/16" }' "${clash_config}" 2>/dev/null)
|
||||
clash_dns_port=$(busybox awk '!/^ *#/ && /listen:/ { split($0, arr, ":"); print arr[3]; found=1; exit } END{ if(!found) print "1053" }' "${clash_config}" 2>/dev/null)
|
||||
if [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
tun_device=$(busybox awk '!/^ *#/ && /device: / { print $2;found=1; exit } END{ if(!found) print "utun" }' "${clash_config}" 2>/dev/null)
|
||||
@@ -28,15 +28,17 @@ case "${bin_name}" in
|
||||
tun_device="tun0"
|
||||
fi
|
||||
fi
|
||||
fake_ip_range=$(find ${box_dir}/sing-box/ -type f -name "*.json" -exec busybox awk -F'"' '/inet4_range/ {print $4}' {} \;)
|
||||
fake_ip6_range=$(find ${box_dir}/sing-box/ -type f -name "*.json" -exec busybox awk -F'"' '/inet6_range/ {print $4}' {} \;)
|
||||
;;
|
||||
"xray" | "v2fly")
|
||||
if [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
log error "$bin_name does not support proxy_mode: tun or network_mode: mixed"
|
||||
log Error "$bin_name does not support proxy_mode: tun or network_mode: mixed"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -44,12 +46,15 @@ esac
|
||||
misc_info() {
|
||||
case "${bin_name}" in
|
||||
clash)
|
||||
log debug "enhanced-mode: $clash_enhanced_mode, fake-ip-range: $clash_fake_ip_range, listen-port: $clash_dns_port"
|
||||
log Debug "enhanced-mode: $clash_enhanced_mode, fake-ip-range: $fake_ip_range, listen-port: $clash_dns_port"
|
||||
;;
|
||||
clash|sing-box)
|
||||
if [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
log info "tun_device: $tun_device"
|
||||
log Info "tun_device: $tun_device"
|
||||
fi
|
||||
[ -n "${fake_ip_range}" ] && {
|
||||
log Debug "fakeip inet4(6)_range: ${fake_ip_range}, ${fake_ip6_range}"
|
||||
}
|
||||
;;
|
||||
*)
|
||||
true
|
||||
@@ -58,11 +63,10 @@ misc_info() {
|
||||
}
|
||||
|
||||
box_sync_port() {
|
||||
sleep 0.5
|
||||
if [[ "${network_mode}" == "tproxy" && "${proxy_mode}" != "tun" ]]; then
|
||||
netstat -tnulp | grep -q "${tproxy_port}" || log warn "tproxy_port: ${tproxy_port} out of sync with config"
|
||||
netstat -tnulp | grep -q "${tproxy_port}" || log Warning "tproxy_port: ${tproxy_port} out of sync with config"
|
||||
elif [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
ifconfig | grep -q "${tun_device}" || log warn "tun_device: '${tun_device}' not found"
|
||||
ifconfig | grep -q "${tun_device}" || log Warning "tun_device: '${tun_device}' not found"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -74,9 +78,9 @@ find_packages_uid() {
|
||||
}
|
||||
|
||||
probe_user_group() {
|
||||
if bin_pid=$(busybox pidof ${bin_name}) ; then
|
||||
box_user=$(stat -c %U /proc/"${bin_pid}")
|
||||
box_group=$(stat -c %G /proc/"${bin_pid}")
|
||||
if PID=$(busybox pidof ${bin_name}) ; then
|
||||
box_user=$(stat -c %U /proc/$PID)
|
||||
box_group=$(stat -c %G /proc/$PID)
|
||||
return 0
|
||||
else
|
||||
IFS=':' read -r box_user box_group <<< "${box_user_group}"
|
||||
@@ -152,14 +156,20 @@ start_redirect() {
|
||||
if [ "${bin_name}" = "clash" ]; then
|
||||
${iptables} -t nat -A BOX_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}"
|
||||
${iptables} -t nat -A BOX_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}"
|
||||
if [ "${clash_enhanced_mode}" = "fake-ip" ] ; then
|
||||
${iptables} -t nat -A BOX_EXTERNAL -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -A BOX_LOCAL -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
# else
|
||||
# Other types of inbound should be added here to receive DNS traffic instead of sniffing
|
||||
# ${iptables} -t nat -A BOX_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}"
|
||||
# ${iptables} -t nat -A BOX_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}"
|
||||
|
||||
# Other types of inbound should be added here to receive DNS traffic instead of sniffing
|
||||
# ${iptables} -t nat -A BOX_EXTERNAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}"
|
||||
# ${iptables} -t nat -A BOX_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${redir_port}"
|
||||
fi
|
||||
|
||||
# Fix ICMP (ping)
|
||||
# This does not guarantee that the ping result is valid
|
||||
# Just that it returns a result
|
||||
# "--to-destination" can be set to a reachable address.
|
||||
|
||||
if [ -n "${fake_ip_range}" ]; then
|
||||
${iptables} -t nat -A BOX_EXTERNAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -A BOX_LOCAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
|
||||
# Allow access to intranet subnets
|
||||
@@ -174,7 +184,7 @@ start_redirect() {
|
||||
for ap in "${ap_list[@]}"; do
|
||||
${iptables} -t nat -A BOX_EXTERNAL -p tcp -i "${ap}" -j REDIRECT --to-ports "${redir_port}"
|
||||
done
|
||||
log info "${ap_list[*]} transparent proxy."
|
||||
log Info "${ap_list[*]} transparent proxy."
|
||||
fi
|
||||
|
||||
${iptables} -t nat -I PREROUTING -j BOX_EXTERNAL
|
||||
@@ -185,7 +195,7 @@ start_redirect() {
|
||||
for ignore in "${ignore_out_list[@]}"; do
|
||||
${iptables} -t nat -I BOX_LOCAL -o "${ignore}" -j RETURN
|
||||
done
|
||||
log info "${ignore_out_list[*]} ignore transparent proxy."
|
||||
log Info "${ignore_out_list[*]} ignore transparent proxy."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -197,7 +207,7 @@ start_redirect() {
|
||||
if [ -z "$(cat "${uid_list[@]}")" ] ; then
|
||||
# Route Everything
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -j REDIRECT --to-ports "${redir_port}"
|
||||
log info "Transparent proxy for all apps."
|
||||
log Info "Transparent proxy for all apps."
|
||||
else
|
||||
# Bypass apps
|
||||
# loop through the UID list
|
||||
@@ -211,13 +221,13 @@ start_redirect() {
|
||||
|
||||
# Allow !app
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -j REDIRECT --to-ports "${redir_port}"
|
||||
log info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] no transparent proxy."
|
||||
log Info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] no transparent proxy."
|
||||
fi
|
||||
elif [ "${proxy_mode}" = "whitelist" ]; then
|
||||
if [ -z "$(cat "${uid_list[@]}")" ] ; then
|
||||
# Route Everything
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -j REDIRECT --to-ports "${redir_port}"
|
||||
log info "Transparent proxy for all apps."
|
||||
log Info "Transparent proxy for all apps."
|
||||
else
|
||||
# Route apps to Box
|
||||
# loop through the UID list
|
||||
@@ -231,12 +241,12 @@ start_redirect() {
|
||||
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -m owner --uid-owner 0 -j REDIRECT --to-ports "${redir_port}"
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -m owner --uid-owner 1052 -j REDIRECT --to-ports "${redir_port}"
|
||||
log info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] transparent proxy."
|
||||
log Info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] transparent proxy."
|
||||
fi
|
||||
else
|
||||
log warn "proxy-mode: ${proxy_mode} < error."
|
||||
log Warning "proxy-mode: ${proxy_mode} < error."
|
||||
${iptables} -t nat -A BOX_LOCAL -p tcp -j REDIRECT --to-ports "${redir_port}"
|
||||
log info "Transparent proxy for all apps."
|
||||
log Info "Transparent proxy for all apps."
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -266,8 +276,10 @@ stop_redirect() {
|
||||
fi
|
||||
|
||||
if [ "${iptables}" != "ip6tables -w 64" ]; then
|
||||
${iptables} -t nat -D BOX_EXTERNAL -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -D BOX_LOCAL -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
if [ -n "${fake_ip_range}" ]; then
|
||||
${iptables} -t nat -D BOX_EXTERNAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -D BOX_LOCAL -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
|
||||
${iptables} -t nat -F BOX_EXTERNAL
|
||||
${iptables} -t nat -X BOX_EXTERNAL
|
||||
@@ -340,7 +352,7 @@ start_tproxy() {
|
||||
# add iptables rules for UDP traffic
|
||||
${iptables} -t mangle -A BOX_EXTERNAL -p udp -i "${ap}" -j TPROXY --on-port "${tproxy_port}" --tproxy-mark "${fwmark}"
|
||||
done
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "${ap_list[*]} transparent proxy."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "${ap_list[*]} transparent proxy."
|
||||
fi
|
||||
|
||||
${iptables} -t mangle -I PREROUTING -j BOX_EXTERNAL
|
||||
@@ -352,7 +364,7 @@ start_tproxy() {
|
||||
for ignore in ${ignore_out_list[@]} ; do
|
||||
${iptables} -t mangle -I BOX_LOCAL -o "${ignore}" -j RETURN
|
||||
done
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "${ignore_out_list[*]} ignore transparent proxy."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "${ignore_out_list[*]} ignore transparent proxy."
|
||||
fi
|
||||
|
||||
# Bypass intranet Clash
|
||||
@@ -393,7 +405,7 @@ start_tproxy() {
|
||||
# Route Everything
|
||||
${iptables} -t mangle -A BOX_LOCAL -p tcp -j MARK --set-mark "${fwmark}"
|
||||
${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "transparent proxy for all apps."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "transparent proxy for all apps."
|
||||
else
|
||||
# Bypass apps
|
||||
|
||||
@@ -407,7 +419,7 @@ start_tproxy() {
|
||||
# Allow !app
|
||||
${iptables} -t mangle -A BOX_LOCAL -p tcp -j MARK --set-mark "${fwmark}"
|
||||
${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] no transparent proxy."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] no transparent proxy."
|
||||
fi
|
||||
|
||||
elif [ "${proxy_mode}" = "whitelist" ]; then
|
||||
@@ -415,7 +427,7 @@ start_tproxy() {
|
||||
# Route Everything
|
||||
${iptables} -t mangle -A BOX_LOCAL -p tcp -j MARK --set-mark "${fwmark}"
|
||||
${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "transparent proxy for all apps."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "transparent proxy for all apps."
|
||||
else
|
||||
# Route apps to Box
|
||||
# loop through uid list and add iptables rule
|
||||
@@ -434,13 +446,13 @@ start_tproxy() {
|
||||
${iptables} -t mangle -A BOX_LOCAL -p udp -m owner --uid-owner 1052 -j MARK --set-mark "${fwmark}"
|
||||
# Route DNS request to Box
|
||||
[ "${bin_name}" != "clash" ] && ${iptables} -t mangle -A BOX_LOCAL -p udp --dport 53 -j MARK --set-mark "${fwmark}"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] transparent proxy."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "proxy-mode: ${proxy_mode} < [ ${packages_list[*]} ] transparent proxy."
|
||||
fi
|
||||
else
|
||||
log debug "proxy-mode: ${proxy_mode} < error"
|
||||
log Debug "proxy-mode: ${proxy_mode} < error"
|
||||
${iptables} -t mangle -A BOX_LOCAL -p tcp -j MARK --set-mark "${fwmark}"
|
||||
${iptables} -t mangle -A BOX_LOCAL -p udp -j MARK --set-mark "${fwmark}"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log info "transparent proxy for all apps."
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Info "transparent proxy for all apps."
|
||||
fi
|
||||
|
||||
${iptables} -t mangle -I OUTPUT -j BOX_LOCAL
|
||||
@@ -457,7 +469,7 @@ start_tproxy() {
|
||||
${iptables} -A OUTPUT -p udp --dport 443 -j REJECT
|
||||
${iptables} -A OUTPUT -p udp --dport 80 -j REJECT
|
||||
# ${iptables} -A OUTPUT -p udp -m multiport --dport 443,80 -j REJECT
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log warn "disable QUIC"
|
||||
[ "${iptables}" != "ip6tables -w 64" ] && log Warning "disable QUIC"
|
||||
fi
|
||||
|
||||
# This rule blocks local access to tproxy-port to prevent traffic loopback.
|
||||
@@ -481,16 +493,17 @@ start_tproxy() {
|
||||
${iptables} -t nat -A CLASH_DNS_LOCAL -m owner --uid-owner "${box_user}" --gid-owner "${box_group}" -j RETURN
|
||||
${iptables} -t nat -A CLASH_DNS_LOCAL -p udp --dport 53 -j REDIRECT --to-ports "${clash_dns_port}"
|
||||
${iptables} -t nat -I OUTPUT -j CLASH_DNS_LOCAL
|
||||
|
||||
# Fix ICMP (ping)
|
||||
# This does not guarantee that the ping result is valid
|
||||
# Just that it returns a result
|
||||
# "--to-destination" can be set to a reachable address.
|
||||
if [ "${clash_enhanced_mode}" = "fake-ip" ] ; then
|
||||
${iptables} -t nat -I OUTPUT -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -I PREROUTING -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
fi
|
||||
# Fix ICMP (ping)
|
||||
# This does not guarantee that the ping result is valid
|
||||
# Just that it returns a result
|
||||
# "--to-destination" can be set to a reachable address.
|
||||
|
||||
if [ -n "${fake_ip_range}" ]; then
|
||||
${iptables} -t nat -I OUTPUT -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -I PREROUTING -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -546,10 +559,13 @@ stop_tproxy() {
|
||||
${iptables} -t nat -F CLASH_DNS_LOCAL
|
||||
${iptables} -t nat -X CLASH_DNS_LOCAL
|
||||
|
||||
${iptables} -t nat -D OUTPUT -p icmp -d "${clash_fake_ip_range}" -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -D PREROUTING -p icmp -d "${clash_fake_ip_range}" -j DNAT --to-destination 127.0.0.1
|
||||
# ${iptables} -t nat -D OUTPUT -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
# ${iptables} -t nat -D PREROUTING -d "${clash_fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
if [ -n "${fake_ip_range}" ]; then
|
||||
${iptables} -t nat -D OUTPUT -p icmp -d "${fake_ip_range}" -j DNAT --to-destination 127.0.0.1
|
||||
${iptables} -t nat -D PREROUTING -p icmp -d "${fake_ip_range}" -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
|
||||
# ${iptables} -t nat -D OUTPUT -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
# ${iptables} -t nat -D PREROUTING -d "${fake_ip_range}" -p icmp -j DNAT --to-destination 127.0.0.1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -557,7 +573,7 @@ if [ "${proxy_mode}" != "tun" ]; then
|
||||
case "$1" in
|
||||
enable)
|
||||
misc_info
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
#ipv4
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
@@ -574,70 +590,69 @@ if [ "${proxy_mode}" != "tun" ]; then
|
||||
find_packages_uid
|
||||
case "${network_mode}" in
|
||||
tproxy)
|
||||
log info "use TPROXY: TCP + UDP."
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use TPROXY: TCP + UDP."
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_tproxy && log info "create iptables transparent proxy rules done." || { log error "create iptables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
start_tproxy && log Info "create iptables transparent proxy rules done." || { log Error "create iptables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
start_tproxy && log info "create ip(6)tables transparent proxy rules done." || { log error "create ip(6)tables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
start_tproxy && log Info "create ip(6)tables transparent proxy rules done." || { log Error "create ip(6)tables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
redirect)
|
||||
log info "use REDIRECT: TCP ONLY"
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use REDIRECT: TCP ONLY"
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_redirect && log info "create iptables transparent proxy rules done." || { log error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create iptables transparent proxy rules done." || { log Error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
start_redirect && log info "create ip(6)tables transparent proxy rules done." || { log error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create ip(6)tables transparent proxy rules done." || { log Error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
mixed)
|
||||
log info "use MIXED: TCP + TUN"
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use MIXED: TCP + TUN"
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
forward -I || forward -D >> /dev/null 2>&1
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_redirect && log info "create iptables transparent proxy rules done." || (log error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1)
|
||||
start_redirect && log Info "create iptables transparent proxy rules done." || (log Error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1)
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
forward -I || forward -D >> /dev/null 2>&1
|
||||
start_redirect && log info "create ip(6)tables transparent proxy rules done." || (log error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1)
|
||||
start_redirect && log Info "create ip(6)tables transparent proxy rules done." || (log Error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1)
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log error "network_mode: ${network_mode}, unknown"
|
||||
log Error "network_mode: ${network_mode}, unknown"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
box_sync_port
|
||||
log info "${bin_name} connected."
|
||||
log Info "${bin_name} connected."
|
||||
;;
|
||||
renew)
|
||||
misc_info
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log warn "cleaning up iptables transparent proxy rules."
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log Warning "cleaning up iptables transparent proxy rules."
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
stop_redirect
|
||||
@@ -648,75 +663,76 @@ if [ "${proxy_mode}" != "tun" ]; then
|
||||
stop_redirect
|
||||
forward -D
|
||||
} >> /dev/null 2>&1
|
||||
log warn "clean up iptables transparent proxy rules done."
|
||||
log Warning "clean up iptables transparent proxy rules done."
|
||||
misc_info
|
||||
find_packages_uid
|
||||
case "${network_mode}" in
|
||||
tproxy)
|
||||
log info "use TPROXY: TCP + UDP."
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use TPROXY: TCP + UDP."
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_tproxy && log info "create iptables transparent proxy rules done." || { log error "create iptables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
start_tproxy && log Info "create iptables transparent proxy rules done." || { log Error "create iptables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
start_tproxy && log info "create ip(6)tables transparent proxy rules done." || { log error "create ip(6)tables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
start_tproxy && log Info "create ip(6)tables transparent proxy rules done." || { log Error "create ip(6)tables transparent proxy rules failed." && stop_tproxy >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
redirect)
|
||||
log info "use REDIRECT: TCP ONLY"
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use REDIRECT: TCP ONLY"
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_redirect && log info "create iptables transparent proxy rules done." || { log error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create iptables transparent proxy rules done." || { log Error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
start_redirect && log info "create ip(6)tables transparent proxy rules done." || { log error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create ip(6)tables transparent proxy rules done." || { log Error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
mixed)
|
||||
log info "use MIXED: TCP + TUN"
|
||||
log info "creating iptables transparent proxy rules."
|
||||
log Info "use MIXED: TCP + TUN"
|
||||
log Info "creating iptables transparent proxy rules."
|
||||
iptables="iptables -w 64"
|
||||
forward -I || forward -D >> /dev/null 2>&1
|
||||
intranet+=($(ip address | busybox awk '/inet / && !/127\.0\.0\.1/ {print $2}'))
|
||||
start_redirect && log info "create iptables transparent proxy rules done." || { log error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create iptables transparent proxy rules done." || { log Error "create iptables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
intranet6+=($(ip address | busybox awk '/inet6/ && !/::1/ && !/fe80/ {print $2}'))
|
||||
forward -I || forward -D >> /dev/null 2>&1
|
||||
start_redirect && log info "create ip(6)tables transparent proxy rules done." || { log error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
start_redirect && log Info "create ip(6)tables transparent proxy rules done." || { log Error "create ip(6)tables transparent proxy rule failed." && stop_redirect >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log error "network_mode: ${network_mode}, unknown"
|
||||
log Error "network_mode: ${network_mode}, unknown"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
box_sync_port
|
||||
log info "restart iptables transparent proxy rules done."
|
||||
log info "${bin_name} connected."
|
||||
log Info "restart iptables transparent proxy rules done."
|
||||
log Info "${bin_name} connected."
|
||||
;;
|
||||
disable)
|
||||
ipv6_enable
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log warn "clean up iptables transparent proxy rules."
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log Warning "clean up iptables transparent proxy rules."
|
||||
#ipv4
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
@@ -729,7 +745,7 @@ if [ "${proxy_mode}" != "tun" ]; then
|
||||
stop_redirect
|
||||
forward -D
|
||||
} >> /dev/null 2>&1
|
||||
log warn "clean up iptables transparent proxy rules done."
|
||||
log Warning "clean up iptables transparent proxy rules done."
|
||||
;;
|
||||
*)
|
||||
echo "${red}$0 $1 no found${normal}"
|
||||
@@ -740,8 +756,8 @@ else
|
||||
case "$1" in
|
||||
enable)
|
||||
misc_info
|
||||
log info "use TUN: TCP + UDP"
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log Info "use TUN: TCP + UDP"
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
#ipv4
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
@@ -755,24 +771,23 @@ else
|
||||
forward -D
|
||||
} >> /dev/null 2>&1
|
||||
iptables="iptables -w 64"
|
||||
forward -I && log info "create iptables tun rules done." || { log error "create iptables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
forward -I && log Info "create iptables tun rules done." || { log Error "create iptables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
forward -I && log info "create ip(6)tables tun rules done." || { log error "create ip(6)tables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
forward -I && log Info "create ip(6)tables tun rules done." || { log Error "create ip(6)tables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
box_sync_port
|
||||
log info "${bin_name} connected."
|
||||
log Info "${bin_name} connected."
|
||||
;;
|
||||
renew)
|
||||
misc_info
|
||||
log info "use TUN: TCP + UDP"
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log warn "cleaning up tun rules."
|
||||
log Info "use TUN: TCP + UDP"
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log Warning "cleaning up tun rules."
|
||||
#ipv4
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
@@ -785,26 +800,27 @@ else
|
||||
stop_redirect
|
||||
forward -D
|
||||
} >> /dev/null 2>&1
|
||||
log warn "clean up tun rules done."
|
||||
log Warning "clean up tun rules done."
|
||||
misc_info
|
||||
iptables="iptables -w 64"
|
||||
forward -I && log info "create iptables tun rules done." || { log error "create iptables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
forward -I && log Info "create iptables tun rules done." || { log Error "create iptables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
if [ "${ipv6}" = "true" ]; then
|
||||
log debug "use IPv6."
|
||||
log Debug "use IPv6."
|
||||
ipv6_enable
|
||||
iptables="ip6tables -w 64"
|
||||
forward -I && log info "create ip(6)tables tun rules done." || { log error "create ip(6)tables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
forward -I && log Info "create ip(6)tables tun rules done." || { log Error "create ip(6)tables tun rules failed." && forward -D >> /dev/null 2>&1; }
|
||||
else
|
||||
disable_ipv6
|
||||
log warn "disable IPv6."
|
||||
log Warning "disable IPv6."
|
||||
fi
|
||||
box_sync_port
|
||||
log info "restart iptables tun rules done."
|
||||
log info "${bin_name} connected."
|
||||
log Info "restart iptables tun rules done."
|
||||
log Info "${bin_name} connected."
|
||||
;;
|
||||
disable)
|
||||
ipv6_enable
|
||||
probe_user_group || log error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log warn "cleaning up tun rules."
|
||||
probe_user_group || log Error "failed to check BOX user group, please make sure ${bin_name} kernel is started."
|
||||
log Warning "cleaning up tun rules."
|
||||
#ipv4
|
||||
iptables="iptables -w 64" && {
|
||||
stop_tproxy
|
||||
@@ -817,7 +833,7 @@ else
|
||||
stop_redirect
|
||||
forward -D
|
||||
} >> /dev/null 2>&1
|
||||
log warn "clean up tun rules done."
|
||||
log Warning "clean up tun rules done."
|
||||
;;
|
||||
*)
|
||||
echo "${red}$0 $1 no found${normal}"
|
||||
|
||||
@@ -6,30 +6,33 @@ source /data/adb/box/settings.ini
|
||||
|
||||
box_check_logs() {
|
||||
# Delete logs for each bin in the list
|
||||
log info "deleting and backing up logs for ${bin_list[*]}"
|
||||
log Info "deleting and backup logs"
|
||||
for bin in "${bin_list[@]}"; do
|
||||
if [ -f "${box_run}/${bin}.log" ]; then
|
||||
mv "${box_run}/${bin}.log" "${box_run}/${bin}-$(date +%Y-%m-%d-%H-%M-%S).log"
|
||||
fi
|
||||
done
|
||||
# Delete other log files
|
||||
find "${box_run}" -type f \( -name "root" -o -name "*.yaml" -o -name "*.list" -o -name "*.inotify.log" \) -exec rm -f {} \; || log warn "Error deleting other log files"
|
||||
find "${box_run}" -type f \( -name "root" -o -name "*.list" -o -name "*.inotify.log" \) -exec rm -f {} \;
|
||||
# Delete logs that are three days old or older
|
||||
find "${box_run}" -type f -name "*.log" -mtime +2 -exec rm -f {} \; || log warn "Error deleting old logs"
|
||||
find "${box_run}" -type f -name "*.log" -mtime +2 -exec rm -f {} \;
|
||||
}
|
||||
|
||||
box_bin_alive() {
|
||||
sleep 1.5
|
||||
pid=$(busybox pidof ${bin_name} 2>/dev/null)
|
||||
if ! kill -0 "${pid}" 2>/dev/null; then
|
||||
log error "${bin_name} service is not running."
|
||||
log error "Please check ${bin_name}.log for more information."
|
||||
log error "Killing stale pid ${pid}"
|
||||
local PID=$(<"${box_pid}" 2>/dev/null)
|
||||
if ! kill -0 "$PID" 2>/dev/null; then
|
||||
log Error "$(<"${box_run}/${bin_name}.log")"
|
||||
log Error "${bin_name} service is not running."
|
||||
log Error "please check ${bin_name}.log for more information."
|
||||
log Error "killing stale pid $PID"
|
||||
for bin in "${bin_list[@]}"; do
|
||||
killall -15 "${bin}" >/dev/null 2>&1 || busybox pkill -15 "${bin}" >/dev/null 2>&1
|
||||
done
|
||||
${scripts_dir}/box.iptables disable >/dev/null 2>&1
|
||||
exit 1
|
||||
"${scripts_dir}/box.iptables" disable >/dev/null 2>&1
|
||||
[ -f "${box_pid}" ] && rm -f "${box_pid}"
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -42,29 +45,21 @@ box_run_crontab() {
|
||||
chmod 0755 "${box_run}/root"
|
||||
|
||||
if [ "${run_crontab}" = "true" ]; then
|
||||
log debug "Cron job enabled"
|
||||
log Debug "Cron job enabled"
|
||||
echo "${interva_update} ${scripts_dir}/box.tool geosub" >> "${box_run}/root"
|
||||
log debug "Interval crontab geox and subs: ${interva_update}."
|
||||
log info "${bin_name} geox updates: ${update_geo}."
|
||||
log Debug "Interval crontab geox and subs: ${interva_update}."
|
||||
log Info "${bin_name} geox updates: ${update_geo}."
|
||||
if [[ "${bin_name}" == @(clash|sing-box) ]]; then
|
||||
log info "${bin_name} subscription update: ${update_subscription}."
|
||||
log Info "${bin_name} subscription update: ${update_subscription}."
|
||||
fi
|
||||
else
|
||||
log info "Cron Job disabled"
|
||||
log info "Crontab geox and subscription is disabled."
|
||||
fi
|
||||
}
|
||||
|
||||
box_detected_port() {
|
||||
if [ "${port_detect}" = "true" ]; then
|
||||
${scripts_dir}/box.tool port
|
||||
else
|
||||
log info "${bin_name} skipped port detection."
|
||||
log Info "Cron Job disabled"
|
||||
log Info "Crontab geox and subscription is disabled."
|
||||
fi
|
||||
}
|
||||
|
||||
box_permission() {
|
||||
if [[ "${box_user_group}" = "root:net_admin" || "${box_user_group}" = "0:3005" ]] && [ -f "${bin_path}" ]; then
|
||||
if [[ "${box_user_group}" == @(root:net_admin|0:3005) && -f "${bin_path}" ]]; then
|
||||
# Set ownership and permission of kernel directory
|
||||
chown ${box_user_group} ${bin_path}
|
||||
chmod 6755 ${bin_path}
|
||||
@@ -72,7 +67,7 @@ box_permission() {
|
||||
chmod 0755 "${box_dir}/bin/yq"
|
||||
# Set ownership of data directory
|
||||
chown -R ${box_user_group} ${box_dir}
|
||||
log info "Use the kernel located in '${bin_path}'."
|
||||
log Info "Use the kernel located in '${bin_path}'."
|
||||
elif which ${bin_name} | grep -q "/system/bin/"; then
|
||||
box_user=$(echo ${box_user_group} | busybox awk -F ':' '{print $1}')
|
||||
box_group=$(echo ${box_user_group} | busybox awk -F ':' '{print $2}')
|
||||
@@ -80,7 +75,7 @@ box_permission() {
|
||||
box_group_id=$(id -g ${box_group})
|
||||
# Check if box_user and box_group exist
|
||||
if ! [[ ${box_user_id} && ${box_group_id} ]]; then
|
||||
log error "${box_user_group} error, use root:net_admin instead."
|
||||
log Error "${box_user_group} error, use root:net_admin instead."
|
||||
box_user_group="root:net_admin"
|
||||
fi
|
||||
bin_path=$(which ${bin_name})
|
||||
@@ -92,62 +87,51 @@ box_permission() {
|
||||
# Check if user is not root and group is not net_admin
|
||||
if [[ "${box_user_id}" != "0" || "${box_group_id}" != "3005" ]]; then
|
||||
# Set capability of kernel directory
|
||||
if ! setcap 'cap_net_admin,cap_net_raw,cap_net_bind_service+ep' "${bin_path}"; then log error "setcap authorization failed, you may need libcap package."; fi
|
||||
if ! setcap 'cap_net_admin,cap_net_raw,cap_net_bind_service+ep' "${bin_path}"; then log Error "setcap authorization failed, you may need libcap package."; fi
|
||||
fi
|
||||
# Set ownership of data directory
|
||||
box_user_group="root:net_admin"
|
||||
log info "Using kernel directory ${bin_name} in ${bin_path}"
|
||||
log Info "Using kernel directory ${bin_name} in ${bin_path}"
|
||||
chown -R ${box_user_group} ${box_dir}
|
||||
else
|
||||
sed -i "s/box_user_group=.*/box_user_group=\"root:net_admin\"/g" ${settings}
|
||||
log error "Kernel <${bin_name}> is missing."
|
||||
log error "Please download the <${bin_name}> kernel and place it in the ${bin_dir}/ directory."
|
||||
log debug "or executed: su -c /data/adb/box/scripts/box.tool upcore ."
|
||||
log Error "Kernel <${bin_name}> is missing."
|
||||
log Error "Please download the <${bin_name}> kernel and place it in the ${bin_dir}/ directory."
|
||||
log Debug "or executed: su -c /data/adb/box/scripts/box.tool upcore ."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
box_check_bin() {
|
||||
if ! command -v "${bin_path}" >/dev/null 2>&1; then
|
||||
log error "${bin_path} not found or not executable."
|
||||
exit 1
|
||||
elif [ ! -x "${bin_path}" ]; then
|
||||
log error "${bin_path} is not executable."
|
||||
exit 1
|
||||
elif [ ! -f "${bin_path}" ]; then
|
||||
log error "${bin_path} is not a regular file."
|
||||
if [ ! -x "${bin_path}" ]; then
|
||||
log Error "${bin_path} is not executable."
|
||||
exit 1
|
||||
fi
|
||||
case "${bin_name}" in
|
||||
clash)
|
||||
if ! "${bin_path}" -v >/dev/null 2>&1; then
|
||||
log error "${bin_name} version information not available."
|
||||
if ! version_output=$("${bin_path}" -v) >/dev/null 2>&1; then
|
||||
log Error "${bin_name} version information not available."
|
||||
exit 1
|
||||
else
|
||||
version_output="$(${bin_path} -v)"
|
||||
log info "${version_output}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if ! "${bin_path}" version >/dev/null 2>&1; then
|
||||
log error "${bin_name} version information not available."
|
||||
if ! version_output=$("${bin_path}" version) >/dev/null 2>&1; then
|
||||
log Error "${bin_name} version information not available."
|
||||
exit 1
|
||||
else
|
||||
version_output="$(${bin_path} version)"
|
||||
log info "${version_output}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
log Info "${version_output}"
|
||||
}
|
||||
|
||||
box_create_tun() {
|
||||
# Creates a symlink for /dev/tun if it doesn't already exist
|
||||
if [ ! -c "/dev/net/tun" ]; then
|
||||
if ! mkdir -p /dev/net || ! mknod /dev/net/tun c 10 200; then
|
||||
log warn "Cannot create /dev/net/tun. Possible reasons:"
|
||||
log warn "This script is not executed as root user."
|
||||
log warn "Your system does not support the TUN/TAP driver."
|
||||
log warn "Your system kernel version is not compatible with the TUN/TAP driver."
|
||||
log Warning "Cannot create /dev/net/tun. Possible reasons:"
|
||||
log Warning "This script is not executed as root user."
|
||||
log Warning "Your system does not support the TUN/TAP driver."
|
||||
log Warning "Your system kernel version is not compatible with the TUN/TAP driver."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
@@ -155,12 +139,17 @@ box_create_tun() {
|
||||
|
||||
prepare_singbox() {
|
||||
# check configuration file
|
||||
if ! [ -f "${sing_config}" ]; then log error "configuration file ${clash_config} not found";exit 1; fi
|
||||
if ! [ -f "${sing_config}" ]; then
|
||||
log Error "configuration file ${sing_config} not found"
|
||||
exit 1
|
||||
else
|
||||
log Info "config ${sing_config}"
|
||||
fi
|
||||
|
||||
yq_cmd="yq"
|
||||
if ! command -v yq &>/dev/null; then
|
||||
if [ ! -e "${box_dir}/bin/yq" ]; then
|
||||
log debug "yq file not found, start to download from github"
|
||||
log Debug "yq file not found, start to download from github"
|
||||
${scripts_dir}/box.tool upyq
|
||||
fi
|
||||
yq_cmd="${box_dir}/bin/yq"
|
||||
@@ -169,35 +158,48 @@ prepare_singbox() {
|
||||
sed -i '/\/\*/,/\*\//d; /^[[:space:]]*\/\//d; /^( *\/\/|\/\*.*\*\/)$/d' "${box_dir}/sing-box/"*.json
|
||||
if [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
if grep -q '"type": "tproxy"' "${sing_config}"; then
|
||||
"${yq_cmd}" eval 'del(.inbounds[] | select(.type == "tproxy"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" 'del(.inbounds[] | select(.type == "tproxy"))' -i --output-format=json "${sing_config}"
|
||||
fi
|
||||
# Checks if "type" is "tun" in configuration
|
||||
if grep -q '"type": "tun"' "${sing_config}"; then
|
||||
log info "type 'tun' already exists in ${sing_config}"
|
||||
log Info "type 'tun' already exists in ${sing_config}"
|
||||
else
|
||||
# Add "tun" configuration if missing
|
||||
"${yq_cmd}" eval '.inbounds += [{"type": "tun","tag": "tun-in","interface_name": "tun3","inet4_address": "172.19.0.1/30","inet6_address": "fdfe:dcba:9876::1/126","mtu": 9000,"stack": "system","auto_route": true,"strict_route": false,"sniff": true,"sniff_override_destination": true,"include_android_user": [0,10],"include_package": [],"exclude_package": []}]' -i --output-format=json "${sing_config}"
|
||||
log debug "'tun' configuration has been added to ${sing_config}"
|
||||
"${yq_cmd}" '.inbounds += [{"type": "tun","tag": "tun-in","interface_name": "tun3","inet4_address": "172.19.0.1/30","inet6_address": "fdfe:dcba:9876::1/126","mtu": 9000,"stack": "system","auto_route": true,"strict_route": false,"sniff": true,"sniff_override_destination": true,"include_android_user": [0,10],"include_package": [],"exclude_package": []}]' -i --output-format=json "${sing_config}"
|
||||
log Debug "'tun' configuration has been added to ${sing_config}"
|
||||
fi
|
||||
if [ "${network_mode}" = "mixed" ]; then
|
||||
# Checks if "type" is "redirect" in configuration
|
||||
if grep -q '"type": "redirect"' "${sing_config}"; then
|
||||
log Info "type 'redirect' already exists in ${sing_config}"
|
||||
else
|
||||
# Add "redirect" configuration if missing
|
||||
"${yq_cmd}" '.inbounds += [{"type": "redirect","tag": "redirect-in","listen": "::","listen_port": '"${redir_port}"',"sniff": true,"sniff_override_destination": true}]' -i --output-format=json "${sing_config}"
|
||||
log Debug "'redirect' configuration has been added to ${sing_config}"
|
||||
fi
|
||||
fi
|
||||
sed -i 's/"auto_detect_interface": false/"auto_detect_interface": true/g' "${box_dir}/sing-box/"*.json
|
||||
sed -i 's/auto_route": false/auto_route": true/g' "${box_dir}/sing-box/"*.json
|
||||
else
|
||||
if grep -q '"type": "tun"' "${sing_config}"; then
|
||||
"${yq_cmd}" eval 'del(.inbounds[] | select(.type == "tun"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" 'del(.inbounds[] | select(.type == "tun"))' -i --output-format=json "${sing_config}"
|
||||
fi
|
||||
if grep -q '"type": "redirect"' "${sing_config}"; then
|
||||
"${yq_cmd}" 'del(.inbounds[] | select(.type == "redirect"))' -i --output-format=json "${sing_config}"
|
||||
fi
|
||||
# Checks if "type" is "tproxy" in configuration
|
||||
if grep -q '"type": "tproxy"' "${sing_config}"; then
|
||||
log info "type 'tproxy' already exists in ${sing_config}"
|
||||
log Info "type 'tproxy' already exists in ${sing_config}"
|
||||
else
|
||||
# Add "tproxy" configuration if missing
|
||||
"${yq_cmd}" eval '.inbounds += [{"type": "tproxy", "tag": "tproxy-in", "listen": "::", "listen_port": '"${tproxy_port}"', "sniff": true, "sniff_override_destination": true}]' -i --output-format=json "${sing_config}"
|
||||
log debug "'tproxy' configuration has been added to ${sing_config}"
|
||||
"${yq_cmd}" '.inbounds += [{"type": "tproxy", "tag": "tproxy-in", "listen": "::", "listen_port": '"${tproxy_port}"', "sniff": true, "sniff_override_destination": true}]' -i --output-format=json "${sing_config}"
|
||||
log Debug "'tproxy' configuration has been added to ${sing_config}"
|
||||
fi
|
||||
# sync tproxy port sing-box, Looping through each JSON file in the directory
|
||||
for file in "${box_dir}/sing-box/"*.json; do
|
||||
tproxy=$(sed -n 's/.*"type": "\(tproxy\)".*/\1/p' "${file}")
|
||||
if [[ -n "${tproxy}" ]]; then
|
||||
"${yq_cmd}" -o=json eval "(.inbounds[]? | select(.type == \"tproxy\") | .listen_port) = ${tproxy_port}" -i --output-format=json "${file}"
|
||||
if [ -n "${tproxy}" ]; then
|
||||
"${yq_cmd}" -o=json "(.inbounds[]? | select(.type == \"tproxy\") | .listen_port) = ${tproxy_port}" -i --output-format=json "${file}"
|
||||
fi
|
||||
done
|
||||
sed -i 's/"auto_detect_interface": true/"auto_detect_interface": false/g' "${box_dir}/sing-box/"*.json
|
||||
@@ -207,7 +209,13 @@ prepare_singbox() {
|
||||
|
||||
prepare_clash() {
|
||||
# check configuration file
|
||||
if ! [ -f "${clash_config}" ]; then log error "configuration file ${clash_config} not found";exit 1; fi
|
||||
if ! [ -f "${clash_config}" ]; then
|
||||
log Error "configuration file ${clash_config} not found"
|
||||
exit 1
|
||||
else
|
||||
temp_clash_config_file
|
||||
log Info "config ${clash_config}"
|
||||
fi
|
||||
|
||||
# ipv6=$(busybox awk '/ipv6:/ { print $2; found=1; exit } END{ if(!found) print "false" }' "${clash_config}" | head -n 1 2>/dev/null)
|
||||
# sed -i "s/ipv6:.*/ipv6: ${ipv6}/g" "${clash_config}"
|
||||
@@ -251,9 +259,9 @@ prepare_clash() {
|
||||
' auto-detect-interface: true' \
|
||||
' include-android-user: [0, 10]' \
|
||||
' exclude-package: []' \ >> "${clash_config}"
|
||||
log debug "'tun' configuration has been added to ${sing_config}"
|
||||
log Debug "'tun' configuration has been added to ${sing_config}"
|
||||
else
|
||||
log info "type 'tun' already exists in ${clash_config}"
|
||||
log Info "type 'tun' already exists in ${clash_config}"
|
||||
fi
|
||||
sed -i "/tun:/ {n;s/enable: false/enable: true/}" "${clash_config}"
|
||||
else
|
||||
@@ -265,6 +273,7 @@ prepare_clash() {
|
||||
if [ "${clash_tun_status}" != "true" ]; then
|
||||
# sync tproxy port
|
||||
sed -i -E "s/(tproxy-port: )[0-9]+/\1${tproxy_port}/" "${clash_config}"
|
||||
sed -i -E "s/(redir-port: )[0-9]+/\1${redir_port}/" "${clash_config}"
|
||||
else
|
||||
[ "${proxy_mode}" != "tun" ] && sed -i 's/network_mode=.*/network_mode="mixed"/g' "${settings}"
|
||||
# remove tproxy port >>> 0
|
||||
@@ -274,36 +283,49 @@ prepare_clash() {
|
||||
fi
|
||||
}
|
||||
|
||||
temp_clash_config_file() {
|
||||
clash_template="/data/adb/box/clash/template"
|
||||
temp_clash_config_file="${clash_config}"
|
||||
|
||||
if [ -f "${clash_template}" ]; then
|
||||
log debug "use template configuration"
|
||||
cp -f "${clash_template}" "${temp_clash_config_file}.temp" && echo "\n" >> "${temp_clash_config_file}.temp"
|
||||
sed -n -E '/^proxies:$/,$p' "${clash_config}" >> "${temp_clash_config_file}.temp"
|
||||
sed -i '/^[[:space:]]*$/d' "${temp_clash_config_file}.temp"
|
||||
if mv "${temp_clash_config_file}.temp" "${clash_config}"; then
|
||||
log Info "The merging of the $clash_config and $clash_template files is complete."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
box_run_bin() {
|
||||
log info "client-list: [ ${bin_list[*]} ]"
|
||||
log info "choose: ${bin_name}, start the service."
|
||||
log Info "client-list: [ ${bin_list[*]} ]"
|
||||
log Info "choose: ${bin_name}, start the service."
|
||||
ulimit -SHn 65535
|
||||
case "${bin_name}" in
|
||||
sing-box)
|
||||
prepare_singbox
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -D "${box_dir}/${bin_name}" --config-directory "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.1
|
||||
|
||||
if ! busybox pidof "${bin_name}" >/dev/null; then
|
||||
MESSAGE=$(cat "${box_run}/${bin_name}.log")
|
||||
log error "Message: $MESSAGE"
|
||||
log error "Configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
if ${bin_path} check -D "${box_dir}/${bin_name}" --config-directory "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1; then
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -D "${box_dir}/${bin_name}" --config-directory "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.5
|
||||
else
|
||||
log Error "$(<"${box_run}/${bin_name}.log")"
|
||||
log Error "configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
clash)
|
||||
prepare_clash
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" -d "${box_dir}/${bin_name}" -f "${clash_config}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.1
|
||||
|
||||
if ! busybox pidof "${bin_name}" >/dev/null; then
|
||||
MESSAGE=$(cat "${box_run}/${bin_name}.log")
|
||||
log error "Message: $MESSAGE"
|
||||
log error "Configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
if ${bin_path} -t -d "${box_dir}/${bin_name}" -f "${clash_config}" > "${box_run}/${bin_name}.log" 2>&1; then
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" -d "${box_dir}/${bin_name}" -f "${clash_config}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.5
|
||||
else
|
||||
log Error "$(<"${box_run}/${bin_name}.log")"
|
||||
log Error "configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
@@ -312,23 +334,29 @@ box_run_bin() {
|
||||
sed -i 's/\(network_mode=\)\"[^\"]*\"/\1"tproxy"/g' ${settings}
|
||||
[ "${proxy_mode}" = "tun" ] && sed -i 's/\(proxy_mode=\)\"[^\"]*\"/\1"blacklist"/g' ${settings}
|
||||
|
||||
# sync port
|
||||
# sed -i "s/port = [0-9]*\.[0-9]*/port = ${tproxy_port}.0/" ${box_dir}/$bin_name/config.toml
|
||||
|
||||
# check configuration file
|
||||
if ! [ -f "${box_dir}/${bin_name}/config.toml" ] && ! [ -f "${box_dir}/${bin_name}/config.json" ]; then
|
||||
log error "configuration file not found: ${box_dir}/${bin_name}/config.toml or config.json"
|
||||
log Error "configuration file not found: ${box_dir}/${bin_name}/config.toml or config.json"
|
||||
rm -f "${box_pid}"
|
||||
exit 1
|
||||
else
|
||||
# Displays a configuration xray"
|
||||
log Info "config ${box_dir}/${bin_name}/*.json, or *.toml"
|
||||
fi
|
||||
|
||||
# run xray
|
||||
export XRAY_LOCATION_ASSET="${box_dir}/${bin_name}"
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -confdir "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.1
|
||||
|
||||
if ! busybox pidof "${bin_name}" >/dev/null; then
|
||||
MESSAGE=$(cat "${box_run}/${bin_name}.log")
|
||||
log error "Message: $MESSAGE"
|
||||
log error "Configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
if ${bin_path} -test -confdir "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1; then
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -confdir "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.5
|
||||
else
|
||||
log Error "$(<"${box_run}/${bin_name}.log")"
|
||||
log Error "configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
@@ -337,28 +365,33 @@ box_run_bin() {
|
||||
sed -i 's/\(network_mode=\)\"[^\"]*\"/\1"tproxy"/g' ${settings}
|
||||
[ "${proxy_mode}" = "tun" ] && sed -i 's/\(proxy_mode=\)\"[^\"]*\"/\1"blacklist"/g' ${settings}
|
||||
|
||||
# sync port
|
||||
# sed -i "s/port = [0-9]*\.[0-9]*/port = ${tproxy_port}.0/" ${box_dir}/$bin_name/config.toml
|
||||
|
||||
# check configuration file
|
||||
if ! [ -f "${box_dir}/${bin_name}/config.toml" ] && ! [ -f "${box_dir}/${bin_name}/config.json" ]; then
|
||||
log error "configuration file not found: ${box_dir}/${bin_name}/config.toml or config.json"
|
||||
log Error "configuration file not found: ${box_dir}/${bin_name}/config.toml or config.json"
|
||||
exit 1
|
||||
else
|
||||
# Displays a configuration v2fly"
|
||||
log Info "config ${box_dir}/${bin_name}/*.json, or *.toml"
|
||||
fi
|
||||
|
||||
# run v2ray
|
||||
export V2RAY_LOCATION_ASSET="${box_dir}/${bin_name}"
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -d "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.1
|
||||
|
||||
if ! busybox pidof "${bin_name}" >/dev/null; then
|
||||
MESSAGE=$(cat "${box_run}/${bin_name}.log")
|
||||
log error "Message: $MESSAGE"
|
||||
log error "Configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
if ${bin_path} test -confdir "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1; then
|
||||
nohup busybox setuidgid "${box_user_group}" "${bin_path}" run -d "${box_dir}/${bin_name}" > "${box_run}/${bin_name}.log" 2>&1 &
|
||||
PID=$!
|
||||
echo -n $PID > "${box_pid}"
|
||||
sleep 0.5
|
||||
else
|
||||
log Error "$(<"${box_run}/${bin_name}.log")"
|
||||
log Error "configuration failed. Please check the ${box_run}/${bin_name}.log file."
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -367,173 +400,151 @@ box_run_bin() {
|
||||
box_cgroup() {
|
||||
if [ "${cgroup_memory}" = "true" ]; then
|
||||
if ${scripts_dir}/box.tool cgroup; then
|
||||
log info "cgroup limit: ${cgroup_memory_limit}."
|
||||
log Info "cgroup limit: ${cgroup_memory_limit}."
|
||||
else
|
||||
log warn "failed to enable cgroup for ${bin_name}."
|
||||
log warn "cgroups is turned off"
|
||||
log Warning "failed to enable cgroup for ${bin_name}."
|
||||
log Warning "cgroups is turned off"
|
||||
sed -i -E "/cgroup_memory/ s/(true)/false/" "${settings}"
|
||||
fi
|
||||
else
|
||||
log info "${bin_name} cgroup: disabled."
|
||||
log Info "${bin_name} cgroup: disabled."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to display the usage of a binary
|
||||
# This script retrieves information about a running binary process and logs it to a log file.
|
||||
|
||||
box_bin_status() {
|
||||
# Get the process ID of the binary
|
||||
bin_pid=$(busybox pidof ${bin_name})
|
||||
local PID=$(busybox pidof ${bin_name})
|
||||
|
||||
if [ -z "${bin_pid}" ]; then
|
||||
log error "${bin_name} is not running."
|
||||
if [ -z "$PID" ]; then
|
||||
log Error "${bin_name} is not running."
|
||||
return 1
|
||||
fi
|
||||
|
||||
log Info "${bin_name}($PID) service is running."
|
||||
log Info "proxy_mode: ${proxy_mode}, $(if [ "${proxy_mode}" != "tun" ]; then echo network_mode: ${network_mode}; fi)"
|
||||
|
||||
# Get the memory usage of the binary
|
||||
rss=$(grep VmRSS /proc/${bin_pid}/status | busybox awk '{ print $2 }')
|
||||
rss=$(grep VmRSS /proc/$PID/status | busybox awk '{ print $2 }')
|
||||
[ "${rss}" -ge 1024 ] && bin_rss="$(expr ${rss} / 1024) MB" || bin_rss="${rss} KB"
|
||||
swap=$(grep VmSwap /proc/${bin_pid}/status | busybox awk '{ print $2 }')
|
||||
swap=$(grep VmSwap /proc/$PID/status | busybox awk '{ print $2 }')
|
||||
[ "${swap}" -ge 1024 ] && bin_swap="$(expr ${swap} / 1024) MB" || bin_swap="${swap} KB"
|
||||
|
||||
# Get the state of the binary
|
||||
state=$(grep State /proc/${bin_pid}/status | busybox awk '{ print $2" "$3 }')
|
||||
state=$(grep State /proc/$PID/status | busybox awk '{ print $2" "$3 }')
|
||||
|
||||
# Get the user and group of the binary
|
||||
user_group=$(stat -c %U:%G /proc/${bin_pid})
|
||||
user_group=$(stat -c %U:%G /proc/$PID)
|
||||
|
||||
# Log the information
|
||||
log info "${bin_name} has started with the '${user_group}' user group."
|
||||
log info "${bin_name} status: ${state} (PID: ${bin_pid})"
|
||||
log info "${bin_name} memory usage: ${bin_rss}, swap: ${bin_swap}"
|
||||
log Info "${bin_name} has started with the '${user_group}' user group."
|
||||
log Info "${bin_name} status: ${state} (PID: $PID)"
|
||||
log Info "${bin_name} memory usage: ${bin_rss}, swap: ${bin_swap}"
|
||||
|
||||
# Get the CPU usage of the binary
|
||||
cpu=$(ps -p ${bin_pid} -o %cpu | busybox awk 'NR==2{print $1}' 2> /dev/null)
|
||||
cpu=$(ps -p $PID -o %cpu | busybox awk 'NR==2{print $1}' 2> /dev/null)
|
||||
if [ -n "${cpu}" ]; then
|
||||
log info "${bin_name} CPU usage: ${cpu}%"
|
||||
log Info "${bin_name} CPU usage: ${cpu}%"
|
||||
else
|
||||
log info "${bin_name} CPU usage: not available"
|
||||
log Info "${bin_name} CPU usage: not available"
|
||||
fi
|
||||
|
||||
# Get the running time of the binary
|
||||
running_time=$(ps -p ${bin_pid} -o etime | busybox awk 'NR==2{print $1}' 2> /dev/null)
|
||||
running_time=$(ps -p $PID -o etime | busybox awk 'NR==2{print $1}' 2> /dev/null)
|
||||
if [ -n "${running_time}" ]; then
|
||||
log info "${bin_name} running time: ${running_time}"
|
||||
log Info "${bin_name} running time: ${running_time}"
|
||||
else
|
||||
log info "${bin_name} running time: not available."
|
||||
log Info "${bin_name} running time: not available."
|
||||
fi
|
||||
|
||||
# Save the process ID to the pid file
|
||||
echo -n "${bin_pid}" > "${box_pid}"
|
||||
[ -n "$PID" ] && echo -n "$PID" > "${box_pid}"
|
||||
}
|
||||
|
||||
start_box() {
|
||||
# Clear the log file and add the timestamp and delimiter
|
||||
echo -n "" > "${box_log}"
|
||||
# Check whether busybox is installed or not on the system using command -v
|
||||
if ! command -v busybox &> /dev/null; then
|
||||
log error "busybox command not found."
|
||||
exit 1
|
||||
fi
|
||||
# Check if the script is being run in interactive mode or not and display the appropriate message
|
||||
time_zone=$(getprop persist.sys.timezone)
|
||||
sim_operator=$(getprop gsm.sim.operator.alpha)
|
||||
network_type=$(getprop gsm.network.type)
|
||||
if [ -t 1 ]; then
|
||||
echo -e "${yellow}${time_zone}${normal}"
|
||||
echo -e "${yellow}${sim_operator} / ${network_type}${normal}"
|
||||
echo -e "${yellow}$(getprop persist.sys.timezone)${normal}"
|
||||
echo -e "${yellow}$(getprop gsm.sim.operator.alpha) / $(getprop gsm.network.type)${normal}"
|
||||
echo -e "${yellow}$(date)${normal}"
|
||||
echo -e "${white}--------------------------------------------${normal}"
|
||||
else
|
||||
echo "$(getprop persist.sys.timezone)" | tee -a "${box_log}" > /dev/null 2>&1
|
||||
echo "${sim_operator} / ${network_type}" | tee -a "${box_log}" > /dev/null 2>&1
|
||||
echo "$(getprop gsm.sim.operator.alpha) / $(getprop gsm.network.type)" | tee -a "${box_log}" > /dev/null 2>&1
|
||||
echo "$(date)" | tee -a "${box_log}" > /dev/null 2>&1
|
||||
echo "--------------------------------------------" | tee -a "${box_log}" > /dev/null 2>&1
|
||||
fi
|
||||
|
||||
# Update iptables if bin_name is still running
|
||||
local pid=$(cat ${box_pid} 2>/dev/null)
|
||||
if kill -0 "${pid}" > /dev/null 2>&1 || busybox pidof "${bin_name}" > /dev/null 2>&1; then
|
||||
log debug "${bin_name} service is still running, auto restart box."
|
||||
PIDS=("clash" "xray" "sing-box" "v2fly")
|
||||
PID=""
|
||||
i=0
|
||||
while [ -z "$PID" ] && [ "$i" -lt "${#PIDS[@]}" ]; do
|
||||
PID=$(busybox pidof "${PIDS[$i]}")
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
if [ -n "$PID" ]; then
|
||||
pid_name="/data/adb/box/run/pid_name.txt"
|
||||
ps -p $PID -o comm= > "${pid_name}"
|
||||
sed -i '/^[[:space:]]*$/d' "${pid_name}"
|
||||
log Debug "$(<"${pid_name}") (PID: $PID) service is still running, auto restart BOX."
|
||||
rm -f "${pid_name}"
|
||||
stop_box
|
||||
start_box
|
||||
${scripts_dir}/box.iptables renew || ${scripts_dir}/box.iptables disable
|
||||
start_box && "${scripts_dir}/box.iptables" renew
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Checks if bin_name is defined
|
||||
case "${bin_name}" in
|
||||
"xray" | "sing-box" | "clash" | "v2fly")
|
||||
log info "Good day 🐻"
|
||||
log Info "Good day 🐱"
|
||||
;;
|
||||
*)
|
||||
log error "bin_name: <${bin_name}> unknown not defined."
|
||||
log Error "bin_name: <..${bin_name}..> unknown not defined."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Check permissions, check for bin existence, delete old logs, create a TUN if necessary, run box, and wait for 1 second
|
||||
box_permission
|
||||
box_check_bin
|
||||
box_check_logs
|
||||
|
||||
# Enable IP forwarding
|
||||
if ! sysctl -w net.ipv4.ip_forward=1 >/dev/null 2>&1 || ! sysctl -w net.ipv6.conf.all.forwarding=1 >/dev/null 2>&1; then
|
||||
echo "Cannot enable IP forwarding."
|
||||
log Debug "Cannot enable IP forwarding."
|
||||
fi
|
||||
box_create_tun
|
||||
box_run_bin
|
||||
sleep 1
|
||||
# Displays a configuration message if bin_name is "clash|xray|sing-box|v2fly"
|
||||
case "${bin_name}" in
|
||||
"clash")
|
||||
log info "config ${clash_config}"
|
||||
;;
|
||||
"sing-box")
|
||||
log info "config ${box_dir}/${bin_name}/*.json"
|
||||
;;
|
||||
"xray" | "v2fly")
|
||||
log info "config ${box_dir}/${bin_name}/*.json, or *.toml"
|
||||
;;
|
||||
*)
|
||||
log error "bin_name: <${bin_name}> unknown not defined."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Execute the box_create_tun functions
|
||||
if [[ "${network_mode}" == "mixed" || "${proxy_mode}" == "tun" ]]; then
|
||||
box_create_tun
|
||||
fi
|
||||
|
||||
# Execute box_run_crontab if run_crontab is not equal to "false"
|
||||
if [ "${run_crontab}" != "false" ]; then
|
||||
box_run_crontab
|
||||
else
|
||||
log info "crontab: disabled."
|
||||
fi
|
||||
# Execute the box_cgroup, box_detected_port, box_bin_alive functions
|
||||
[ "${run_crontab}" != "false" ] && box_run_crontab || log Info "crontab disabled."
|
||||
|
||||
# Execute the box_cgroup, box_run_bin, box_detected_port, box_bin_alive,box_bin_status functions
|
||||
box_run_bin
|
||||
box_cgroup
|
||||
box_detected_port
|
||||
box_bin_alive
|
||||
# Checks if bin_name is defined
|
||||
if [ -z "${bin_name}" ]; then
|
||||
log error "bin_name: <${bin_name}> unknown not defined."
|
||||
exit 1
|
||||
fi
|
||||
# Look up the PID of bin_name
|
||||
bin_pid=$(busybox pidof "${bin_name}")
|
||||
# Checks if bin_name is running
|
||||
if [ -n "${bin_pid}" ]; then
|
||||
# If so, prints a message and calls the box_bin_status function
|
||||
log info "${bin_name} service is running. (PID: ${bin_pid})."
|
||||
log info "proxy_mode: $proxy_mode $(if [ "${proxy_mode}" != "tun" ]; then echo / network_mode: $network_mode; fi)"
|
||||
box_bin_status
|
||||
else
|
||||
# Otherwise, it prints a message and returns status 1
|
||||
log warn "${bin_name} service is stopped."
|
||||
exit 1
|
||||
fi
|
||||
# $bin_name detected port
|
||||
if [ "${port_detect}" = "true" ]; then "${scripts_dir}/box.tool" port; else log Info "${bin_name} skipped port detection."; fi
|
||||
count=0
|
||||
while [ $count -le 10 ]; do
|
||||
sleep 0.15
|
||||
box_bin_alive || break
|
||||
count=$((count + 1))
|
||||
done
|
||||
box_bin_status
|
||||
|
||||
# open the yacd in browser
|
||||
open_yacd
|
||||
}
|
||||
|
||||
stop_box() {
|
||||
# Find cronjob PID using `pgrep`
|
||||
cronkill=$(busybox pgrep -f "crond -c ${box_run}")
|
||||
for cron in ${cronkill[@]}; do
|
||||
# kill cronjob
|
||||
kill -15 "${cron}"
|
||||
done
|
||||
stop_cron
|
||||
# Kill each binary using a loop
|
||||
for bin in "${bin_list[@]}"; do
|
||||
# Check if the binary is running using pgrep
|
||||
@@ -546,6 +557,7 @@ stop_box() {
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Check if the binary has stopped
|
||||
sleep 0.5
|
||||
if ! busybox pidof "${bin_name}" >/dev/null 2>&1; then
|
||||
@@ -553,17 +565,27 @@ stop_box() {
|
||||
if [ -f "${box_pid}" ]; then
|
||||
rm -f "${box_pid}"
|
||||
fi
|
||||
log warn "${bin_name} service is stopped."
|
||||
log warn "${bin_name} disconnected."
|
||||
log Warning "${bin_name} service is stopped."
|
||||
log Warning "${bin_name} disconnected."
|
||||
[ -t 1 ] && echo -e "${white}--------------------------------------------${normal}"
|
||||
else
|
||||
log warn "${bin_name} Not stopped; may still be shutting down or failed to shut down."
|
||||
log Warning "${bin_name} Not stopped; may still be shutting down or failed to shut down."
|
||||
force_stop
|
||||
fi
|
||||
}
|
||||
|
||||
stop_cron() {
|
||||
# Find cronjob PID using `pgrep`
|
||||
cronkill=$(busybox pgrep -f "crond -c ${box_run}")
|
||||
for cron in ${cronkill[@]}; do
|
||||
# kill cronjob
|
||||
kill -15 "${cron}"
|
||||
done
|
||||
}
|
||||
|
||||
force_stop() {
|
||||
# try forcing it to shut down.
|
||||
log warn "try forcing it to shut down."
|
||||
log Warning "try forcing it to shut down."
|
||||
for bin in "${bin_list[@]}"; do
|
||||
# Use `busybox pkill` to kill the binary with signal 9, otherwise use `killall`.
|
||||
if busybox pkill -9 "${bin}"; then
|
||||
@@ -578,11 +600,17 @@ force_stop() {
|
||||
done
|
||||
sleep 0.5
|
||||
if ! busybox pidof "${bin_name}" >/dev/null 2>&1; then
|
||||
log warn "done, YOU can sleep peacefully."
|
||||
log Warning "done, YOU can sleep peacefully."
|
||||
rm -f "${box_pid}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check whether busybox is installed or not on the system using command -v
|
||||
if ! command -v busybox &> /dev/null; then
|
||||
log Error "busybox command not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
stop_box >> /dev/null 2>&1
|
||||
@@ -593,7 +621,7 @@ case "$1" in
|
||||
;;
|
||||
restart)
|
||||
"${scripts_dir}/box.iptables" disable && stop_box
|
||||
sleep 1
|
||||
sleep 0.5
|
||||
start_box && "${scripts_dir}/box.iptables" renew
|
||||
;;
|
||||
status)
|
||||
@@ -603,24 +631,22 @@ case "$1" in
|
||||
clash) echo "${yellow}$("${bin_path}" -v)${normal}";;
|
||||
*) echo "${yellow}$("${bin_path}" version)${normal}";;
|
||||
esac
|
||||
log info "proxy_mode: $proxy_mode $(if [ "${proxy_mode}" != "tun" ]; then echo / network_mode: $network_mode; fi)"
|
||||
box_bin_status
|
||||
else
|
||||
log warn "${bin_name} service is stopped."
|
||||
log Warning "${bin_name} service is stopped."
|
||||
fi
|
||||
;;
|
||||
cron)
|
||||
run_crontab="true"
|
||||
cronkill=$(busybox pgrep -f "crond -c ${box_run}")
|
||||
for cron in ${cronkill[@]}; do
|
||||
# kill cronjob
|
||||
kill -15 "${cron}"
|
||||
done
|
||||
sleep 0.2
|
||||
stop_cron
|
||||
sleep 0.5
|
||||
box_run_crontab
|
||||
;;
|
||||
kcron)
|
||||
stop_cron
|
||||
;;
|
||||
*)
|
||||
echo "${red}$0 $1 no found${normal}"
|
||||
echo "${yellow}usage${normal}: ${green}$0${normal} {${yellow}start|stop|restart|status${normal}}"
|
||||
echo "${yellow}usage${normal}: ${green}$0${normal} {${yellow}start|stop|restart|status|cron|kcron${normal}}"
|
||||
;;
|
||||
esac
|
||||
@@ -15,29 +15,22 @@ singbox_releases=false
|
||||
# whether use ghproxy to accelerate github download
|
||||
use_ghproxy=true
|
||||
|
||||
# Check if a binary is running by checking the pid file
|
||||
probe_bin_alive() {
|
||||
if [ ! -f "${box_pid}" ]; then
|
||||
log error "pid file not found, binary is not alive"
|
||||
return 1
|
||||
fi
|
||||
sleep 0.5
|
||||
if ! busybox pidof "${bin_name}" >/dev/null; then
|
||||
log error "binary is not alive"
|
||||
return 1
|
||||
fi
|
||||
return 0 # binary is alive
|
||||
}
|
||||
|
||||
# Restart the binary, after stopping and running again
|
||||
restart_box() {
|
||||
${scripts_dir}/box.service restart
|
||||
sleep 0.5
|
||||
if probe_bin_alive ; then
|
||||
# ${scripts_dir}/box.iptables renew
|
||||
log debug "$(date +"%F %R") || ${bin_name} finished restarting."
|
||||
"${scripts_dir}/box.service" restart
|
||||
# PIDS=("clash" "xray" "sing-box" "v2fly")
|
||||
PIDS=(${bin_name})
|
||||
PID=""
|
||||
i=0
|
||||
while [ -z "$PID" ] && [ "$i" -lt "${#PIDS[@]}" ]; do
|
||||
PID=$(busybox pidof "${PIDS[$i]}")
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
if [ -n "$PID" ]; then
|
||||
log Debug "${bin_name} Restart complete [$(date +"%F %R")]"
|
||||
else
|
||||
log error "Failed to restart ${bin_name}."
|
||||
log Error "Failed to restart ${bin_name}."
|
||||
${scripts_dir}/box.iptables disable >/dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
@@ -51,7 +44,7 @@ update_file() {
|
||||
mv "${file}" "${file_bak}" || return 1
|
||||
fi
|
||||
# Use ghproxy
|
||||
if [[ "${use_ghproxy}" == true ]] && [[ "${update_url}" == @(https://github.com/*|https://raw.githubusercontent.com/*|https://gist.github.com/*|https://gist.githubusercontent.com/*) ]]; then
|
||||
if [ "${use_ghproxy}" == true ] && [[ "${update_url}" == @(https://github.com/*|https://raw.githubusercontent.com/*|https://gist.github.com/*|https://gist.githubusercontent.com/*) ]]; then
|
||||
update_url="https://ghproxy.com/${update_url}"
|
||||
fi
|
||||
# request
|
||||
@@ -65,7 +58,7 @@ update_file() {
|
||||
if [ -f "${file_bak}" ]; then
|
||||
mv "${file_bak}" "${file}" || true
|
||||
fi
|
||||
log error "Download ${request} ${orange}failed${normal}"
|
||||
log Error "Download ${request} ${orange}failed${normal}"
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
@@ -79,13 +72,13 @@ update_yq() {
|
||||
"armv7l"|"armv8l") arch="arm"; platform="android" ;;
|
||||
"i686") arch="386"; platform="android" ;;
|
||||
"x86_64") arch="amd64"; platform="android" ;;
|
||||
*) log warn "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
*) log Warning "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
# If you use yq_linux, an error will occur (cmd: mkdir /tmp permission denied) when using a cron job.
|
||||
# download_link="https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${arch}"
|
||||
download_link="https://github.com/taamarin/yq/releases/download/prerelease/yq_${platform}_${arch}"
|
||||
|
||||
log debug "Download ${download_link}"
|
||||
log Debug "Download ${download_link}"
|
||||
update_file "${box_dir}/bin/yq" "${download_link}"
|
||||
chown "${box_user_group}" "${box_dir}/bin/yq"
|
||||
chmod 0755 "${box_dir}/bin/yq"
|
||||
@@ -116,12 +109,12 @@ update_geox() {
|
||||
geosite_url="https://github.com/MetaCubeX/meta-rules-dat/raw/release/geosite.dat"
|
||||
;;
|
||||
esac
|
||||
if [ "${update_geo}" = "true" ] && { log info "daily updates geox" && log debug "Downloading ${geoip_url}"; } && update_file "${geoip_file}" "${geoip_url}" && { log debug "Downloading ${geosite_url}" && update_file "${geosite_file}" "${geosite_url}"; }; then
|
||||
if [ "${update_geo}" = "true" ] && { log Info "daily updates geox" && log Debug "Downloading ${geoip_url}"; } && update_file "${geoip_file}" "${geoip_url}" && { log Debug "Downloading ${geosite_url}" && update_file "${geosite_file}" "${geosite_url}"; }; then
|
||||
|
||||
find "${box_dir}/${bin_name}" -type f -name "*.db.bak" -delete
|
||||
find "${box_dir}/${bin_name}" -type f -name "*.dat.bak" -delete
|
||||
find "${box_dir}/${bin_name}" -type f -name "*.mmdb.bak" -delete
|
||||
log debug "Update geox $(date +%F %R)"
|
||||
log Debug "Update geox $(date +%F %R)"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
@@ -137,7 +130,7 @@ update_subs() {
|
||||
# If yq native doesn't exist
|
||||
if [ "${yq_command}" -eq 1 ]; then
|
||||
if [ ! -e "${box_dir}/bin/yq" ]; then
|
||||
log debug "yq file not found, start to download from github"
|
||||
log Debug "yq file not found, start to download from github"
|
||||
update_yq
|
||||
fi
|
||||
yq_command=$(command -v "${box_dir}/bin/yq" >/dev/null 2>&1; echo $?)
|
||||
@@ -147,7 +140,7 @@ update_subs() {
|
||||
enhanced=true
|
||||
update_file_name="${update_file_name}.subscription"
|
||||
else
|
||||
log warn "yq not found, this will update main configuration $(if [ "${bin_name}" = "clash" ]; then echo "${clash_config}"; else echo "${sing_config}"; fi)"
|
||||
log Warning "yq not found, this will update main configuration $(if [ "${bin_name}" = "clash" ]; then echo "${clash_config}"; else echo "${sing_config}"; fi)"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -156,35 +149,35 @@ update_subs() {
|
||||
# subscription clash
|
||||
if [ -n "${subscription_url_clash}" ]; then
|
||||
if [ "${update_subscription}" = "true" ]; then
|
||||
log info "daily updates subs"
|
||||
log debug "Downloading ${update_file_name}"
|
||||
log Info "daily updates subs"
|
||||
log Debug "Downloading ${update_file_name}"
|
||||
if update_file "${update_file_name}" "${subscription_url_clash}"; then
|
||||
log info "${update_file_name} saved"
|
||||
log Info "${update_file_name} saved"
|
||||
# If there is a yq command, extract the proxy information from the yml and output it to the clash_provide_config file
|
||||
if [ "${enhanced}" = "true" ]; then
|
||||
if ${yq_cmd} eval '.proxies' "${update_file_name}" >/dev/null 2>&1; then
|
||||
if ${yq_cmd} '.proxies' "${update_file_name}" >/dev/null 2>&1; then
|
||||
"${yq_cmd}" '.proxies' "${update_file_name}" > "${clash_provide_config}"
|
||||
"${yq_cmd}" -i '{"proxies": .}' "${clash_provide_config}"
|
||||
log info "subscription success"
|
||||
log info "Update subscription $(date +"%F %R")"
|
||||
if [[ -f "${update_file_name}.bak" ]]; then
|
||||
log Info "subscription success"
|
||||
log Info "Update subscription $(date +"%F %R")"
|
||||
if [ -f "${update_file_name}.bak" ]; then
|
||||
rm "${update_file_name}.bak"
|
||||
fi
|
||||
else
|
||||
log error "${update_file_name} update subscription failed"
|
||||
log Error "${update_file_name} update subscription failed"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
log error "update subscription failed"
|
||||
log Error "update subscription failed"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log warn "${bin_name} subscription url is empty..."
|
||||
log Warning "${bin_name} subscription url is empty..."
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
@@ -192,10 +185,10 @@ update_subs() {
|
||||
if [ -n "${subscription_url_sing}" ]; then
|
||||
# subscription sing-box
|
||||
if [ "${update_subscription}" = "true" ]; then
|
||||
log info "daily updates subs"
|
||||
log debug "Downloading ${update_file_name}"
|
||||
log Info "daily updates subs"
|
||||
log Debug "Downloading ${update_file_name}"
|
||||
if update_file "${update_file_name}" "${subscription_url_sing}"; then
|
||||
log info "${update_file_name} saved"
|
||||
log Info "${update_file_name} saved"
|
||||
if [ "${enhanced}" = "true" ]; then
|
||||
if "${yq_cmd}" -e . "${update_file_name}" >/dev/null 2>&1; then
|
||||
cp "${update_file_name}" "${sing_provide_config}"
|
||||
@@ -205,59 +198,140 @@ update_subs() {
|
||||
|
||||
# script to edit sing-box subscriptions
|
||||
# removed the structure: inbounds/experimental/route/log and dns
|
||||
"${yq_cmd}" eval 'del(.inbounds, .experimental, .route, .log, .dns)' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" 'del(.inbounds, .experimental, .route, .log, .dns)' -i --output-format=json "${sing_provide_config}"
|
||||
|
||||
# remove outbound with type: direct/block/dns/selector/urltest
|
||||
"${yq_cmd}" eval 'del(.outbounds[] | select(.type == "direct" or .type == "block" or .type == "dns" or .type == "selector" or .type == "urltest"))' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" 'del(.outbounds[] | select(.type == "direct" or .type == "block" or .type == "dns" or .type == "selector" or .type == "urltest"))' -i --output-format=json "${sing_provide_config}"
|
||||
|
||||
# create new outbounds with type: selector, tag: ✿✘ꕥ in ${sing_provide_config}
|
||||
"${yq_cmd}" eval '.outbounds += [{"tag": "✿✘ꕥ", "type": "selector", "outbounds": [.outbounds[].tag]}]' -i --output-format=json "${sing_provide_config}"
|
||||
# create new outbounds with type: selector, tag: ❀✿❀ in ${sing_provide_config}
|
||||
"${yq_cmd}" '.outbounds += [{"tag": "❀✿❀", "type": "selector", "outbounds": [.outbounds[].tag]}]' -i --output-format=json "${sing_provide_config}"
|
||||
|
||||
# create new outbounds with type: urltest, tag: ✿✘ꕥ[urltest] in ${sing_provide_config}
|
||||
"${yq_cmd}" eval '.outbounds += [{"tag": "✿✘ꕥ[urltest]", "type": "urltest", "url": "https://www.gstatic.com/generate_204", "interval": "3m", "outbounds": [.outbounds[].tag]}]' -i --output-format=json "${sing_provide_config}"
|
||||
# create new outbounds with type: urltest, tag: ❀✿❀[urltest] in ${sing_provide_config}
|
||||
"${yq_cmd}" '.outbounds += [{"tag": "❀✿❀[urltest]", "type": "urltest", "url": "https://www.gstatic.com/generate_204", "interval": "3m", "outbounds": [.outbounds[].tag]}]' -i --output-format=json "${sing_provide_config}"
|
||||
|
||||
# renew outbounds with tag: ✿✘ꕥ in main ${sing_config} dan ${sing_provide_config}
|
||||
"${yq_cmd}" eval 'del(.outbounds[].outbounds[] | select(. == "✿✘ꕥ"))' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" eval 'del(.outbounds[].outbounds[] | select(. == "✿✘ꕥ"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" eval '.outbounds[0].outbounds += ["✿✘ꕥ"]' -i --output-format=json "${sing_config}"
|
||||
# renew outbounds with tag: ❀✿❀ in main ${sing_config} dan ${sing_provide_config}
|
||||
"${yq_cmd}" 'del(.outbounds[].outbounds[] | select(. == "❀✿❀"))' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" 'del(.outbounds[].outbounds[] | select(. == "❀✿❀"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" '.outbounds[0].outbounds += ["❀✿❀"]' -i --output-format=json "${sing_config}"
|
||||
|
||||
# renew outbounds with tag: ✿✘ꕥ[urltest] in main ${sing_config} dan ${sing_provide_config}
|
||||
"${yq_cmd}" eval 'del(.outbounds[].outbounds[] | select(. == "✿✘ꕥ[urltest]"))' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" eval 'del(.outbounds[].outbounds[] | select(. == "✿✘ꕥ[urltest]"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" eval '.outbounds[0].outbounds += ["✿✘ꕥ[urltest]"]' -i --output-format=json "${sing_config}"
|
||||
# renew outbounds with tag: ❀✿❀[urltest] in main ${sing_config} dan ${sing_provide_config}
|
||||
"${yq_cmd}" 'del(.outbounds[].outbounds[] | select(. == "❀✿❀[urltest]"))' -i --output-format=json "${sing_provide_config}"
|
||||
"${yq_cmd}" 'del(.outbounds[].outbounds[] | select(. == "❀✿❀[urltest]"))' -i --output-format=json "${sing_config}"
|
||||
"${yq_cmd}" '.outbounds[0].outbounds += ["❀✿❀[urltest]"]' -i --output-format=json "${sing_config}"
|
||||
|
||||
log info "subscription success"
|
||||
log info "Update subscription $(date +"%F %R")"
|
||||
log Info "subscription success"
|
||||
log Info "Update subscription $(date +"%F %R")"
|
||||
else
|
||||
log error "update subscription failed"
|
||||
log error "${update_file_name} error"
|
||||
log Error "update subscription failed"
|
||||
log Error "${update_file_name} error"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
log error "update subscription failed"
|
||||
log Error "update subscription failed"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log warn "${bin_name} subscription url is empty..."
|
||||
log Warning "${bin_name} subscription url is empty..."
|
||||
return 1
|
||||
fi
|
||||
;;
|
||||
"xray" | "v2fly")
|
||||
log warn "${bin_name} does not support subscriptions.."
|
||||
log Warning "${bin_name} does not support subscriptions.."
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
update_kernel() {
|
||||
# su -c /data/adb/box/scripts/box.tool upcore
|
||||
mkdir -p "${bin_dir}/backup"
|
||||
if [ -f "${bin_dir}/${bin_name}" ]; then
|
||||
cp "${bin_dir}/${bin_name}" "${bin_dir}/backup/${bin_name}.bak" >/dev/null 2>&1
|
||||
fi
|
||||
case $(uname -m) in
|
||||
"aarch64") arch="arm64"; platform="android" ;;
|
||||
"armv7l"|"armv8l") arch="armv7"; platform="linux" ;;
|
||||
"i686") arch="386"; platform="linux" ;;
|
||||
"x86_64") arch="amd64"; platform="linux" ;;
|
||||
*) log Warning "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
# Do anything else below
|
||||
file_kernel="${bin_name}-${arch}"
|
||||
case "${bin_name}" in
|
||||
"sing-box")
|
||||
url_down="https://github.com/SagerNet/sing-box/releases"
|
||||
if [ "${singbox_releases}" = "false" ]; then
|
||||
sing_box_version_temp=$(busybox wget --no-check-certificate -qO- "${url_down}" | grep -oE '/tag/v[0-9]+\.[0-9]+-[a-z0-9]+' | head -1 | busybox awk -F'/' '{print $3}')
|
||||
else
|
||||
sing_box_version_temp=$(busybox wget --no-check-certificate -qO- "${url_down}" | grep -oE '/tag/v[0-9]+\.[0-9]+\.[0-9]+' | head -1 | busybox awk -F'/' '{print $3}')
|
||||
fi
|
||||
sing_box_version=${sing_box_version_temp#v}
|
||||
download_link="${url_down}/download/${sing_box_version_temp}/sing-box-${sing_box_version}-${platform}-${arch}.tar.gz"
|
||||
log Debug "download ${download_link}"
|
||||
update_file "${box_dir}/${file_kernel}.tar.gz" "${download_link}" && extra_kernel
|
||||
;;
|
||||
"clash")
|
||||
if [ "${meta}" = "true" ]; then
|
||||
# set download link and get the latest version
|
||||
download_link="https://github.com/MetaCubeX/Clash.Meta/releases"
|
||||
if [ "$use_ghproxy" == true ]; then
|
||||
download_link="https://ghproxy.com/${download_link}"
|
||||
fi
|
||||
# tag=$(busybox wget --no-check-certificate -qO- ${download_link} | grep -oE 'tag\/([^"]+)' | cut -d '/' -f 2 | head -1)
|
||||
tag="Prerelease-Alpha"
|
||||
latest_version=$(busybox wget --no-check-certificate -qO- "${download_link}/expanded_assets/${tag}" | grep -oE "alpha-[0-9a-z]+" | head -1)
|
||||
# set the filename based on platform and architecture
|
||||
filename="clash.meta-${platform}-${arch}-${latest_version}"
|
||||
# download and update the file
|
||||
log Debug "download ${download_link}/download/${tag}/${filename}.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "${download_link}/download/${tag}/${filename}.gz" && extra_kernel
|
||||
# if meta flag is false, download clash premium/dev
|
||||
else
|
||||
# if dev flag is true, download latest dev version
|
||||
if [ "${dev}" != "false" ]; then
|
||||
log Debug "download https://release.dreamacro.workers.dev/latest/clash-linux-${arch}-latest.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "https://release.dreamacro.workers.dev/latest/clash-linux-${arch}-latest.gz" && extra_kernel
|
||||
else
|
||||
# if dev flag is false, download latest premium version
|
||||
filename=$(busybox wget --no-check-certificate -qO- "https://github.com/Dreamacro/clash/releases/expanded_assets/premium" | grep -oE "clash-linux-${arch}-[0-9]+.[0-9]+.[0-9]+" | head -1)
|
||||
log Debug "download https://github.com/Dreamacro/clash/releases/download/premium/${filename}.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "https://github.com/Dreamacro/clash/releases/download/premium/${filename}.gz" && extra_kernel
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
"xray"|"v2fly")
|
||||
[ "${bin_name}" = "xray" ] && bin='Xray' || bin='v2ray'
|
||||
api_url="https://api.github.com/repos/$(if [ "${bin_name}" = "xray" ]; then echo "XTLS/Xray-core/releases"; else echo "v2fly/v2ray-core/releases"; fi)"
|
||||
# set download link and get the latest version
|
||||
latest_version=$(busybox wget --no-check-certificate -qO- ${api_url} | grep "tag_name" | grep -o "v[0-9.]*" | head -1)
|
||||
case $(uname -m) in
|
||||
"i386") download_file="$bin-linux-32.zip" ;;
|
||||
"x86_64") download_file="$bin-linux-64.zip" ;;
|
||||
"armv7l"|"armv8l") download_file="$bin-linux-arm32-v7a.zip" ;;
|
||||
"aarch64") download_file="$bin-android-arm64-v8a.zip" ;;
|
||||
*) log Error "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
# Do anything else below
|
||||
download_link="https://github.com/$(if [ "${bin_name}" = "xray" ]; then echo "XTLS/Xray-core/releases"; else echo "v2fly/v2ray-core/releases"; fi)"
|
||||
log Debug "Downloading ${download_link}/download/${latest_version}/${download_file}"
|
||||
update_file "${box_dir}/${file_kernel}.zip" "${download_link}/download/${latest_version}/${download_file}" && extra_kernel
|
||||
;;
|
||||
*)
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check and update kernel
|
||||
extra_kernel() {
|
||||
case "${bin_name}" in
|
||||
@@ -272,10 +346,10 @@ extra_kernel() {
|
||||
if [ -f "${box_pid}" ]; then
|
||||
restart_box
|
||||
else
|
||||
log debug "${bin_name} does not need to be restarted."
|
||||
log Debug "${bin_name} does not need to be restarted."
|
||||
fi
|
||||
else
|
||||
log error "Failed to extract or move the kernel."
|
||||
log Error "Failed to extract or move the kernel."
|
||||
fi
|
||||
;;
|
||||
"sing-box")
|
||||
@@ -290,10 +364,10 @@ extra_kernel() {
|
||||
if [ -f "${box_pid}" ]; then
|
||||
restart_box
|
||||
else
|
||||
log debug "${bin_name} does not need to be restarted."
|
||||
log Debug "${bin_name} does not need to be restarted."
|
||||
fi
|
||||
else
|
||||
log warn "Failed to extract ${box_dir}/${file_kernel}.tar.gz."
|
||||
log Warning "Failed to extract ${box_dir}/${file_kernel}.tar.gz."
|
||||
fi
|
||||
;;
|
||||
"v2fly"|"xray")
|
||||
@@ -312,18 +386,18 @@ extra_kernel() {
|
||||
if [ -f "${box_pid}" ]; then
|
||||
restart_box
|
||||
else
|
||||
log debug "${bin_name} does not need to be restarted."
|
||||
log Debug "${bin_name} does not need to be restarted."
|
||||
fi
|
||||
else
|
||||
log error "Failed to move the kernel."
|
||||
log Error "Failed to move the kernel."
|
||||
fi
|
||||
else
|
||||
log warn "Failed to extract ${box_dir}/${file_kernel}.zip."
|
||||
log Warning "Failed to extract ${box_dir}/${file_kernel}.zip."
|
||||
fi
|
||||
rm -rf "${bin_dir}/update"
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -333,101 +407,20 @@ extra_kernel() {
|
||||
chmod 6755 ${bin_path}
|
||||
}
|
||||
|
||||
update_kernel() {
|
||||
# su -c /data/adb/box/scripts/box.tool upcore
|
||||
mkdir -p "${bin_dir}/backup"
|
||||
if [ -f "${bin_dir}/${bin_name}" ]; then
|
||||
cp "${bin_dir}/${bin_name}" "${bin_dir}/backup/${bin_name}.bak" >/dev/null 2>&1
|
||||
fi
|
||||
case $(uname -m) in
|
||||
"aarch64") arch="arm64"; platform="android" ;;
|
||||
"armv7l"|"armv8l") arch="armv7"; platform="linux" ;;
|
||||
"i686") arch="386"; platform="linux" ;;
|
||||
"x86_64") arch="amd64"; platform="linux" ;;
|
||||
*) log warn "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
# Do anything else below
|
||||
file_kernel="${bin_name}-${arch}"
|
||||
case "${bin_name}" in
|
||||
"sing-box")
|
||||
url_down="https://github.com/SagerNet/sing-box/releases"
|
||||
if [ "${singbox_releases}" = "false" ]; then
|
||||
sing_box_version_temp=$(busybox wget --no-check-certificate -qO- "${url_down}" | grep -oE '/tag/v[0-9]+\.[0-9]+-[a-z0-9]+' | head -1 | busybox awk -F'/' '{print $3}')
|
||||
else
|
||||
sing_box_version_temp=$(busybox wget --no-check-certificate -qO- "${url_down}" | grep -oE '/tag/v[0-9]+\.[0-9]+\.[0-9]+' | head -1 | busybox awk -F'/' '{print $3}')
|
||||
fi
|
||||
sing_box_version=${sing_box_version_temp#v}
|
||||
download_link="${url_down}/download/${sing_box_version_temp}/sing-box-${sing_box_version}-${platform}-${arch}.tar.gz"
|
||||
log debug "download ${download_link}"
|
||||
update_file "${box_dir}/${file_kernel}.tar.gz" "${download_link}" && extra_kernel
|
||||
;;
|
||||
"clash")
|
||||
if [ "${meta}" = "true" ]; then
|
||||
# set download link and get the latest version
|
||||
download_link="https://github.com/MetaCubeX/Clash.Meta/releases"
|
||||
if [[ "$use_ghproxy" == true ]]; then
|
||||
download_link="https://ghproxy.com/${download_link}"
|
||||
fi
|
||||
# tag=$(busybox wget --no-check-certificate -qO- ${download_link} | grep -oE 'tag\/([^"]+)' | cut -d '/' -f 2 | head -1)
|
||||
tag="Prerelease-Alpha"
|
||||
latest_version=$(busybox wget --no-check-certificate -qO- "${download_link}/expanded_assets/${tag}" | grep -oE "alpha-[0-9a-z]+" | head -1)
|
||||
# set the filename based on platform and architecture
|
||||
filename="clash.meta-${platform}-${arch}-${latest_version}"
|
||||
# download and update the file
|
||||
log debug "download ${download_link}/download/${tag}/${filename}.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "${download_link}/download/${tag}/${filename}.gz" && extra_kernel
|
||||
# if meta flag is false, download clash premium/dev
|
||||
else
|
||||
# if dev flag is true, download latest dev version
|
||||
if [ "${dev}" != "false" ]; then
|
||||
log debug "download https://release.dreamacro.workers.dev/latest/clash-linux-${arch}-latest.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "https://release.dreamacro.workers.dev/latest/clash-linux-${arch}-latest.gz" && extra_kernel
|
||||
else
|
||||
# if dev flag is false, download latest premium version
|
||||
filename=$(busybox wget --no-check-certificate -qO- "https://github.com/Dreamacro/clash/releases/expanded_assets/premium" | grep -oE "clash-linux-${arch}-[0-9]+.[0-9]+.[0-9]+" | head -1)
|
||||
log debug "download https://github.com/Dreamacro/clash/releases/download/premium/${filename}.gz"
|
||||
update_file "${box_dir}/${file_kernel}.gz" "https://github.com/Dreamacro/clash/releases/download/premium/${filename}.gz" && extra_kernel
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
"xray"|"v2fly")
|
||||
[ "${bin_name}" = "xray" ] && bin='Xray' || bin='v2ray'
|
||||
api_url="https://api.github.com/repos/$(if [ "${bin_name}" = "xray" ]; then echo "XTLS/Xray-core/releases"; else echo "v2fly/v2ray-core/releases"; fi)"
|
||||
# set download link and get the latest version
|
||||
latest_version=$(busybox wget --no-check-certificate -qO- ${api_url} | grep "tag_name" | grep -o "v[0-9.]*" | head -1)
|
||||
case $(uname -m) in
|
||||
"i386") download_file="$bin-linux-32.zip" ;;
|
||||
"x86_64") download_file="$bin-linux-64.zip" ;;
|
||||
"armv7l"|"armv8l") download_file="$bin-linux-arm32-v7a.zip" ;;
|
||||
"aarch64") download_file="$bin-android-arm64-v8a.zip" ;;
|
||||
*) log error "Unsupported architecture: $(uname -m)" >&2; exit 1 ;;
|
||||
esac
|
||||
# Do anything else below
|
||||
download_link="https://github.com/$(if [ "${bin_name}" = "xray" ]; then echo "XTLS/Xray-core/releases"; else echo "v2fly/v2ray-core/releases"; fi)"
|
||||
log debug "Downloading ${download_link}/download/${latest_version}/${download_file}"
|
||||
update_file "${box_dir}/${file_kernel}.zip" "${download_link}/download/${latest_version}/${download_file}" && extra_kernel
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Check and update yacd
|
||||
update_dashboard() {
|
||||
# su -c /data/adb/box/scripts/box.tool upyacd
|
||||
if [ "${bin_name}" = "clash" -o "${bin_name}" = "sing-box" ]; then
|
||||
file_dashboard="${box_dir}/${bin_name}/dashboard.zip"
|
||||
url="https://github.com/MetaCubeX/Yacd-meta/archive/gh-pages.zip"
|
||||
if [[ "$use_ghproxy" == true ]]; then
|
||||
if [ "$use_ghproxy" == true ]; then
|
||||
url="https://ghproxy.com/${url}"
|
||||
fi
|
||||
dir_name="Yacd-meta-gh-pages"
|
||||
log debug "Download ${url}"
|
||||
log Debug "Download ${url}"
|
||||
if busybox wget --no-check-certificate "${url}" -O "${file_dashboard}" >&2; then
|
||||
if [ ! -d "${box_dir}/${bin_name}/dashboard" ]; then
|
||||
log info "dashboard folder not exist, creating it"
|
||||
log Info "dashboard folder not exist, creating it"
|
||||
mkdir "${box_dir}/${bin_name}/dashboard"
|
||||
else
|
||||
rm -rf "${box_dir}/${bin_name}/dashboard/"*
|
||||
@@ -442,52 +435,42 @@ update_dashboard() {
|
||||
rm -f "${file_dashboard}"
|
||||
rm -rf "${box_dir}/${bin_name}/dashboard/${dir_name}"
|
||||
else
|
||||
log error "Failed to download dashboard" >&2
|
||||
log Error "Failed to download dashboard" >&2
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
log debug "${bin_name} does not support dashboards"
|
||||
log Debug "${bin_name} does not support dashboards"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function for detecting ports used by a process
|
||||
port_detection() {
|
||||
sleep 1.5
|
||||
sleep 1
|
||||
# Use 'command' function to check availability of 'ss'
|
||||
if command -v ss > /dev/null ; then
|
||||
# Use 'awk' with a regular expression to match the process ID
|
||||
ports=$(ss -antup | busybox awk -v pid="$(busybox pidof "${bin_name}")" '$7 ~ pid {print $5}' | busybox awk -F ':' '{print $2}' | sort -u) >/dev/null 2>&1
|
||||
else
|
||||
# Note the warning message if 'ss' is not available
|
||||
log debug "ss command not found, skipping port detection." >&2
|
||||
return
|
||||
fi
|
||||
# Make a note of the detected ports
|
||||
now=$(date +"%I:%M %p")
|
||||
if busybox pidof "${bin_name}" >/dev/null 2>&1; then
|
||||
if [ -t 1 ]; then
|
||||
echo -n "${orange}${now} [debug]: ${bin_name} port detected: ${normal}"
|
||||
else
|
||||
echo -n "${now} [debug]: ${bin_name} port detected: " | tee -a "${box_log}" >> /dev/null 2>&1
|
||||
fi
|
||||
# write ports
|
||||
while read -r port; do
|
||||
sleep 0.5
|
||||
ports=$(ss -antup | busybox awk -v PID="$(busybox pidof "${bin_name}")" '$7 ~ PID {print $5}' | busybox awk -F ':' '{print $2}' | sort -u) >/dev/null 2>&1
|
||||
# Make a note of the detected ports
|
||||
if busybox pidof "${bin_name}" >/dev/null 2>&1; then
|
||||
if [ -t 1 ]; then
|
||||
echo -n "${red}${port} $normal"
|
||||
echo -n "${orange}${now} [debug]: ${bin_name} port detected:${normal}"
|
||||
else
|
||||
echo -n "${port} " | tee -a "${box_log}" >> /dev/null 2>&1
|
||||
echo -n "${now} [debug]: ${bin_name} port detected:" | tee -a "${box_log}" >> /dev/null 2>&1
|
||||
fi
|
||||
done <<< "${ports}"
|
||||
# Add a newline to the output if running in terminal
|
||||
if [ -t 1 ]; then
|
||||
echo -e "\033[1;31m""\033[0m"
|
||||
# write ports
|
||||
while read -r port; do
|
||||
sleep 0.5
|
||||
[ -t 1 ] && (echo -n "${red}${port}|$normal") || (echo -n "${port}|" | tee -a "${box_log}" >> /dev/null 2>&1)
|
||||
done <<< "${ports}"
|
||||
# Add a newline to the output if running in terminal
|
||||
[ -t 1 ] && echo -e "\033[1;31m""\033[0m" || echo "" >> "${box_log}" 2>&1
|
||||
else
|
||||
echo "" >> "${box_log}" 2>&1
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log Debug "ss command not found, skipping port detection." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -496,40 +479,40 @@ port_detection() {
|
||||
cgroup_limit() {
|
||||
# Check if the cgroup memory limit has been set.
|
||||
if [ -z "${cgroup_memory_limit}" ]; then
|
||||
log warn "cgroup_memory_limit is not set"
|
||||
log Warning "cgroup_memory_limit is not set"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if the cgroup memory path is set and exists.
|
||||
if [ -z "${cgroup_memory_path}" ]; then
|
||||
local cgroup_memory_path=$(mount | grep cgroup | busybox awk '/memory/{print $3}' | head -1)
|
||||
if [ -z "${cgroup_memory_path}" ]; then
|
||||
log warn "cgroup_memory_path is not set and could not be found"
|
||||
log Warning "cgroup_memory_path is not set and could not be found"
|
||||
return 1
|
||||
fi
|
||||
elif [ ! -d "${cgroup_memory_path}" ]; then
|
||||
log warn "${cgroup_memory_path} does not exist"
|
||||
else
|
||||
log Warning "Leave the 'cgroup_memory_path' field empty to obtain the path."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Check if box_pid is set and exists.
|
||||
if [ -z "${box_pid}" ]; then
|
||||
log warn "box_pid is not set"
|
||||
return 1
|
||||
elif [ ! -f "${box_pid}" ]; then
|
||||
log warn "${box_pid} does not exist"
|
||||
if [ ! -f "${box_pid}" ]; then
|
||||
log Warning "${box_pid} does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Create cgroup directory and move process to cgroup.
|
||||
local bin_name=${bin_name}
|
||||
bin_name=${bin_name}
|
||||
# local bin_name=$(basename "$0")
|
||||
mkdir -p "${cgroup_memory_path}/${bin_name}"
|
||||
local pid=$(cat "${box_pid}")
|
||||
local PID=$(<"${box_pid}" 2>/dev/null)
|
||||
|
||||
if [ ! -z "${pid}" ]; then
|
||||
echo "${pid}" > "${cgroup_memory_path}/${bin_name}/cgroup.procs" \
|
||||
&& log info "Moved process ${pid} to ${cgroup_memory_path}/${bin_name}/cgroup.procs"
|
||||
if [ ! -z "$PID" ]; then
|
||||
echo "$PID" > "${cgroup_memory_path}/${bin_name}/cgroup.procs" \
|
||||
&& log Info "Moved process $PID to ${cgroup_memory_path}/${bin_name}/cgroup.procs"
|
||||
# Set memory limit for cgroups.
|
||||
echo "${cgroup_memory_limit}" > "${cgroup_memory_path}/${bin_name}/memory.limit_in_bytes" \
|
||||
&& log info "Set memory limit to ${cgroup_memory_limit} for ${cgroup_memory_path}/${bin_name}/memory.limit_in_bytes"
|
||||
&& log Info "Set memory limit to ${cgroup_memory_limit} for ${cgroup_memory_path}/${bin_name}/memory.limit_in_bytes"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
@@ -541,29 +524,29 @@ rconf() {
|
||||
# su -c /data/adb/box/scripts/box.tool rconf
|
||||
case "${bin_name}" in
|
||||
sing-box)
|
||||
if ${bin_path} check -D "${box_dir}/${bin_name}" --config-directory "${box_dir}/sing-box" > "${box_run}/${bin_name}-report.log" 2>&1; then
|
||||
log info "config.json passed"
|
||||
if ${bin_path} check -D "${box_dir}/${bin_name}" --config-directory "${box_dir}/sing-box" > "${box_run}/${bin_name}.err.log" 2>&1; then
|
||||
log Info "${sing_config} passed"
|
||||
reload
|
||||
else
|
||||
log error "config.json check failed"
|
||||
cat "${box_run}/${bin_name}-report.log" >&2
|
||||
log Debug "${sing_config}"
|
||||
log Error "$(<"${box_run}/${bin_name}.err.log")" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
clash)
|
||||
if ${bin_path} -t -d "${box_dir}/clash" -f "${clash_config}" > "${box_run}/${bin_name}-report.log" 2>&1; then
|
||||
log info "config.yaml passed"
|
||||
if ${bin_path} -t -d "${box_dir}/clash" -f "${clash_config}" > "${box_run}/${bin_name}.err.log" 2>&1; then
|
||||
log Info "${clash_config} passed"
|
||||
if [ -t 1 ] && [ "${meta}" = "true" ]; then
|
||||
reload
|
||||
fi
|
||||
else
|
||||
log error "config.yaml check failed"
|
||||
cat "${box_run}/${bin_name}-report.log" >&2
|
||||
info debug "${clash_config}"
|
||||
log Error "$(<"${box_run}/${bin_name}.err.log")" >&2
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
log error "<${bin_name}> unknown binary."
|
||||
log Error "<${bin_name}> unknown binary."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -575,7 +558,7 @@ reload() {
|
||||
case "${bin_name}" in
|
||||
sing-box)
|
||||
if kill -SIGHUP "$(busybox pidof sing-box)" >/dev/null 2>&1; then
|
||||
log debug "Restart with -SIGHUP done"
|
||||
log Debug "Restart with -SIGHUP done"
|
||||
return 0
|
||||
else
|
||||
flag=true
|
||||
@@ -586,7 +569,7 @@ reload() {
|
||||
ip_port=$(busybox awk '/external-controller:/ {print $2}' "${clash_config}") >/dev/null 2>&1
|
||||
secret=$(busybox awk '/secret:/ {print $2}' "${clash_config}") >/dev/null 2>&1
|
||||
if busybox wget --header="Authorization: Bearer ${secret}" --post-data "" -O /dev/null "http://${ip_port}/restart" >/dev/null 2>&1; then
|
||||
log debug "Restart with clash.meta api done"
|
||||
log Debug "Restart with clash.meta api done"
|
||||
return 0
|
||||
else
|
||||
flag=true
|
||||
@@ -606,7 +589,6 @@ case "$1" in
|
||||
;;
|
||||
upyacd)
|
||||
if update_dashboard; then
|
||||
sleep 0.75
|
||||
busybox pidof "${bin_name}" >/dev/null 2>&1 && open_yacd
|
||||
fi
|
||||
;;
|
||||
@@ -643,7 +625,6 @@ case "$1" in
|
||||
;;
|
||||
geosub)
|
||||
update_geox
|
||||
sleep 0.5
|
||||
update_subs
|
||||
if ! reload; then
|
||||
if [ -f "${box_pid}" ] && [ "${bin_name}" != "clash" ] && [ "${flag}" = "true" ]; then
|
||||
|
||||
@@ -21,24 +21,37 @@ refresh_box() {
|
||||
}
|
||||
|
||||
start_service() {
|
||||
if [ ! -f "/data/adb/box/manual" ]; then
|
||||
if [ ! -f "${moddir}/disable" ]; then
|
||||
"${scripts_dir}/box.service" start >> "/dev/null" 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
if [ -f "/data/adb/box/run/box.pid" ]; then
|
||||
enable_iptables() {
|
||||
PIDS=("clash" "xray" "sing-box" "v2fly")
|
||||
PID=""
|
||||
i=0
|
||||
while [ -z "$PID" ] && [ "$i" -lt "${#PIDS[@]}" ]; do
|
||||
PID=$(${busybox} pidof "${PIDS[$i]}")
|
||||
i=$((i+1))
|
||||
done
|
||||
|
||||
if [ -n "$PID" ]; then
|
||||
"${scripts_dir}/box.iptables" enable >> "/dev/null" 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
for pid in $(pidof inotifyd); do
|
||||
if grep -q box.inotify /proc/${pid}/cmdline; then
|
||||
start_inotifyd() {
|
||||
for PID in $(${busybox} pidof inotifyd); do
|
||||
if grep -q box.inotify /proc/$PID/cmdline; then
|
||||
kill -15 ${pid}
|
||||
fi
|
||||
done
|
||||
sleep 0.3
|
||||
inotifyd "${scripts_dir}/box.inotify" "${moddir}" >> "/dev/null" 2>&1 &
|
||||
fi
|
||||
}
|
||||
|
||||
refresh_box
|
||||
start_service
|
||||
if [ ! -f "/data/adb/box/manual" ]; then
|
||||
start_service
|
||||
enable_iptables
|
||||
start_inotifyd
|
||||
fi
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
export PATH="/data/adb/magisk:/data/adb/ksu/bin:$PATH:/system/bin"
|
||||
|
||||
# Take the current time
|
||||
now=$(date +"%I:%M %p")
|
||||
|
||||
# define the settings and paths
|
||||
settings="/data/adb/box/settings.ini"
|
||||
|
||||
@@ -44,7 +47,7 @@ ignore_out_list=()
|
||||
|
||||
# Set cgroup to limit memory usage
|
||||
cgroup_memory="false"
|
||||
cgroup_memory_limit="50M"
|
||||
cgroup_memory_limit="20M"
|
||||
cgroup_memory_path=""
|
||||
|
||||
# Set box directory variables
|
||||
@@ -101,24 +104,22 @@ white="\033[1;37"
|
||||
gray="\033[1;90m"
|
||||
|
||||
log() {
|
||||
# Take the current time
|
||||
now=$(date +"%I:%M %p")
|
||||
# Selects the text color according to the parameters
|
||||
case $1 in
|
||||
info) color="${blue}" ;;
|
||||
error) color="${red}" ;;
|
||||
warn) color="${yellow}" ;;
|
||||
*) color="${green}" ;;
|
||||
esac
|
||||
# Add messages to time and parameters
|
||||
message="${now} [$1]: $2"
|
||||
if [ -t 1 ]; then
|
||||
# Prints messages to the console
|
||||
echo -e "${color}${message}${normal}"
|
||||
else
|
||||
# Print messages to a log file
|
||||
echo "${message}" >> ${box_log} 2>&1
|
||||
fi
|
||||
# Selects the text color according to the parameters
|
||||
case $1 in
|
||||
info) color="${blue}" ;;
|
||||
error) color="${red}" ;;
|
||||
warn) color="${yellow}" ;;
|
||||
*) color="${green}" ;;
|
||||
esac
|
||||
# Add messages to time and parameters
|
||||
message="${now} [$1]: $2"
|
||||
if [ -t 1 ]; then
|
||||
# Prints messages to the console
|
||||
echo -e "${color}${message}${normal}"
|
||||
else
|
||||
# Print messages to a log file
|
||||
echo "${message}" >> ${box_log} 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
# open yacd on start
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
"clash_api": {
|
||||
"external_controller": "127.0.0.1:9090",
|
||||
"external_ui": "./dashboard",
|
||||
"store_selected": false
|
||||
"store_selected": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user