Squid 完全指南 / 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
参数说明:
| 参数 | 说明 |
|---|---|
-b | LDAP 搜索基(Base DN) |
-D | 绑定 DN(服务账号) |
-W | 绑定密码文件 |
-f | 用户过滤器(%s 替换为用户名) |
-H | LDAP 服务器地址 |
-R | 禁用引用跟踪 |
-v | LDAP 协议版本 |
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 |
%Hs | HTTP 状态码 |
%Ss | Squid 状态码 |
%<st | 响应大小 |
8.10 认证安全建议
| 建议 | 说明 |
|---|---|
| 使用 HTTPS | Basic 认证密码以明文传输 |
| 限制尝试次数 | 防止暴力破解 |
| 设置 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 | 中高 |
| NTLM | Windows 域 | 高 |
| Negotiate (Kerberos) | AD 域 SSO | 最高 |
| RADIUS | 运营商/ISP | 高 |
| 外部 ACL | 自定义逻辑 | 可控 |