aboutsummaryrefslogtreecommitdiffstats
path: root/config/squid3/34
diff options
context:
space:
mode:
authordoktornotor <notordoktor@gmail.com>2015-11-28 21:08:42 +0100
committerdoktornotor <notordoktor@gmail.com>2015-11-28 21:08:42 +0100
commit7503dd1b4eaaffbd203652835e171ae5e810b3e5 (patch)
tree002939ec7db2c4162d6dfe2e07b17f91ca952383 /config/squid3/34
parent574df7719c4ce38555128110c64b146b93832b61 (diff)
downloadpfsense-packages-7503dd1b4eaaffbd203652835e171ae5e810b3e5.tar.gz
pfsense-packages-7503dd1b4eaaffbd203652835e171ae5e810b3e5.tar.bz2
pfsense-packages-7503dd1b4eaaffbd203652835e171ae5e810b3e5.zip
Add lots of input validations to sanitize configuration, plus other fixes
- Allow reverse proxy to be used without running normal Squid proxy - Force users to select at least one proxy or reverse proxy interface when enabling Squid (unless reverse proxy is enabled) - Only allow to configure transparent proxy on interfaces where Squid is actually running (never had any effect otherwise anyway) - Only allow to configure HTTPS/SSL Interception on interfaces where transparent proxy is enabled (never had any effect otherwise anyway) - Do not add loopback interface twice when transparent proxy is enabled and loopback is selected in Proxy Interface(s) - Avoid adding empty localnet ACL - Fix HTTPS proxy default port - Some code style fixes and cleanups
Diffstat (limited to 'config/squid3/34')
-rwxr-xr-xconfig/squid3/34/squid.inc159
1 files changed, 121 insertions, 38 deletions
diff --git a/config/squid3/34/squid.inc b/config/squid3/34/squid.inc
index aab4d134..763fe34c 100755
--- a/config/squid3/34/squid.inc
+++ b/config/squid3/34/squid.inc
@@ -66,7 +66,7 @@ define('SQUID_CONFBASE', SQUID_LOCALBASE .'/etc/squid');
define('SQUID_CONFFILE', SQUID_CONFBASE . '/squid.conf');
define('SQUID_ACLDIR', '/var/squid/acl');
define('SQUID_PASSWD', '/var/etc/squid.passwd');
-define('SQUID_SSL_DB','/var/squid/lib/ssl_db');
+define('SQUID_SSL_DB', '/var/squid/lib/ssl_db');
$valid_acls = array();
@@ -148,15 +148,11 @@ function squid_enabled() {
// check whether Squid is enabled ...
if ($config['installedpackages']['squid']['config'][0]['enable_squid'] == "on") {
// ... and has at least one interface configured ...
- if ($config['installedpackages']['squid']['config'][0]['active_interface'] != "") {
+ if (!empty($config['installedpackages']['squid']['config'][0]['active_interface'])) {
+ $proxy_enabled = true;
+ // ... or whether Squid reverse proxy is enabled
+ } elseif (squid_reverse_enabled()) {
$proxy_enabled = true;
- } else {
- // ... or has at least one reverse interface configured
- if (is_array($config['installedpackages']['squidreversegeneral']['config'])) {
- if ($config['installedpackages']['squidreversegeneral']['config'][0]['reverse_interface'] != "") {
- $proxy_enabled = true;
- }
- }
}
}
}
@@ -724,16 +720,27 @@ function squid_validate_general($post, &$input_errors) {
// force users to configure cache
if (!is_array($config['installedpackages']['squidcache']['config'])) {
- $input_errors[] = 'Please, configure and save \'Local Cache\' settings first.';
+ $input_errors[] = "Please, configure and save 'Local Cache' settings first.";
}
- $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
- $port = $post['proxy_port'] ? $post['proxy_port'] : $port;
+ // force users to select at least one proxy or reverse proxy interface when enabling Squid
+ if ($post['enable_squid'] == "on") {
+ // if reverse proxy is configured, perhaps the user wants to use the reverse proxy features only
+ if (!squid_reverse_enabled()) {
+ if (empty($post['active_interface'])) {
+ $input_errors[] = "You must select at least one interface under 'Proxy Interface(s)' to enable Squid proxy.";
+ $input_errors[] = "If you intend to use Squid as reverse proxy ONLY, then visit Services: Squid Proxy Server: General, configure and save the reverse proxy settings first.";
+ }
+ } else {
+ log_error("[squid] Enabled as reverse proxy ONLY. If this is not what you intended, visit Services: Squid Proxy Server: General and configure proxy interfaces.");
+ }
+ }
$icp_port = trim($post['icp_port']);
if (!empty($icp_port) && !is_port($icp_port)) {
- $input_errors[] = 'You must enter a valid port number in the \'ICP port\' field.';
+ $input_errors[] = "You must enter a valid port number in the 'ICP port' field.";
}
+ unset($icp_port);
if (substr($post['log_dir'], -1, 1) == '/') {
$input_errors[] = 'Log location must not end with a / character.';
@@ -748,26 +755,66 @@ function squid_validate_general($post, &$input_errors) {
}
$log_rotate = trim($post['log_rotate']);
-
if (!empty($log_rotate) && (!is_numericint($log_rotate) or ($log_rotate < 1))) {
$input_errors[] = "You must enter a valid number of days in the 'Log rotate' field.";
}
+ unset($log_rotate);
+ // check that the proxy port does not clash with WebGUI
+ $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
+ $port = $post['proxy_port'] ? $post['proxy_port'] : $port;
$webgui_port = $config['system']['webgui']['port'];
-
if (($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "http")) {
$webgui_port = 80;
}
if (($config['system']['webgui']['port'] == "") && ($config['system']['webgui']['protocol'] == "https")) {
$webgui_port = 443;
}
-
if (($post['transparent_proxy'] != 'on') && ($port == $webgui_port)) {
$input_errors[] = "You can not run Squid on the same port as the pfSense WebGUI";
}
+ unset($port, $webgui_port);
+
+ if ($post['transparent_proxy'] == 'on') {
+ if (empty($post['transparent_active_interface'])) {
+ $input_errors[] = "You must select at least one interface under 'Transparent Proxy Interface(s)' when 'Transparent HTTP Proxy' is enabled.";
+ } else {
+ // allow transparent proxy only on interfaces where Squid is actually running to keep configuration sane
+ $a_ifaces = $post['active_interface'] ?: array();
+ $t_ifaces = $post['transparent_active_interface'];
+ foreach ($t_ifaces as $t_iface) {
+ if (!in_array($t_iface, $a_ifaces)) {
+ $err_iface = convert_friendly_interface_to_friendly_descr($t_iface);
+ $input_errors[] = "'Transparent Proxy Interface(s)' may only contain interfaces also selected in 'Proxy Interface(s)' above. '{$err_iface}' is not valid.";
+ unset($err_iface);
+ }
+ }
+ unset($a_ifaces, $t_iface, $t_ifaces);
+ }
+ }
- if (($post['ssl_proxy'] == 'on') && ( $post['dca'] == '')) {
- $input_errors[] = "SSL interception cannot be enabled without a CA.";
+ if ($post['ssl_proxy'] == 'on') {
+ if ($post['transparent_proxy'] != 'on') {
+ $input_errors[] = "SSL interception cannot be enabled without enabling 'Transparent HTTP Proxy'.";
+ }
+ if ($post['dca'] == 'none') {
+ $input_errors[] = "SSL interception cannot be enabled without a CA.";
+ }
+ if (empty($post['ssl_active_interface'])) {
+ $input_errors[] = "You must select at least one interface under 'SSL Intercept Interface(s)' when 'HTTPS/SSL Interception' is enabled.";
+ } else {
+ // allow HTTPS/SSL Interception only on interfaces where transparent proxy is enabled
+ $t_ifaces = $post['transparent_active_interface'] ?: array();
+ $s_ifaces = $post['ssl_active_interface'];
+ foreach ($s_ifaces as $s_iface) {
+ if (!in_array($s_iface, $t_ifaces)) {
+ $err_iface = convert_friendly_interface_to_friendly_descr($s_iface);
+ $input_errors[] = "'SSL Intercept Interface(s)' may only contain interfaces also selected in 'Transparent Proxy Interface(s)' above. '{$err_iface}' is not valid.";
+ unset($err_iface);
+ }
+ }
+ unset($t_ifaces, $s_ifaces, $s_iface);
+ }
}
foreach (array('defined_ip_proxy_off') as $hosts) {
@@ -778,6 +825,8 @@ function squid_validate_general($post, &$input_errors) {
}
}
}
+ unset($host, $hosts);
+
foreach (array('defined_ip_proxy_off_dest') as $hosts) {
foreach (explode(";", $post[$hosts]) as $host) {
$host = trim($host);
@@ -786,6 +835,7 @@ function squid_validate_general($post, &$input_errors) {
}
}
}
+ unset($host, $hosts);
if (!empty($post['dns_nameservers'])) {
$altdns = explode(";", ($post['dns_nameservers']));
@@ -796,6 +846,7 @@ function squid_validate_general($post, &$input_errors) {
}
}
}
+ unset($altdns, $dnssrv);
}
/* Proxy Server: Remote Proxy Settings input validation */
@@ -823,6 +874,7 @@ function squid_validate_upstream($post, &$input_errors) {
}
}
}
+ unset($port);
}
/* Proxy Server: Cache Management input validation */
@@ -846,17 +898,20 @@ function squid_validate_cache($post, &$input_errors) {
$input_errors[] = "You must enter a valid value for '$field'.";
}
}
+ unset($num_fields);
$value = trim($post['minimum_object_size']);
if (!is_numericint($value)) {
$input_errors[] = "You must enter a valid value for 'Minimum object size'.";
}
+ unset($value);
if (!empty($post['cache_swap_low'])) {
$value = trim($post['cache_swap_low']);
if (!is_numericint($value) || ($value > 100)) {
$input_errors[] = "You must enter a valid value for 'Low-water-mark'.";
}
+ unset($value);
}
if (!empty($post['cache_swap_high'])) {
@@ -864,6 +919,7 @@ function squid_validate_cache($post, &$input_errors) {
if (!is_numericint($value) || ($value > 100)) {
$input_errors[] = "You must enter a valid value for 'High-water-mark'.";
}
+ unset($value);
}
if ($post['donotcache'] != "") {
@@ -873,6 +929,7 @@ function squid_validate_cache($post, &$input_errors) {
$input_errors[] = "The host '$host' is not a valid IP or hostname.";
}
}
+ unset($host);
}
if (substr($post['harddisk_cache_location'], -1, 1) == '/') {
@@ -897,6 +954,7 @@ function squid_validate_nac($post, &$input_errors) {
$input_errors[] = "'Allowed Subnets' must be a valid CIDR range or 'all'. The subnet '$subnet' is not valid.";
}
}
+ unset($allowed_subnets);
foreach (array('unrestricted_hosts', 'banned_hosts') as $hosts) {
if (preg_match_all("@([0-9.]+)(/[0-9.]+|)@", $_POST[$hosts], $matches)) {
@@ -921,6 +979,7 @@ function squid_validate_nac($post, &$input_errors) {
$input_errors[] = "'$mac' is not a valid MAC address.";
}
}
+ unset($mac);
}
foreach (explode(",", $post['timelist']) as $time) {
@@ -929,6 +988,7 @@ function squid_validate_nac($post, &$input_errors) {
$input_errors[] = "The time range '$time' is not a valid time range.";
}
}
+ unset($time);
if (!empty($post['ext_cachemanager'])) {
$extmgr = explode(";", ($post['ext_cachemanager']));
@@ -938,6 +998,7 @@ function squid_validate_nac($post, &$input_errors) {
}
}
}
+ unset($extmgr);
}
/* Proxy server: Traffic Management input validation */
@@ -955,6 +1016,7 @@ function squid_validate_traffic($post, &$input_errors) {
$input_errors[] = "The '$name' field must contain a positive integer.";
}
}
+ unset($num_fields);
if (!empty($post['quick_abort_min'])) {
$value = trim($post['quick_abort_min']);
@@ -982,6 +1044,7 @@ function squid_validate_traffic($post, &$input_errors) {
if ($post['throttle_binaries'] == "" && $post['throttle_cdimages'] == "" && $post['throttle_multimedia'] == "" && $others == "") {
$input_errors[] = "'Throttle Only Specific Extensions' enabled but no extensions specified. Select some options under 'Squid Transfer Extension Settings' or disable this option.";
}
+ unset($others);
}
}
@@ -999,6 +1062,7 @@ function squid_validate_auth($post, &$input_errors) {
$input_errors[] = "The '{$field[1]}' field must contain a valid number greater than {$field[2]}";
}
}
+ unset($num_fields);
$auth_method = $post['auth_method'];
if (($auth_method != 'none') && ($auth_method != 'local') && ($auth_method != 'cp')) {
@@ -1046,6 +1110,7 @@ function squid_validate_auth($post, &$input_errors) {
}
}
}
+ unset($auth_method, $port, $server, $secret, $user);
}
/* Proxy Server: General Settings configuration handler */
@@ -1108,7 +1173,7 @@ function squid_resync_general() {
}
}
$port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
- $ssl_port = ($settings['ssl_proxy_port'] ? $settings['ssl_proxy_port'] : 3127);
+ $ssl_port = ($settings['ssl_proxy_port'] ? $settings['ssl_proxy_port'] : 3129);
// Read assigned interfaces
$real_ifaces = array();
@@ -1116,7 +1181,7 @@ function squid_resync_general() {
if ($settings['active_interface']) {
$proxy_ifaces = explode(",", $settings['active_interface']);
} else {
- $proxy_ifaces = array("lan");
+ $proxy_ifaces = array();
}
if ($settings['transparent_proxy'] == "on") {
@@ -1136,7 +1201,7 @@ function squid_resync_general() {
foreach ($ssl_ifaces as $s_iface) {
$s_iface_ip = squid_get_real_interface_address($s_iface);
if ($s_iface_ip[0]) {
- $real_ifaces[]=$s_iface_ip;
+ $real_ifaces[] = $s_iface_ip;
}
}
} else {
@@ -1147,11 +1212,16 @@ function squid_resync_general() {
foreach ($proxy_ifaces as $iface) {
$iface_ip = squid_get_real_interface_address($iface);
if ($iface_ip[0]) {
- $real_ifaces[] = $iface_ip;
- if (in_array($iface, $ssl_ifaces)) {
- $conf .= "http_port {$iface_ip[0]}:{$port} {$ssl_interception}\n";
+ // do not add loopback twice when transparent proxy is enabled
+ if ($iface_ip[0] == "127.0.0.1" && $settings['transparent_proxy'] == "on") {
+ continue;
} else {
- $conf .= "http_port {$iface_ip[0]}:{$port}\n";
+ $real_ifaces[] = $iface_ip;
+ if (in_array($iface, $ssl_ifaces)) {
+ $conf .= "http_port {$iface_ip[0]}:{$port} {$ssl_interception}\n";
+ } else {
+ $conf .= "http_port {$iface_ip[0]}:{$port}\n";
+ }
}
}
}
@@ -1165,7 +1235,7 @@ function squid_resync_general() {
}
}
$icp_port = ($settings['icp_port'] ? $settings['icp_port'] : 0);
- $dns_v4_first = ($settings['dns_v4_first'] == "on" ? "on" : "off" );
+ $dns_v4_first = ($settings['dns_v4_first'] == "on" ? "on" : "off");
$piddir = "{$g['varrun_path']}/squid";
$pidfile = "{$piddir}/squid.pid";
if (!is_dir($piddir)) {
@@ -1237,9 +1307,11 @@ EOD;
}
}
}
- $conf .= "# Allow local network(s) on interface(s)\n";
- $conf .= "acl localnet src $src\n";
- $valid_acls[] = 'localnet';
+ if (!empty($src)) {
+ $conf .= "# Allow local network(s) on interface(s)\n";
+ $conf .= "acl localnet src $src\n";
+ $valid_acls[] = 'localnet';
+ }
}
if ($settings['xforward_mode']) {
@@ -1411,25 +1483,33 @@ function squid_resync_upstream() {
function squid_resync_nac() {
global $config, $valid_acls;
- $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
if (is_array($config['installedpackages']['squidnac'])) {
$settings = $config['installedpackages']['squidnac']['config'][0];
} else {
$settings = array();
}
+ if (is_array($config['installedpackages']['squid'])) {
+ $squidsettings = $config['installedpackages']['squid']['config'][0];
+ } else {
+ $squidsettings = array();
+ }
+
$webgui_port = $config['system']['webgui']['port'];
$addtl_ports = $settings['addtl_ports'];
$addtl_sslports = $settings['addtl_sslports'];
- $port = ($settings['proxy_port'] ? $settings['proxy_port'] : 3128);
- $ssl_port = ($settings['ssl_proxy_port'] ? $settings['ssl_proxy_port'] : 3127);
+ // do not add (default) proxy ports when using Squid as reverse proxy only
+ if (!empty($squidsettings['active_interface'])) {
+ $port = $squidsettings['proxy_port'] ? $squidsettings['proxy_port'] : 3128;
+ $ssl_port = $squidsettings['ssl_proxy_port'] ? $squidsettings['ssl_proxy_port'] : 3129;
+ }
$conf = <<< EOD
# Setup some default acls
# From 3.2 further configuration cleanups have been done to make things easier and safer. The manager, localhost, and to_localhost ACL definitions are now built-in.
# acl localhost src 127.0.0.1/32
acl allsrc src all
-acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 $webgui_port $port $ssl_port 1025-65535 $addtl_ports
-acl sslports port 443 563 $webgui_port $addtl_sslports
+acl safeports port 21 70 80 210 280 443 488 563 591 631 777 901 {$webgui_port} {$port} {$ssl_port} 1025-65535 {$addtl_ports}
+acl sslports port 443 563 {$webgui_port} {$addtl_sslports}
# From 3.2 further configuration cleanups have been done to make things easier and safer. The manager, localhost, and to_localhost ACL definitions are now built-in.
#acl manager proto cache_object
@@ -1731,9 +1811,9 @@ function squid_resync_auth() {
$conf .= "always_direct allow all\n";
$conf .= "ssl_bump server-first all\n";
}
- $conf .= "# Setup allowed acls\n";
+ $conf .= "# Setup allowed ACLs\n";
$allowed = array('allowed_subnets');
- if ($settingsconfig['allow_interface'] == 'on') {
+ if ($settingsconfig['allow_interface'] == 'on' && !empty($settingsconfig['active_interface'])) {
$conf .= "# Allow local network(s) on interface(s)\n";
$allowed[] = "localnet";
}
@@ -1952,10 +2032,13 @@ function squid_generate_rules($type) {
file_put_contents($cp_file, $new_cp_inc, LOCK_EX);
}
- // do not install any firewall rules if Squid is disabled
+ // do not install any firewall rules if Squid is disabled or used as reverse proxy only
if (!squid_enabled()) {
log_error("[squid] Installed but disabled. Not installing '{$type}' rules.");
return;
+ } elseif (empty($squid_conf['active_interface'])) {
+ log_error("[squid] Configured as reverse proxy only. Not installing '{$type}' rules.");
+ return;
}
// normal squid rule check
@@ -1984,7 +2067,7 @@ function squid_generate_rules($type) {
}
$port = ($squid_conf['proxy_port'] ? $squid_conf['proxy_port'] : 3128);
- $ssl_port = ($squid_conf['ssl_proxy_port'] ? $squid_conf['ssl_proxy_port'] : 3127);
+ $ssl_port = ($squid_conf['ssl_proxy_port'] ? $squid_conf['ssl_proxy_port'] : 3129);
$fw_aliases = filter_generate_aliases();
if (strstr($fw_aliases, "pptp =")) {