使用外部身份验证和 ICAP 的 SQUID 拦截模式与 adjustment_send_username 不起作用

使用外部身份验证和 ICAP 的 SQUID 拦截模式与 adjustment_send_username 不起作用

我的目标是根据通过外部 acl 类型获取的用户名透明地过滤 HTTP 和 HTTPS URL。

我在拦截模式下运行 Squid 3.5.23,经过研究,似乎您可以在拦截模式下使用 external_acl_type (我可能是错的),然后返回 OK user=testuser 作为 OK/ERR 响应的一部分,SQUID 将使用该用户名作为经过身份验证的用户。

我编写了一个简单的 python 脚本来读取 stdin,然后立即将 OK user=testuser 写回 SQUID 的 stdout。

SSL peek、拼接和碰撞正在工作,对于 http_access,如果请求不是 SSL 端口,则它使用纯外部身份验证,该身份验证使用 %DST 而不是 SNI。接下来,如果端口是 SSL,则它允许,但随后使用 ssl-bump,它会咨询通过 SNI 的 SSL 外部身份验证。

这两个外部 acl 都只是以 OK user=testuser 响应,我可以在我创建的日志中看到它的工作情况。

当联系 ICAP 服务器时就会出现问题。

在一些记录的请求中,我可以看到客户端 IP 和用户名确实出现在 ICAP 标头中,而在某些请求中,它根本没有发送。

我无法确定为什么某些 ICAP 请求具有标头而其他请求没有标头的模式,并且我不确定这是否是配置错误、错误或总体上不受支持。

ICAP 请求何时发送,在外部身份验证之前还是之后?

我是否做错了什么,或者只是想做一些实际上不起作用的事情?

这是我认为我的配置的相关部分。

    external_acl_type ssl_external negative_ttl=0 %SRC %PORT %METHOD %ssl::>sni %PATH /etc/webscreen/auth/webscreen.py
    external_acl_type plain_external negative_ttl=0 %SRC %PORT %METHOD %DST %PATH /etc/webscreen/auth/webscreen.py

    acl ssl_webscreen external ssl_external
    acl plain_webscreen external plain_external

    acl SSL_ports port 443

    acl step1 at_step SslBump1
    acl step2 at_step SslBump2
    acl step3 at_step SslBump3

    http_access allow !SSL_ports plain_webscreen
    http_access allow SSL_ports localnet
    http_access deny all

    ssl_bump peek step1 all
    ssl_bump splice step2 ssl_webscreen
    ssl_bump bump all

    icap_enable on
    icap_service_failure_limit -1
    icap_preview_enable on
    icap_preview_size 1024
    icap_persistent_connections on
    adaptation_send_client_ip on
    adaptation_send_username on
    icap_service webscreen1 reqmod_precache icap://127.0.0.1:1344/reqmod bypass=0
    icap_service webscreen2 respmod_precache icap://127.0.0.1:1344/respmod bypass=0
    adaptation_access webscreen1 allow all
    adaptation_access webscreen2 allow all

根据评论中的要求,这里是 webscreen.py

#!/usr/bin/env python
import sys, time, datetime, os

log_file = "/etc/squid/webscreen/webscreen.log"

def main ():

        while (1):
                inline = sys.stdin.readline()
                logEntry (10, "New proxy request "+inline)
                sys.stdout.write("OK user=webscreen\n")
                sys.stdout.flush()


def logEntry(logmessagelevel, logmessage):

        global log_file
        # Get timestamp as human readable format
        now = datetime.datetime.now()
        timestamp = now.strftime("%Y-%m-%d %H:%M:%s")

        # open file to apptend
        logfile = open(log_file, 'a')
        logfile.write(timestamp+" "+str(logmessagelevel)+" "+logmessage+"\n")
        logfile.close()
        return



if __name__ == '__main__':
        main()

相关内容