强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

08 - 认证机制

第八章:认证机制

8.1 认证概述

Squid 支持多种认证方式(Authentication Scheme),用于验证客户端身份并结合 ACL 实现基于用户的访问控制。

客户端请求
    │
    ▼
┌─────────────────────────────┐
│     Squid 认证流程            │
│                              │
│  1. 检查是否需要认证          │
│  2. 提取认证凭据              │
│  3. 调用 Helper 验证          │
│  4. 设置认证结果              │
│  5. 结合 ACL 做访问决策       │
└─────────────────────────────┘

8.2 认证方式对比

认证方式安全性用户体验部署难度适用场景
Basic★★★★★★★小型环境、HTTP 代理
Digest★★★★★★★★★替代 Basic 的更安全方案
NTLM★★★★★★★★★★Windows 域环境
Negotiate (Kerberos)★★★★★★★★★★★★★★★企业 AD 环境
LDAP★★★★★★★★★★有 LDAP 目录的企业
PAM★★★★★★★★Linux 系统用户

注意:Basic 认证以 Base64 明文传输密码(等同于明文),必须配合 HTTPS 使用。Squid 的认证仅对正向代理有意义;反向代理通常不使用 Squid 的认证机制。

8.3 Basic 认证

8.3.1 NCSA 密码文件认证

# 基础配置
auth_param basic program /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5 startup=2 idle=1
auth_param basic realm "Squid Proxy - Please Login"
auth_param basic credentialsttl 2 hours
auth_param basic casesensitive off

# 定义认证 ACL
acl authenticated proxy_auth REQUIRED

# 应用认证
http_access allow authenticated
http_access deny all

创建和管理密码文件

# 创建密码文件(-c 创建新文件)
sudo htpasswd -c /etc/squid/passwd admin

# 添加用户
sudo htpasswd /etc/squid/passwd user1

# 添加用户(使用 Bcrypt 加密,更安全)
sudo htpasswd -B /etc/squid/passwd user2

# 删除用户
sudo htpasswd -D /etc/squid/passwd user3

# 查看用户列表
cat /etc/squid/passwd

# 安装 htpasswd(如未安装)
# Ubuntu: sudo apt install apache2-utils
# CentOS: sudo dnf install httpd-tools

8.3.2 NCSA 密码文件格式

# /etc/squid/passwd
# 格式: username:encrypted_password
admin:$apr1$abc123$xxxxxxxxxxxxxxxxxxxxxx
user1:$apr1$def456$yyyyyyyyyyyyyyyyyyyyyy
user2:$2y$05$zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

8.3.3 PAM 系统认证

# 使用 Linux 系统用户认证
auth_param basic program /usr/lib/squid/basic_pam_auth
auth_param basic children 5
auth_param basic realm "System Login"
auth_param basic credentialsttl 1 hour

# PAM 配置文件
# /etc/pam.d/squid
# auth    required   pam_unix.so
# account required   pam_unix.so
# 创建 PAM 配置
sudo tee /etc/pam.d/squid <<'EOF'
auth    required   pam_unix.so
account required   pam_unix.so
EOF

8.3.4 数据库认证

# MySQL 认证(需要自行编译 helper)
auth_param basic program /usr/lib/squid/basic_db_auth \
    --dsn "DBI:mysql:database=proxy_auth;host=localhost" \
    --user squid \
    --password "dbpassword" \
    --table users \
    --usercol username \
    --passwdcol password
auth_param basic children 5
auth_param basic realm "Database Auth"

8.4 Digest 认证

Digest 认证比 Basic 更安全,密码不以明文传输。

# Digest 认证配置
auth_param digest program /usr/lib/squid/digest_file_auth /etc/squid/digest_passwd
auth_param digest children 5
auth_param digest realm "Squid Digest Auth"
auth_param digest nonce_garbage_interval 5 minutes
auth_param digest nonce_max_duration 30 minutes
auth_param digest nonce_max_count 50

# ACL
acl digest_auth proxy_auth REQUIRED
http_access allow digest_auth
http_access deny all
# 创建 Digest 密码文件
sudo htdigest -c /etc/squid/digest_passwd "Squid Digest Auth" admin
sudo htdigest /etc/squid/digest_passwd "Squid Digest Auth" user1

# 格式: username:realm:HA1_hash

8.5 NTLM 认证

NTLM 认证适用于 Windows 域环境,支持 SSO(Single Sign-On)。

