Adapting the Scripts

This commit is contained in:
taamarin
2023-06-27 13:07:21 +07:00
committed by shioeri
parent 767a954db2
commit e6516c80d8
7 changed files with 618 additions and 581 deletions

View File

@@ -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

View File

@@ -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}"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -92,7 +92,7 @@
"clash_api": {
"external_controller": "127.0.0.1:9090",
"external_ui": "./dashboard",
"store_selected": false
"store_selected": true
}
}
}