squid_ins

squid_ins

bash安装squid,ubuntu为例

ubuntu

rm -f install-squid.sh && cat > install-squid.sh <<'EOF'
#!/bin/bash
# Author:运维工具
# System:Ubuntu20.04
# Squid 纯净无错乱脚本|无转义|无乱码|生产可用
# 特性:默认无密码、安装强制清空残留、禁止多参数、健壮容错

# ========== 全局变量 ==========
SQUID_CONF="/etc/squid/squid.conf"
SQUID_PASS="/etc/squid/passwd"
DEFAULT_USER="proxy"
DEFAULT_PASS="123456"
DEFAULT_PORT="3128"
# 自动获取本机内网IP(用于输出客户端命令)
SERVER_IP=$(hostname -I | awk '{print $1}')

# ========== 帮助菜单 ==========
show_help(){
    SERVER_IP=$(hostname -I | awk '{print $1}')
    echo "============================================="
    echo "          Squid 运维脚本使用帮助"
    echo "============================================="
    echo "用法:  bash install-squid.sh [单个参数]   (每次仅允许一个参数)"
    echo ""
    echo "【命令参数】"
    echo "  install        一键重装(强制清空旧配置与数据后全新安装)"
    echo "  pass_on        开启密码认证(公网环境建议开启)"
    echo "  pass_off       关闭密码认证(恢复匿名访问)"
    echo "  remove         彻底卸载 Squid 及配置残留"
    echo "  passwd         修改代理认证密码(需已 pass_on)"
    echo "  status         查看 systemd 服务与监听端口"
    echo "  check          已安装时重新打印客户端配置与连通性测试命令"
    echo "  allow_all      允许全网 IP 连接代理"
    echo "  allow_lan      仅允许内网网段连接代理"
    echo "  help           查看本帮助(无参数时同 help)"
    echo ""
    echo "【代理与认证默认值】"
    echo "  监听端口:           ${DEFAULT_PORT}"
    echo "  代理账号(认证时):   ${DEFAULT_USER}"
    echo "  初始密码(仅服务端): ${DEFAULT_PASS}  (安装时写入 htpasswd,输出不向客户端展示)"
    echo "  密码认证:           关闭 (匿名直通,install 后默认状态)"
    echo "  认证方式:           Basic NCSA  (pass_on 后生效)"
    echo "  认证域(realm):      Proxy-Auth"
    echo "  认证子进程数:       5"
    echo "  密码文件:           ${SQUID_PASS}"
    echo "  本机 IP(自动检测):  ${SERVER_IP:-未检测到}"
    echo ""
    echo "【Squid 配置默认值(install 写入)】"
    echo "  主配置文件:         ${SQUID_CONF}"
    echo "  缓存目录:           /var/spool/squid  (ufs 1024MB, L1=16, L2=256)"
    echo "  内存缓存:           512 MB"
    echo "  单对象上限:         4096 MB"
    echo "  替换策略:           heap LFUDA"
    echo "  访问日志:           /var/log/squid/access.log"
    echo "  缓存日志:           /var/log/squid/cache.log"
    echo "  X-Forwarded-For:    关闭 (forwarded_for off)"
    echo ""
    echo "【访问控制默认值】"
    echo "  内网 ACL(localnet): 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16"
    echo "  http_access 顺序:   allow localnet -> allow all -> deny all"
    echo "  安装后访问范围:     允许所有来源 IP (等同 allow_all 未改前的默认行为)"
    echo ""
    echo "【系统与安装行为默认值】"
    echo "  适用系统:           Ubuntu 20.04 (apt 安装 squid、apache2-utils)"
    echo "  安装模式:           强制清空残留后重装 (remove_squid_force)"
    echo "  防火墙(ufw):        自动放行 tcp/${DEFAULT_PORT}"
    echo "  开机自启:           开启 (systemctl enable squid)"
    echo "  客户端代理协议:     HTTP  (export http_proxy/https_proxy=http://IP:PORT)"
    echo "  连通性测试域名:     www.qq.com, www.google.com  (见 check/install 输出)"
    echo "============================================="
}

