Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#!/bin/sh

PKG_DEPS="xray-core v2ray-geoip v2ray-geosite chinadns-ng tcping geoview"
KMODS="kmod-nft-socket kmod-nft-tproxy kmod-nft-nat"
API_SB="https://api.github.com/repos/SagerNet/sing-box/releases/latest"
API_PW="https://api.github.com/repos/Openwrt-Passwall/openwrt-passwall2/releases/latest"
TMP_DIR="/tmp/passwall_install"

C_GREEN="\033[32;1m"
C_WARN="\033[33;1m"
C_ERR="\033[31;1m"
C_RESET="\033[0m"


msg() { printf "${C_GREEN}%s${C_RESET}\n" "$1"; }
warn() { printf "${C_WARN}%s${C_RESET}\n" "$1"; }
err() { printf "${C_ERR}%s${C_RESET}\n" "$1"; exit 1; }

is_installed() {
opkg list-installed | grep -q "^$1 "
}

ask() {
local prompt="$1"
local def="$2"
local suffix="[Y/n]"
[ "$def" = "N" ] && suffix="[y/N]"

printf "${C_GREEN}%s %s: ${C_RESET}" "$prompt" "$suffix"
read -r ans
[ -z "$ans" ] && ans="$def"
case "$ans" in [yY]*) return 0 ;; *) return 1 ;; esac
}

get_json_val() {
wget --no-check-certificate -qO- "$1" | grep -o "$2" | head -n 1
}

prepare_system() {
msg "Checking system prerequisites..."

# 1. Unzip Check
if ! is_installed "unzip"; then
msg "Installing unzip utility..."
opkg install unzip || err "Failed to install unzip"
fi

# 2. DNSMasq Check: Replace basic dnsmasq with dnsmasq-full
if ! is_installed "dnsmasq-full"; then
if is_installed "dnsmasq"; then
msg "Removing basic dnsmasq to replace with full version..."
opkg remove dnsmasq
fi
msg "Installing dnsmasq-full..."
opkg install dnsmasq-full || err "Failed to install dnsmasq-full"
fi

# 3. Kernel Modules Check
for kmod in $KMODS; do
if ! is_installed "$kmod"; then
msg "Installing module: $kmod..."
opkg install "$kmod" || warn "Failed to install $kmod (might be missing in repo)"
fi
done
}

install_dep_from_zip() {
local pkg="$1"
local zip="$2"

if is_installed "$pkg"; then
return
fi

if unzip -l "$zip" | grep -q "$pkg"; then
unzip -jo "$zip" "*${pkg}*.ipk" -d "$TMP_DIR" >/dev/null 2>&1
local ipk
ipk=$(find "$TMP_DIR" -name "*${pkg}*.ipk" | head -n 1)

if [ -n "$ipk" ]; then
msg "Installing $pkg..."
opkg install "$ipk" --force-overwrite
rm -f "$ipk"
else
warn "Extracted $pkg but ipk file not found."
fi
else
warn "Package $pkg not found in the downloaded archive."
fi
}

install_singbox() {
local arch="$1"
if is_installed "sing-box"; then
return
fi

msg "Fetching Sing-box URL..."
local url
url=$(get_json_val "$API_SB" "https://[^\"]*sing-box_[^\"]*_openwrt_${arch}\.ipk")
[ -z "$url" ] && url=$(get_json_val "$API_SB" "https://[^\"]*sing-box_[^\"]*_${arch}\.ipk")

if [ -n "$url" ]; then
msg "Installing Sing-box from $url..."
opkg install "$url" --force-overwrite
else
warn "Sing-box package not found for architecture: $arch"
fi
}

main() {
rm -rf "$TMP_DIR" && mkdir -p "$TMP_DIR"

ask "Install sing-box?" "Y" && DO_SB=1
ask "Install hysteria?" "N" && DO_HY=1

msg "Updating package feeds..."
opkg update
prepare_system

# Detect architecture
local arch
arch=$(opkg print-architecture | awk '$2!="all" {print $2}' | tail -n1)
[ -z "$arch" ] && err "Failed to detect architecture."
msg "Detected architecture: $arch"

# Fetch Passwall release info
msg "Fetching Passwall release info..."
local json_pw
json_pw=$(wget --no-check-certificate -qO- "$API_PW")

local zip_url
zip_url=$(echo "$json_pw" | grep -o "https://[^\"]*passwall_packages_ipk_${arch}\.zip" | head -n 1)
[ -z "$zip_url" ] && zip_url=$(echo "$json_pw" | grep -o "https://[^\"]*passwall_packages_ipk_.*generic\.zip" | head -n 1)

[ -z "$zip_url" ] && err "Dependencies ZIP URL not found in release data."

# Download dependencies
msg "Downloading dependencies archive..."
wget --no-check-certificate -O "$TMP_DIR/deps.zip" "$zip_url" || err "Download failed."

# Install dependencies
for pkg in $PKG_DEPS; do
install_dep_from_zip "$pkg" "$TMP_DIR/deps.zip"
done

if [ "$DO_HY" = "1" ]; then
install_dep_from_zip "hysteria" "$TMP_DIR/deps.zip"
fi

if [ "$DO_SB" = "1" ]; then
install_singbox "$arch"
fi

# Install LuCI
local luci_url
luci_url=$(echo "$json_pw" | grep -o "https://[^\"]*luci-app-passwall2[^\"]*_all\.ipk" | head -n 1)

if [ -n "$luci_url" ]; then
msg "Installing LuCI app Passwall2..."
opkg install "$luci_url" --force-overwrite
else
err "LuCI package not found in release data."
fi

# Final cleanup
rm -rf "$TMP_DIR"
msg "Installation complete!"
}

main
2 changes: 1 addition & 1 deletion luci-app-passwall2/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.1.16
PKG_VERSION:=26.1.18
PKG_RELEASE:=1
PKG_PO_VERSION:=$(PKG_VERSION)

Expand Down
13 changes: 13 additions & 0 deletions luci-app-passwall2/luasrc/passwall2/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ CACHE_PATH = "/tmp/etc/passwall2_tmp"
TMP_PATH = "/tmp/etc/" .. appname
TMP_IFACE_PATH = TMP_PATH .. "/iface"

NEW_PORT = nil

local lang = conf.main.lang or "auto"
if lang == "auto" then
local auto_lang = uci:get(appname, "@global[0]", "auto_lang")
Expand Down Expand Up @@ -110,12 +112,23 @@ end
function set_cache_var(key, val)
sys.call(string.format('. /usr/share/passwall2/utils.sh ; set_cache_var %s "%s"', key, val))
end

function get_cache_var(key)
local val = sys.exec(string.format('. /usr/share/passwall2/utils.sh ; echo -n $(get_cache_var %s)', key))
if val == "" then val = nil end
return val
end

function get_new_port()
local cmd_format = ". /usr/share/passwall2/utils.sh ; echo -n $(get_new_port %s tcp,udp)"
local set_port = 0
if NEW_PORT and tonumber(NEW_PORT) then
set_port = tonumber(NEW_PORT) + 1
end
NEW_PORT = tonumber(sys.exec(string.format(cmd_format, set_port == 0 and "auto" or set_port)))
return NEW_PORT
end

function exec_call(cmd)
local process = io.popen(cmd .. '; echo -e "\n$?"')
local lines = {}
Expand Down
Loading