8.5.1 Samba/Winbind 配置

# 安装 Samba 和 Winbind
sudo apt install -y samba winbind libnss-winbind libpam-winbind

# 配置 Samba
sudo tee /etc/samba/smb.conf <<'EOF'
[global]
    workgroup = EXAMPLE
    realm = EXAMPLE.COM
    security = ads
    password server = dc.example.com
    winbind use default domain = yes
    winbind enum users = yes
    winbind enum groups = yes
EOF

# 加入域
sudo net ads join -U administrator

# 启动 Winbind
sudo systemctl start winbind
sudo systemctl enable winbind

8.5.2 Squid NTLM 配置

# NTLM 认证
auth_param ntlm program /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp
auth_param ntlm children 10
auth_param ntlm keep_alive on

# Negotiate (Kerberos) 认证
auth_param negotiate program /usr/bin/negotiate_wrapper_auth \
    --ntlm /usr/bin/ntlm_auth --helper-protocol=squid-2.5-ntlmssp \
    --kerberos /usr/lib/squid/negotiate_kerberos_auth -s HTTP/[email protected]
auth_param negotiate children 10
auth_param negotiate keep_alive on

# ACL
acl ntlm_auth proxy_auth REQUIRED
http_access allow ntlm_auth
http_access deny all

8.6 LDAP 认证

8.6.1 基础 LDAP 认证

# LDAP 认证
auth_param basic program /usr/lib/squid/basic_ldap_auth \
    -b "ou=people,dc=example,dc=com" \
    -D "cn=squid,ou=services,dc=example,dc=com" \
    -W /etc/squid/ldap_pass.txt \
    -f "(&(uid=%s)(objectClass=inetOrgPerson))" \
    -H ldap://ldap.example.com:389 \
    -R \
    -v 3

auth_param basic children 10 startup=3 idle=1
auth_param basic realm "LDAP Authenticated Proxy"
auth_param basic credentialsttl 1 hour

# ACL
acl ldap_users proxy_auth REQUIRED
http_access allow ldap_users
http_access deny all

参数说明

参数说明
-bLDAP 搜索基(Base DN)
-D绑定 DN(服务账号)
-W绑定密码文件
-f用户过滤器(%s 替换为用户名)
-HLDAP 服务器地址
-R禁用引用跟踪
-vLDAP 协议版本

8.6.2 LDAP 组验证

# LDAP 组成员验证
external_acl_type ldap_group_ttl ttl=300 %LOGIN \
    /usr/lib/squid/ext_ldap_group_acl \
    -b "ou=groups,dc=example,dc=com" \
    -D "cn=squid,ou=services,dc=example,dc=com" \
    -W /etc/squid/ldap_pass.txt \
    -f "(&(memberUid=%u)(cn=%g))" \
    -H ldap://ldap.example.com \
    -v 3

# 定义组 ACL
acl proxy_users external ldap_group_ttl proxy_users
acl admins external ldap_group_ttl admins
acl developers external ldap_group_ttl developers

# 先认证
auth_param basic program /usr/lib/squid/basic_ldap_auth \
    -b "ou=people,dc=example,dc=com" \
    -D "cn=squid,ou=services,dc=example,dc=com" \
    -W /etc/squid/ldap_pass.txt \
    -f "(uid=%s)" \
    -H ldap://ldap.example.com

acl auth proxy_auth REQUIRED
http_access deny !auth

# 基于组的访问控制
http_access allow admins       # 管理员:完全访问
http_access allow developers   # 开发者:部分访问
http_access allow proxy_users  # 普通用户:基本访问
http_access deny all

8.6.3 Active Directory 认证

# AD 域认证
auth_param basic program /usr/lib/squid/basic_ldap_auth \
    -b "dc=example,dc=com" \
    -D "cn=squid_svc,ou=Service Accounts,dc=example,dc=com" \
    -W /etc/squid/ad_pass.txt \
    -f "(&(sAMAccountName=%s)(objectClass=user))" \
    -H ldap://dc.example.com:389 \
    -R

# AD 组验证
external_acl_type ad_group ttl=300 %LOGIN \
    /usr/lib/squid/ext_ldap_group_acl \
    -b "ou=Groups,dc=example,dc=com" \
    -D "cn=squid_svc,ou=Service Accounts,dc=example,dc=com" \
    -W /etc/squid/ad_pass.txt \
    -f "(&(member=%u)(cn=%g))" \
    -H ldap://dc.example.com \
    -R