# ========== 权限检测 ==========
check_root(){
    if [ $(id -u) -ne 0 ];then
        echo -e "\033[31m 请使用root权限执行!\033[0m"
        exit 1
    fi
}

# ========== 是否开启密码认证 ==========
is_auth_enabled(){
    [ -f ${SQUID_CONF} ] && grep -q "^auth_param basic program" ${SQUID_CONF} 2>/dev/null
}

# ========== 打印客户端配置与连通性测试 ==========
show_client_info(){
    SERVER_IP=$(hostname -I | awk '{print $1}')
    if is_auth_enabled; then
        local auth_status="开启(需账号密码)"
    else
        local auth_status="关闭(匿名无密码)"
    fi

    echo "============================================="
    echo " 代理地址: ${SERVER_IP}:${DEFAULT_PORT}"
    echo " 认证状态: ${auth_status}"
    echo " 开启密码: ./install-squid.sh pass_on"
    echo " 关闭密码: ./install-squid.sh pass_off"
    echo "============================================="
    echo -e "\033[34m 【Linux 客户端代理设置|CentOS/Ubuntu 通用】\033[0m"
    echo -e "\033[36m ---------- 一、临时代理(仅当前终端) ----------\033[0m"
    echo "export http_proxy=http://${SERVER_IP}:${DEFAULT_PORT}"
    echo "export https_proxy=http://${SERVER_IP}:${DEFAULT_PORT}"
    echo "unset http_proxy https_proxy  # 取消代理"
    echo -e "\033[36m ---------- 二、永久代理(全局所有终端) ----------\033[0m"
    echo "# Ubuntu/Debian"
    echo "echo 'export http_proxy=http://${SERVER_IP}:${DEFAULT_PORT}' >> ~/.bashrc"
    echo "echo 'export https_proxy=http://${SERVER_IP}:${DEFAULT_PORT}' >> ~/.bashrc"
    echo "source ~/.bashrc"
    echo "# CentOS/RHEL"
    echo "echo 'export http_proxy=http://${SERVER_IP}:${DEFAULT_PORT}' >> ~/.bash_profile"
    echo "echo 'export https_proxy=http://${SERVER_IP}:${DEFAULT_PORT}' >> ~/.bash_profile"
    echo "source ~/.bash_profile"
    if is_auth_enabled; then
        echo -e "\033[36m ---------- 三、已开启密码认证时的客户端格式 ----------\033[0m"
        echo "# 将 <你的密码> 替换为实际密码(账号默认: ${DEFAULT_USER})"
        echo "export http_proxy=http://${DEFAULT_USER}:<你的密码>@${SERVER_IP}:${DEFAULT_PORT}"
        echo "export https_proxy=http://${DEFAULT_USER}:<你的密码>@${SERVER_IP}:${DEFAULT_PORT}"
        echo "# 或使用 curl -U 指定账号密码:"
        echo "curl -x http://${SERVER_IP}:${DEFAULT_PORT} -U ${DEFAULT_USER}:<你的密码> -I --connect-timeout 10 https://www.qq.com"
    else
        echo -e "\033[36m ---------- 三、如需密码认证 ----------\033[0m"
        echo "# 服务端执行 pass_on 后,客户端使用:"
        echo "export http_proxy=http://${DEFAULT_USER}:<你的密码>@${SERVER_IP}:${DEFAULT_PORT}"
    fi
    echo -e "\033[36m ---------- 四、使用前连通性测试(在 Linux 客户端执行) ----------\033[0m"
    if is_auth_enabled; then
        echo "curl -x http://${SERVER_IP}:${DEFAULT_PORT} -U ${DEFAULT_USER}:<你的密码> -I --connect-timeout 10 https://www.qq.com"
        echo "curl -x http://${SERVER_IP}:${DEFAULT_PORT} -U ${DEFAULT_USER}:<你的密码> -I --connect-timeout 10 https://www.google.com"
    else
        echo "curl -x http://${SERVER_IP}:${DEFAULT_PORT} -I --connect-timeout 10 https://www.qq.com"
        echo "curl -x http://${SERVER_IP}:${DEFAULT_PORT} -I --connect-timeout 10 https://www.google.com"
    fi
    echo "# 返回 HTTP/1.x 200 或 301/302 表示代理可用;超时或 403 请检查防火墙/ACL"
    echo "============================================="
}

