내 목표는 외부 ACL 유형을 통해 얻은 사용자 이름을 기반으로 HTTP 및 HTTPS URL을 투명하게 필터링하는 것입니다.
나는 인터셉트 모드에서 Squid 3.5.23을 실행하고 있으며 조사한 후에는 인터셉트 모드에서 external_acl_type을 사용할 수 있는 것 같습니다(틀렸을 수도 있음). 그런 다음 OK/ERR 응답의 일부로 OK user=testuser를 반환하면 SQUID가 이를 사용할 것입니다. 사용자 이름은 인증된 사용자입니다.
나는 stdin을 읽는 간단한 Python 스크립트를 작성한 다음 즉시 SQUID의 stdout에 OK user=testuser를 다시 작성했습니다.
SSL 픽, 스플라이싱, 범핑이 작동하며 http_access의 경우 SSL 포트에 대한 요청이 아닌 경우 SNI 대신 %DST를 사용하는 순수 외부 인증을 사용합니다. 다음으로 포트가 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()