diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Proxy/forms/main.xml b/src/opnsense/mvc/app/controllers/OPNsense/Proxy/forms/main.xml
index d86522c02..eac4bf1b8 100644
--- a/src/opnsense/mvc/app/controllers/OPNsense/Proxy/forms/main.xml
+++ b/src/opnsense/mvc/app/controllers/OPNsense/Proxy/forms/main.xml
@@ -342,6 +342,108 @@
true
+
+
+ proxy.forward.icap.enable
+
+ checkbox
+
+
+ Select if you want to use ICAP.
+ true
+ false
+
+
+ proxy.forward.icap.RequestURL
+
+ text
+
+
+ Enter the url of the ICAP Server
+ true
+ false
+
+
+ proxy.forward.icap.ResponseURL
+
+ text
+
+
+ Enter the url of the ICAP Server
+ true
+ false
+
+
+ proxy.forward.icap.OptionsTTL
+
+ text
+
+
+ Enter the default ttl.
+ true
+ true
+
+
+ proxy.forward.icap.SendClientIP
+
+ checkbox
+
+
+ Send the client IP address to the ICAP server.
+ true
+ true
+
+
+ proxy.forward.icap.SendUsername
+
+ checkbox
+
+
+ Check if the username should be sent to the ICAP server.
+ true
+ true
+
+
+ proxy.forward.icap.EncodeUsername
+
+ checkbox
+
+
+ Check if you want to encode the username using base64.
+ true
+ true
+
+
+ proxy.forward.icap.UsernameHeader
+
+ text
+
+
+ Enter the name of the header.
+ true
+ true
+
+
+ proxy.forward.icap.EnablePreview
+
+ checkbox
+
+
+ Enable if you want to use previews.
+ true
+ true
+
+
+ proxy.forward.icap.PreviewSize
+
+ text
+
+
+ Enter the size of the preview.
+ true
+ true
+
+
proxy.forward.authentication.method
diff --git a/src/opnsense/mvc/app/models/OPNsense/Proxy/Proxy.xml b/src/opnsense/mvc/app/models/OPNsense/Proxy/Proxy.xml
index 48514c338..0970ea35e 100644
--- a/src/opnsense/mvc/app/models/OPNsense/Proxy/Proxy.xml
+++ b/src/opnsense/mvc/app/models/OPNsense/Proxy/Proxy.xml
@@ -252,6 +252,49 @@
+
+
+ 0
+ Y
+
+
+ Y
+ icap://127.0.0.1/reqmod
+
+
+ icap://127.0.0.1/respmod
+ Y
+
+
+ Y
+ 1
+
+
+ 0
+ Y
+
+
+ 0
+ Y
+
+
+ Y
+ X-Username
+ /^([a-zA-Z-]+)$/
+
+
+ 1
+ Y
+
+
+ 1024
+ Y
+
+
+ 60
+ Y
+
+
N
diff --git a/src/opnsense/service/templates/OPNsense/Proxy/squid.conf b/src/opnsense/service/templates/OPNsense/Proxy/squid.conf
index 4fa07d990..5f7826bf2 100644
--- a/src/opnsense/service/templates/OPNsense/Proxy/squid.conf
+++ b/src/opnsense/service/templates/OPNsense/Proxy/squid.conf
@@ -166,6 +166,54 @@ acl Safe_ports port {{element.split(":")[0]}} # {{element.split(":")[1]|default(
{% endif %}
acl CONNECT method CONNECT
+# ICAP SETTINGS
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+# enable icap
+icap_enable on
+{% if helpers.exists('OPNsense.proxy.forward.icap.OptionsTTL') %}
+icap_default_options_ttl {{OPNsense.proxy.forward.icap.OptionsTTL}}
+{% endif %}
+
+# send user information to the icap server
+{% if helpers.exists('OPNsense.proxy.forward.icap.SendClientIP') and OPNsense.proxy.forward.icap.SendClientIP == '1' %}
+adaptation_send_client_ip on
+{% else %}
+adaptation_send_client_ip off
+{% endif %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.SendUsername') and OPNsense.proxy.forward.icap.SendUsername == '1' %}
+adaptation_send_username on
+{% else %}
+adaptation_send_username off
+{% endif %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.EncodeUsername') and OPNsense.proxy.forward.icap.EncodeUsername == '1' %}
+icap_client_username_encode on
+{% else %}
+icap_client_username_encode off
+{% endif %}
+
+# preview
+{% if helpers.exists('OPNsense.proxy.forward.icap.EnablePreview') and OPNsense.proxy.forward.icap.EnablePreview == '1' %}
+icap_preview_enable on
+{% else %}
+icap_preview_enable off
+{% endif %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.PreviewSize') %}
+icap_preview_size {{OPNsense.proxy.forward.icap.PreviewSize}}
+{% endif %}
+
+# add the servers
+{% if helpers.exists('OPNsense.proxy.forward.icap.ResponseURL') %}
+icap_service response_mod respmod_precache {{OPNsense.proxy.forward.icap.ResponseURL}}
+{% endif %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.RequestURL') %}
+icap_service request_mod reqmod_precache {{OPNsense.proxy.forward.icap.RequestURL}}
+{% endif %}
+
+{% else %}
+# disable icap
+icap_enable off
+{% endif %}
+
# Authentication Settings
{% if helpers.exists('OPNsense.proxy.forward.authentication.method') and OPNsense.proxy.forward.authentication.method != '' %}
# Configure Local User Authentication helper
@@ -186,12 +234,20 @@ acl local_auth proxy_auth REQUIRED
# ALLOW UNRESTRICTED
# ACL list (Allow) unrestricted
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow unrestricted
+adaptation_access request_mod allow unrestricted
+{% endif %}
http_access allow unrestricted
{% endif %}
{% if helpers.exists('OPNsense.proxy.forward.acl.whiteList') %}
# ACL list (Allow) whitelist
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow whiteList
+adaptation_access request_mod allow whiteList
+{% endif %}
http_access allow whiteList
{% endif %}
@@ -199,14 +255,21 @@ http_access allow whiteList
#
# ACL list (Deny) blacklist
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny blackList
+adaptation_access request_mod deny blackList
+{% endif %}
http_access deny blackList
-
{% endif %}
{% if helpers.exists('OPNsense.proxy.forward.acl.remoteACLs.blacklists') %}
{% for blacklist in helpers.toList('OPNsense.proxy.forward.acl.remoteACLs.blacklists.blacklist') if blacklist.enabled=='1' %}
{% if loop.first %}
# ACL list (Deny) remoteblacklist
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny remoteblacklist
+adaptation_access request_mod deny remoteblacklist
+{% endif %}
http_access deny remoteblacklist
{% endif %}
{% endfor %}
@@ -215,12 +278,26 @@ http_access deny remoteblacklist
{% if helpers.exists('OPNsense.proxy.forward.acl.browser') %}
# ACL list (Deny) blockuseragent
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny blockuseragents
+adaptation_access request_mod deny blockuseragents
+{% endif %}
http_access deny blockuseragents
{% endif %}
{% if helpers.exists('OPNsense.proxy.forward.acl.mimeType') %}
# ACL list (Deny) blockmimetypes
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny blockmimetypes {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
+
+adaptation_access request_mod deny blockmimetypes {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
+
+adaptation_access response_mod deny blockmimetypes_requests {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
+
+adaptation_access request_mod deny blockmimetypes_requests {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
+
+{% endif %}
http_reply_access deny blockmimetypes {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
http_access deny blockmimetypes_requests {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted {% endif %}
@@ -228,22 +305,48 @@ http_access deny blockmimetypes_requests {% if helpers.exists('OPNsense.proxy.fo
{% endif %}
# Deny requests to certain unsafe ports
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny !Safe_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
+
+adaptation_access request_mod deny !Safe_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
+
+{% endif %}
http_access deny !Safe_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
-# Deny CONNECT to other than secure SSL ports
+# Deny CONNECT to other than secure SSL ports{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+
+adaptation_access response_mod deny CONNECT !SSL_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
+
+adaptation_access request_mod deny CONNECT !SSL_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
+
+{% endif %}
http_access deny CONNECT !SSL_ports {% if helpers.exists('OPNsense.proxy.forward.acl.unrestricted') %}!unrestricted{% endif %}
{% if helpers.exists('OPNsense.proxy.forward.acl.bannedHosts') %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny bannedHosts
+adaptation_access request_mod deny bannedHosts
+{% endif %}
http_access deny bannedHosts
{% endif %}
# Only allow cachemgr access from localhost
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow localhost manager
+adaptation_access request_mod allow localhost manager
+adaptation_access response_mod deny manager
+adaptation_access request_mod deny manager
+{% endif %}
http_access allow localhost manager
http_access deny manager
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny to_localhost
+adaptation_access request_mod deny to_localhost
+{% endif %}
http_access deny to_localhost
#
@@ -251,22 +354,41 @@ http_access deny to_localhost
#
# Deny request from unauthorized clients
{% if helpers.exists('OPNsense.proxy.forward.authentication.method') and OPNsense.proxy.forward.authentication.method != '' %}
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow local_auth
+adaptation_access request_mod allow local_auth
+{% endif %}
http_access allow local_auth
{% endif %}
#
# ACL - localnet - default these include ranges from selected interfaces (Allow local subnets)
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow localnet
+adaptation_access request_mod allow localnet
+{% endif %}
http_access allow localnet
# ACL - localhost
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow localhost
+adaptation_access request_mod allow localhost
+{% endif %}
http_access allow localhost
{% if helpers.exists('OPNsense.proxy.forward.acl.allowedSubnets') %}
# ACL list (Allow) subnets
+{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod allow subnets
+adaptation_access request_mod allow subnets
+{% endif %}
http_access allow subnets
{% endif %}
-# Deny all other access to this proxy
+# Deny all other access to this proxy{% if helpers.exists('OPNsense.proxy.forward.icap.enable') and OPNsense.proxy.forward.icap.enable == '1' %}
+adaptation_access response_mod deny all
+adaptation_access request_mod deny all
+{% endif %}
http_access deny all
{% if helpers.exists('OPNsense.proxy.general.cache.local') %}