# ========== 强制彻底清空 ==========
remove_squid_force(){
    check_root
    echo -e "\033[33m 正在强制清理残留...\033[0m"
    systemctl stop squid >/dev/null 2>&1
    systemctl disable squid >/dev/null 2>&1
    apt remove squid -y >/dev/null 2>&1
    apt autoremove -y >/dev/null 2>&1
    rm -rf /etc/squid /var/spool/squid /var/log/squid
    ufw delete allow ${DEFAULT_PORT}/tcp >/dev/null 2>&1
    echo -e "\033[32m 残留清理完成!\033[0m"
}

# ========== 安装重装函数 ==========
install_squid(){
    check_root
    remove_squid_force

    echo -e "\033[32m 1.安装Squid依赖...\033[0m"
    apt update -y >/dev/null 2>&1
    apt install squid apache2-utils -y >/dev/null 2>&1

    mkdir -p /etc/squid
    mkdir -p /var/spool/squid

    [ -f ${SQUID_CONF} ] && cp ${SQUID_CONF} ${SQUID_CONF}.bak

    echo -e "\033[32m 2.写入优化配置(默认匿名无密码)...\033[0m"
    tee ${SQUID_CONF} >/dev/null <<CONF
http_port ${DEFAULT_PORT}
cache_dir ufs /var/spool/squid 1024 16 256
cache_mem 512 MB
maximum_object_size 4096 MB
cache_replacement_policy heap LFUDA
cache_access_log /var/log/squid/access.log
cache_log /var/log/squid/cache.log

acl localnet src 10.0.0.0/8
acl localnet src 172.16.0.0/12
acl localnet src 192.168.0.0/16

# 默认关闭密码认证
# auth_param basic program /usr/lib/squid/basic_ncsa_auth ${SQUID_PASS}
# auth_param basic realm Proxy-Auth
# auth_param basic children 5
# acl authenticated proxy_auth REQUIRED

http_access allow localnet
http_access allow all
http_access deny all

forwarded_for off
request_header_access Allow allow all
CONF

    htpasswd -bc ${SQUID_PASS} ${DEFAULT_USER} ${DEFAULT_PASS} >/dev/null 2>&1
    squid -z >/dev/null 2>&1
    ufw allow ${DEFAULT_PORT}/tcp >/dev/null 2>&1
    systemctl enable squid >/dev/null 2>&1
    systemctl restart squid >/dev/null 2>&1

    echo -e "\033[32m 3.Squid 安装完成!\033[0m"
    show_client_info
}

# ========== 交互式卸载 ==========
remove_squid(){
    check_root
    read -p "确定卸载?(y/n):" op
    [ "${op}" != "y" ] && echo "已取消" && exit 0
    remove_squid_force
}

# ========== 修改密码 ==========
change_passwd(){
    check_root
    [ ! -d /etc/squid ] && mkdir -p /etc/squid
    read -p "输入新密码:" newpass
    htpasswd -bc ${SQUID_PASS} ${DEFAULT_USER} ${newpass}
    systemctl reload squid >/dev/null 2>&1
    echo -e "\033[32m 密码修改成功(新密码未在此显示,请自行记录)\033[0m"
    echo "客户端格式: export http_proxy=http://${DEFAULT_USER}:<你的密码>@${SERVER_IP}:${DEFAULT_PORT}"
}

