Hardened dependencies, added space-safe path quoting, and improved Rocky Linux/RHEL 9 support.
This commit is contained in:
171
conduit.sh
171
conduit.sh
@@ -33,7 +33,7 @@ fi
|
|||||||
|
|
||||||
VERSION="1.0.1"
|
VERSION="1.0.1"
|
||||||
CONDUIT_IMAGE="ghcr.io/ssmirr/conduit/conduit:d8522a8"
|
CONDUIT_IMAGE="ghcr.io/ssmirr/conduit/conduit:d8522a8"
|
||||||
INSTALL_DIR="/opt/conduit"
|
INSTALL_DIR="${INSTALL_DIR:-/opt/conduit}"
|
||||||
FORCE_REINSTALL=false
|
FORCE_REINSTALL=false
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
@@ -146,6 +146,11 @@ detect_os() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log_info "Detected: $OS ($OS_FAMILY family), Package manager: $PKG_MANAGER"
|
log_info "Detected: $OS ($OS_FAMILY family), Package manager: $PKG_MANAGER"
|
||||||
|
|
||||||
|
if command -v podman &>/dev/null && ! command -v docker &>/dev/null; then
|
||||||
|
log_warn "Podman detected. This script is optimized for Docker."
|
||||||
|
log_warn "If installation fails, consider installing 'docker-ce' manually."
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
install_package() {
|
install_package() {
|
||||||
@@ -154,23 +159,54 @@ install_package() {
|
|||||||
|
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt)
|
apt)
|
||||||
apt-get update -qq 2>/dev/null
|
# Make update failure non-fatal but log it
|
||||||
apt-get install -y -qq "$package" 2>/dev/null
|
apt-get update -q || log_warn "apt-get update failed, attempting to install regardless..."
|
||||||
|
if apt-get install -y -q "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
dnf)
|
dnf)
|
||||||
dnf install -y -q "$package" 2>/dev/null
|
if dnf install -y -q "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
yum)
|
yum)
|
||||||
yum install -y -q "$package" 2>/dev/null
|
if yum install -y -q "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
pacman)
|
pacman)
|
||||||
pacman -Sy --noconfirm "$package" 2>/dev/null
|
if pacman -Sy --noconfirm "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
zypper)
|
zypper)
|
||||||
zypper install -y -n "$package" 2>/dev/null
|
if zypper install -y -n "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
apk)
|
apk)
|
||||||
apk add --no-cache "$package" 2>/dev/null
|
if apk add --no-cache "$package"; then
|
||||||
|
log_success "$package installed successfully"
|
||||||
|
else
|
||||||
|
log_error "Failed to install $package"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
log_warn "Unknown package manager. Please install $package manually."
|
log_warn "Unknown package manager. Please install $package manually."
|
||||||
@@ -196,28 +232,28 @@ check_dependencies() {
|
|||||||
# Check for basic tools
|
# Check for basic tools
|
||||||
if ! command -v awk &>/dev/null; then
|
if ! command -v awk &>/dev/null; then
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt) install_package gawk ;;
|
apt) install_package gawk || log_warn "Could not install gawk" ;;
|
||||||
apk) install_package gawk ;;
|
apk) install_package gawk || log_warn "Could not install gawk" ;;
|
||||||
*) install_package awk ;;
|
*) install_package awk || log_warn "Could not install awk" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for free command
|
# Check for free command
|
||||||
if ! command -v free &>/dev/null; then
|
if ! command -v free &>/dev/null; then
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt|dnf|yum) install_package procps ;;
|
apt|dnf|yum) install_package procps || log_warn "Could not install procps" ;;
|
||||||
pacman) install_package procps-ng ;;
|
pacman) install_package procps-ng || log_warn "Could not install procps" ;;
|
||||||
zypper) install_package procps ;;
|
zypper) install_package procps || log_warn "Could not install procps" ;;
|
||||||
apk) install_package procps ;;
|
apk) install_package procps || log_warn "Could not install procps" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check for tput (ncurses)
|
# Check for tput (ncurses)
|
||||||
if ! command -v tput &>/dev/null; then
|
if ! command -v tput &>/dev/null; then
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt) install_package ncurses-bin ;;
|
apt) install_package ncurses-bin || log_warn "Could not install ncurses-bin" ;;
|
||||||
apk) install_package ncurses ;;
|
apk) install_package ncurses || log_warn "Could not install ncurses" ;;
|
||||||
*) install_package ncurses ;;
|
*) install_package ncurses || log_warn "Could not install ncurses" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -229,18 +265,22 @@ check_dependencies() {
|
|||||||
# Check for GeoIP tools
|
# Check for GeoIP tools
|
||||||
if ! command -v geoiplookup &>/dev/null; then
|
if ! command -v geoiplookup &>/dev/null; then
|
||||||
case "$PKG_MANAGER" in
|
case "$PKG_MANAGER" in
|
||||||
apt) install_package geoip-bin ;;
|
apt)
|
||||||
|
# geoip-bin is becoming legacy in some Ubuntu versions, but still works in many.
|
||||||
|
# If it fails, we warn but don't stop the whole script if other things work.
|
||||||
|
install_package geoip-bin || log_warn "Could not install geoip-bin. Live peer map may not show countries."
|
||||||
|
;;
|
||||||
dnf|yum)
|
dnf|yum)
|
||||||
# On RHEL/CentOS
|
# On RHEL/CentOS
|
||||||
if ! rpm -q epel-release &>/dev/null; then
|
if ! rpm -q epel-release &>/dev/null; then
|
||||||
log_info "Enabling EPEL repository for GeoIP..."
|
log_info "Enabling EPEL repository for GeoIP..."
|
||||||
$PKG_MANAGER install -y epel-release &>/dev/null || true
|
$PKG_MANAGER install -y epel-release &>/dev/null || true
|
||||||
fi
|
fi
|
||||||
install_package GeoIP
|
install_package GeoIP || log_warn "Could not install GeoIP."
|
||||||
;;
|
;;
|
||||||
pacman) install_package geoip ;;
|
pacman) install_package geoip || log_warn "Could not install geoip." ;;
|
||||||
zypper) install_package GeoIP ;;
|
zypper) install_package GeoIP || log_warn "Could not install GeoIP." ;;
|
||||||
apk) install_package geoip ;;
|
apk) install_package geoip || log_warn "Could not install geoip." ;;
|
||||||
*) log_warn "Could not install geoiplookup automatically" ;;
|
*) log_warn "Could not install geoiplookup automatically" ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
@@ -413,6 +453,13 @@ install_docker() {
|
|||||||
|
|
||||||
log_info "Installing Docker..."
|
log_info "Installing Docker..."
|
||||||
|
|
||||||
|
# Check OS family for specific requirements
|
||||||
|
if [ "$OS_FAMILY" = "rhel" ]; then
|
||||||
|
log_info "Installing RHEL-specific Docker dependencies..."
|
||||||
|
$PKG_MANAGER install -y -q dnf-plugins-core 2>/dev/null || true
|
||||||
|
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 2>/dev/null || true
|
||||||
|
fi
|
||||||
|
|
||||||
# Alpine
|
# Alpine
|
||||||
if [ "$OS_FAMILY" = "alpine" ]; then
|
if [ "$OS_FAMILY" = "alpine" ]; then
|
||||||
apk add --no-cache docker docker-cli-compose 2>/dev/null
|
apk add --no-cache docker docker-cli-compose 2>/dev/null
|
||||||
@@ -420,7 +467,11 @@ install_docker() {
|
|||||||
service docker start 2>/dev/null || rc-service docker start 2>/dev/null || true
|
service docker start 2>/dev/null || rc-service docker start 2>/dev/null || true
|
||||||
else
|
else
|
||||||
# Use official Docker install
|
# Use official Docker install
|
||||||
curl -fsSL https://get.docker.com | sh
|
if ! curl -fsSL https://get.docker.com | sh; then
|
||||||
|
log_error "Official Docker installation script failed."
|
||||||
|
log_info "Try installing docker manually: https://docs.docker.com/engine/install/"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Enable and start Docker
|
# Enable and start Docker
|
||||||
if [ "$HAS_SYSTEMD" = "true" ]; then
|
if [ "$HAS_SYSTEMD" = "true" ]; then
|
||||||
@@ -458,7 +509,14 @@ install_docker() {
|
|||||||
run_conduit() {
|
run_conduit() {
|
||||||
log_info "Starting Conduit container..."
|
log_info "Starting Conduit container..."
|
||||||
|
|
||||||
# Stop existing container
|
# Check for existing conduit containers (any image containing conduit)
|
||||||
|
local existing=$(docker ps -a --filter "ancestor=ghcr.io/ssmirr/conduit/conduit" --format "{{.Names}}")
|
||||||
|
if [ -n "$existing" ] && [ "$existing" != "conduit" ]; then
|
||||||
|
log_warn "Detected other Conduit containers: $existing"
|
||||||
|
log_warn "Running multiple instances may cause port conflicts."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Stop existing container with our name
|
||||||
docker rm -f conduit 2>/dev/null || true
|
docker rm -f conduit 2>/dev/null || true
|
||||||
|
|
||||||
# Pull image
|
# Pull image
|
||||||
@@ -494,7 +552,7 @@ run_conduit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
save_settings() {
|
save_settings() {
|
||||||
mkdir -p $INSTALL_DIR
|
mkdir -p "$INSTALL_DIR"
|
||||||
|
|
||||||
# Save settings
|
# Save settings
|
||||||
cat > "$INSTALL_DIR/settings.conf" << EOF
|
cat > "$INSTALL_DIR/settings.conf" << EOF
|
||||||
@@ -515,7 +573,8 @@ setup_autostart() {
|
|||||||
|
|
||||||
if [ "$HAS_SYSTEMD" = "true" ]; then
|
if [ "$HAS_SYSTEMD" = "true" ]; then
|
||||||
# Systemd-based systems
|
# Systemd-based systems
|
||||||
cat > /etc/systemd/system/conduit.service << 'EOF'
|
local docker_path=$(command -v docker)
|
||||||
|
cat > /etc/systemd/system/conduit.service << EOF
|
||||||
[Unit]
|
[Unit]
|
||||||
Description=Psiphon Conduit Service
|
Description=Psiphon Conduit Service
|
||||||
After=network.target docker.service
|
After=network.target docker.service
|
||||||
@@ -524,8 +583,8 @@ Requires=docker.service
|
|||||||
[Service]
|
[Service]
|
||||||
Type=oneshot
|
Type=oneshot
|
||||||
RemainAfterExit=yes
|
RemainAfterExit=yes
|
||||||
ExecStart=/usr/bin/docker start conduit
|
ExecStart=$docker_path start conduit
|
||||||
ExecStop=/usr/bin/docker stop conduit
|
ExecStop=$docker_path stop conduit
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -613,7 +672,10 @@ EOF
|
|||||||
#═══════════════════════════════════════════════════════════════════════
|
#═══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
create_management_script() {
|
create_management_script() {
|
||||||
cat > $INSTALL_DIR/conduit << 'MANAGEMENT'
|
# Generate the management script.
|
||||||
|
# Note: We use a placeholder for INSTALL_DIR that we'll replace with sed
|
||||||
|
# to avoid complex escaping in the heredoc while keeping it dynamic.
|
||||||
|
cat > "$INSTALL_DIR/conduit" << 'MANAGEMENT'
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
#
|
#
|
||||||
# Psiphon Conduit Manager
|
# Psiphon Conduit Manager
|
||||||
@@ -621,7 +683,7 @@ create_management_script() {
|
|||||||
#
|
#
|
||||||
|
|
||||||
VERSION="1.0.1"
|
VERSION="1.0.1"
|
||||||
INSTALL_DIR="/opt/conduit"
|
INSTALL_DIR="REPLACE_ME_INSTALL_DIR"
|
||||||
CONDUIT_IMAGE="ghcr.io/ssmirr/conduit/conduit:d8522a8"
|
CONDUIT_IMAGE="ghcr.io/ssmirr/conduit/conduit:d8522a8"
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
@@ -957,7 +1019,7 @@ show_peers() {
|
|||||||
|
|
||||||
echo -ne "\033[?25h" # Show cursor
|
echo -ne "\033[?25h" # Show cursor
|
||||||
tput rmcup 2>/dev/null || true
|
tput rmcup 2>/dev/null || true
|
||||||
rm -f /tmp/conduit_peers_current
|
rm -f /tmp/conduit_peers_current /tmp/conduit_peers_next
|
||||||
trap - SIGINT SIGTERM
|
trap - SIGINT SIGTERM
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1196,7 +1258,7 @@ change_settings() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Save settings
|
# Save settings
|
||||||
cat > $INSTALL_DIR/settings.conf << EOF
|
cat > "$INSTALL_DIR/settings.conf" << EOF
|
||||||
MAX_CLIENTS=$MAX_CLIENTS
|
MAX_CLIENTS=$MAX_CLIENTS
|
||||||
BANDWIDTH=$BANDWIDTH
|
BANDWIDTH=$BANDWIDTH
|
||||||
EOF
|
EOF
|
||||||
@@ -1261,19 +1323,19 @@ uninstall_all() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "[INFO] Stopping Conduit container..."
|
echo -e "${BLUE}[INFO]${NC} Stopping Conduit container..."
|
||||||
docker stop conduit 2>/dev/null || true
|
docker stop conduit 2>/dev/null || true
|
||||||
|
|
||||||
echo "[INFO] Removing Conduit container..."
|
echo -e "${BLUE}[INFO]${NC} Removing Conduit container..."
|
||||||
docker rm -f conduit 2>/dev/null || true
|
docker rm -f conduit 2>/dev/null || true
|
||||||
|
|
||||||
echo "[INFO] Removing Conduit Docker image..."
|
echo -e "${BLUE}[INFO]${NC} Removing Conduit Docker image..."
|
||||||
docker rmi $CONDUIT_IMAGE 2>/dev/null || true
|
docker rmi "$CONDUIT_IMAGE" 2>/dev/null || true
|
||||||
|
|
||||||
echo "[INFO] Removing Conduit data volume..."
|
echo -e "${BLUE}[INFO]${NC} Removing Conduit data volume..."
|
||||||
docker volume rm conduit-data 2>/dev/null || true
|
docker volume rm conduit-data 2>/dev/null || true
|
||||||
|
|
||||||
echo "[INFO] Removing auto-start service..."
|
echo -e "${BLUE}[INFO]${NC} Removing auto-start service..."
|
||||||
# Systemd
|
# Systemd
|
||||||
systemctl stop conduit.service 2>/dev/null || true
|
systemctl stop conduit.service 2>/dev/null || true
|
||||||
systemctl disable conduit.service 2>/dev/null || true
|
systemctl disable conduit.service 2>/dev/null || true
|
||||||
@@ -1287,8 +1349,8 @@ uninstall_all() {
|
|||||||
chkconfig conduit off 2>/dev/null || true
|
chkconfig conduit off 2>/dev/null || true
|
||||||
rm -f /etc/init.d/conduit
|
rm -f /etc/init.d/conduit
|
||||||
|
|
||||||
echo "[INFO] Removing configuration files..."
|
echo -e "${BLUE}[INFO]${NC} Removing configuration files..."
|
||||||
rm -rf /opt/conduit
|
rm -rf "$INSTALL_DIR"
|
||||||
rm -f /usr/local/bin/conduit
|
rm -f /usr/local/bin/conduit
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -1298,8 +1360,7 @@ uninstall_all() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Conduit and all related components have been removed."
|
echo "Conduit and all related components have been removed."
|
||||||
echo ""
|
echo ""
|
||||||
echo "Note: Docker itself was NOT removed. To remove Docker:"
|
echo "Note: Docker itself was NOT removed."
|
||||||
echo " apt-get purge docker-ce docker-ce-cli containerd.io"
|
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1421,10 +1482,14 @@ case "${1:-menu}" in
|
|||||||
esac
|
esac
|
||||||
MANAGEMENT
|
MANAGEMENT
|
||||||
|
|
||||||
chmod +x $INSTALL_DIR/conduit
|
# Patch the INSTALL_DIR in the generated script
|
||||||
|
# Use # as delimiter to avoid issues if path contains /
|
||||||
|
sed -i "s#REPLACE_ME_INSTALL_DIR#$INSTALL_DIR#g" "$INSTALL_DIR/conduit"
|
||||||
|
|
||||||
|
chmod +x "$INSTALL_DIR/conduit"
|
||||||
# Force create symlink
|
# Force create symlink
|
||||||
rm -f /usr/local/bin/conduit 2>/dev/null || true
|
rm -f /usr/local/bin/conduit 2>/dev/null || true
|
||||||
ln -s $INSTALL_DIR/conduit /usr/local/bin/conduit
|
ln -s "$INSTALL_DIR/conduit" /usr/local/bin/conduit
|
||||||
|
|
||||||
log_success "Management script installed: conduit"
|
log_success "Management script installed: conduit"
|
||||||
}
|
}
|
||||||
@@ -1479,11 +1544,10 @@ print_summary() {
|
|||||||
#═══════════════════════════════════════════════════════════════════════
|
#═══════════════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
uninstall() {
|
uninstall() {
|
||||||
echo -e "${CYAN}"
|
echo ""
|
||||||
echo "╔═══════════════════════════════════════════════════════════════════╗"
|
echo -e "${CYAN}╔═══════════════════════════════════════════════════════════════════╗${NC}"
|
||||||
echo "║ ⚠️ UNINSTALL CONDUIT ║"
|
echo "║ ⚠️ UNINSTALL CONDUIT ║"
|
||||||
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
echo "╚═══════════════════════════════════════════════════════════════════╝"
|
||||||
echo -e "${NC}"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "This will completely remove:"
|
echo "This will completely remove:"
|
||||||
echo " • Conduit Docker container"
|
echo " • Conduit Docker container"
|
||||||
@@ -1510,7 +1574,7 @@ uninstall() {
|
|||||||
docker rm -f conduit 2>/dev/null || true
|
docker rm -f conduit 2>/dev/null || true
|
||||||
|
|
||||||
log_info "Removing Conduit Docker image..."
|
log_info "Removing Conduit Docker image..."
|
||||||
docker rmi ghcr.io/ssmirr/conduit/conduit:latest 2>/dev/null || true
|
docker rmi "$CONDUIT_IMAGE" 2>/dev/null || true
|
||||||
|
|
||||||
log_info "Removing Conduit data volume..."
|
log_info "Removing Conduit data volume..."
|
||||||
docker volume rm conduit-data 2>/dev/null || true
|
docker volume rm conduit-data 2>/dev/null || true
|
||||||
@@ -1530,7 +1594,7 @@ uninstall() {
|
|||||||
rm -f /etc/init.d/conduit
|
rm -f /etc/init.d/conduit
|
||||||
|
|
||||||
log_info "Removing configuration files..."
|
log_info "Removing configuration files..."
|
||||||
rm -rf /opt/conduit
|
rm -rf "$INSTALL_DIR"
|
||||||
rm -f /usr/local/bin/conduit
|
rm -f /usr/local/bin/conduit
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
@@ -1540,8 +1604,7 @@ uninstall() {
|
|||||||
echo ""
|
echo ""
|
||||||
echo "Conduit and all related components have been removed."
|
echo "Conduit and all related components have been removed."
|
||||||
echo ""
|
echo ""
|
||||||
echo "Note: Docker itself was NOT removed. To remove Docker:"
|
echo "Note: Docker itself was NOT removed."
|
||||||
echo " apt-get purge docker-ce docker-ce-cli containerd.io"
|
|
||||||
echo ""
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1610,7 +1673,7 @@ main() {
|
|||||||
1)
|
1)
|
||||||
echo -e "${CYAN}Opening management menu...${NC}"
|
echo -e "${CYAN}Opening management menu...${NC}"
|
||||||
create_management_script >/dev/null 2>&1
|
create_management_script >/dev/null 2>&1
|
||||||
exec /opt/conduit/conduit menu
|
exec "$INSTALL_DIR/conduit" menu
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
echo ""
|
echo ""
|
||||||
@@ -1661,7 +1724,7 @@ main() {
|
|||||||
|
|
||||||
read -p "View live statistics now? [Y/n] " view_stats < /dev/tty || true
|
read -p "View live statistics now? [Y/n] " view_stats < /dev/tty || true
|
||||||
if [[ ! "$view_stats" =~ ^[Nn] ]]; then
|
if [[ ! "$view_stats" =~ ^[Nn] ]]; then
|
||||||
/opt/conduit/conduit stats
|
"$INSTALL_DIR/conduit" stats
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
|
|||||||
Reference in New Issue
Block a user