acl it_dept external ad_group "IT Department"
acl hr_dept external ad_group "HR Department"

8.7 外部认证 (External ACL)

8.7.1 自定义认证脚本

# 外部 ACL helper
external_acl_type my_auth ttl=300 %LOGIN %SRC \
    /usr/lib/squid/my_auth_helper

acl custom_auth external my_auth
http_access allow custom_auth
http_access deny all
#!/bin/bash
# /usr/lib/squid/my_auth_helper — 自定义认证脚本
# 从 stdin 读取 "username src_ip\n"
# 输出 "OK" 或 "ERR"

while read line; do
    username=$(echo "$line" | awk '{print $1}')
    src_ip=$(echo "$line" | awk '{print $2}')

    # 自定义验证逻辑(示例:检查 API)
    response=$(curl -s "http://auth-api.example.com/verify?user=$username&ip=$src_ip")

    if [ "$response" = "valid" ]; then
        echo "OK"
    else
        echo "ERR"
    fi
done
# 设置权限
sudo chmod 755 /usr/lib/squid/my_auth_helper

8.7.2 RADIUS 认证

auth_param basic program /usr/lib/squid/basic_radius_auth \
    -h radius.example.com \
    -p 1812 \
    -s shared_secret \
    -w 3 \
    -t 5

auth_param basic children 5
auth_param basic realm "RADIUS Authenticated Proxy"

8.8 多认证方案

8.8.1 认证回退

Squid 不原生支持认证回退(fallback),但可以通过外部 ACL 实现:

# 方案:优先 LDAP,回退到本地文件
# 实际上 Squid 一次只能配置一种认证方式
# 但可以通过外部 ACL 做多种验证

# 主认证:LDAP
auth_param basic program /usr/lib/squid/basic_ldap_auth ...

# 外部 ACL 补充验证(如果 LDAP 失败,检查本地文件)
external_acl_type local_check ttl=60 %LOGIN \
    /usr/lib/squid/basic_ncsa_auth /etc/squid/passwd

acl ldap_auth proxy_auth REQUIRED
acl local_auth external local_check

# 先要求主认证
http_access deny !ldap_auth

# 再检查补充认证
http_access allow local_auth
http_access deny all

注意:上述方案并非真正的回退。真正的回退需要自定义 helper 脚本。

8.8.2 免认证白名单

# 定义免认证的网络/域名
acl no_auth_src src 10.0.0.0/24
acl no_auth_dst dstdomain .example.com .internal

# 免认证访问
http_access allow no_auth_src no_auth_dst

# 其他需要认证
acl auth proxy_auth REQUIRED
http_access deny !auth
http_access allow all

8.9 认证日志

8.9.1 记录认证信息

# 在 access.log 中记录用户名
access_log /var/log/squid/access.log squid

# 日志格式中 %ul 表示认证用户名
# 自定义日志格式
logformat mylog %ts.%03tu %6tr %>a %Ss/%03>Hs %<st %rm %ru %[un %Sh/%<a %mt
access_log /var/log/squid/access.log mylog

8.9.2 日志字段说明

字段说明
%ul认证用户名 (login)
%un认证用户名 (ident)
%>a客户端 IP
%<a服务器 IP
%rm请求方法
%ru请求 URL
%HsHTTP 状态码
%SsSquid 状态码
%<st响应大小

8.10 认证安全建议

建议说明
使用 HTTPSBasic 认证密码以明文传输
限制尝试次数防止暴力破解
设置 credentialsttl定期要求重新认证
使用强密码策略外部认证源配置密码复杂度
监控认证失败日志分析异常登录
限制 Helper 并发auth_param ... children N
# 认证超时
authenticate_ttl 1 hour
authenticate_ip_ttl 10 seconds

# Helper 并发限制
auth_param basic children 10 startup=3 idle=2

# Helper 超时
helper_startup_timeout 30 seconds

8.11 本章小结

认证方式适用场景安全性
Basic (NCSA)小型环境、快速部署低(需 HTTPS)
Basic (PAM)Linux 系统用户
Basic (LDAP)企业目录
Digest替代 Basic中高
NTLMWindows 域
Negotiate (Kerberos)AD 域 SSO最高
RADIUS运营商/ISP
外部 ACL自定义逻辑可控

扩展阅读