# ========== 状态查看 ==========
status_squid(){
    echo "========== Squid 运行信息 =========="
    systemctl status squid | head -15
    echo ""
    echo "监听端口: $(ss -tulpn | grep squid 2>/dev/null || echo '未检测到')"
    if is_auth_enabled; then
        echo -e "认证状态: \033[31m 开启(需密码)\033[0m"
    else
        echo -e "认证状态: \033[32m 关闭(匿名)\033[0m"
    fi
}

# ========== 已安装时重新打印客户端信息 ==========
check_squid(){
    if ! command -v squid >/dev/null 2>&1 || [ ! -f ${SQUID_CONF} ]; then
        echo -e "\033[31m Squid 未安装,请先执行: bash install-squid.sh install\033[0m"
        exit 1
    fi
    echo "========== Squid 安装检查 =========="
    if systemctl is-active squid >/dev/null 2>&1; then
        echo -e "服务状态: \033[32m 运行中\033[0m"
    else
        echo -e "服务状态: \033[31m 未运行(可执行: systemctl start squid)\033[0m"
    fi
    echo "监听端口: $(ss -tulpn | grep squid 2>/dev/null || echo '未检测到')"
    echo ""
    show_client_info
}

# ========== 开启密码认证 ==========
pass_on(){
    check_root
    sed -i 's/^#auth_param/auth_param/g' ${SQUID_CONF}
    sed -i 's/^#acl authenticated/acl authenticated/g' ${SQUID_CONF}
    sed -i 's/http_access allow all/#http_access allow all/g' ${SQUID_CONF}
    sed -i '/http_access allow localnet/a\http_access allow authenticated' ${SQUID_CONF}
    systemctl reload squid >/dev/null 2>&1
    echo -e "\033[32m 密码认证已开启|账号: ${DEFAULT_USER} (密码见 passwd 命令修改,不在此显示)\033[0m"
    show_client_info
}

# ========== 关闭密码认证 ==========
pass_off(){
    check_root
    sed -i 's/^auth_param/#auth_param/g' ${SQUID_CONF}
    sed -i 's/^acl authenticated/#acl authenticated/g' ${SQUID_CONF}
    sed -i 's/#http_access allow all/http_access allow all/g' ${SQUID_CONF}
    sed -i '/http_access allow authenticated/d' ${SQUID_CONF}
    systemctl reload squid >/dev/null 2>&1
    echo -e "\033[32m 密码认证关闭|匿名直通\033[0m"
    show_client_info
}

# ========== 开放全网 ==========
allow_all(){
    check_root
    sed -i 's/acl localnet src 192.168.0.0\/16/#&/g' ${SQUID_CONF}
    sed -i '/http_access allow all/i\acl all_ip src 0.0.0.0/0\nhttp_access allow all_ip' ${SQUID_CONF}
    systemctl reload squid >/dev/null 2>&1
    echo -e "\033[32m 已开放全网访问\033[0m"
}

# ========== 仅内网 ==========
allow_lan(){
    check_root
    sed -i '/all_ip/d' ${SQUID_CONF}
    sed -i 's/#acl localnet src 192.168.0.0\/16/&/g' ${SQUID_CONF}
    systemctl reload squid >/dev/null 2>&1
    echo -e "\033[32m 已限制仅内网访问\033[0m"
}

# ========== 参数校验|禁止多参数 ==========
if [ $# -gt 1 ];then
    echo -e "\033[31m 错误:只能传入单个参数!\033[0m"
    exit 1
fi

# ========== 逻辑入口 ==========
case $1 in
install) install_squid;;
pass_on) pass_on;;
pass_off) pass_off;;
remove) remove_squid;;
passwd) change_passwd;;
status) status_squid;;
check) check_squid;;
allow_all) allow_all;;
allow_lan) allow_lan;;
help|"") show_help;;
*) echo -e "\033[31m 参数错误!输入 help 查看帮助\033[0m";;
esac
EOF
chmod +x install-squid.sh
echo -e "\033[32m ✅ 使用示例: bash install-squid.sh install | bash install-squid.sh check \033[0m"

igozhang 2021