Squid with SSLbump and authentification 403. It is an encapsulated request do not authenticate - squid

I have a problem with my squid v3.5.27.
squid.conf
acl auth proxy_auth REQUIRED
acl basicauth proxy_auth_regex -i service
http_access deny !auth
http_access deny basicauth
http_access allow all
http_port 0.0.0.0:3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/etc/squidCA.pem
ssl_bump bump all
sslproxy_cert_error deny all
sslproxy_flags DONT_VERIFY_PEER
sslcrtd_program /usr/lib64/squid/ssl_crtd -s /etc/squid/ssl_db -M 10MB
Iam authentificated by USERTEST, but get TCP_DENIED/403, when I try to open any sites
access.log:
17/May/2018:12:35:18 +0300 10.0.5.177 USERTEST TCP_DENIED/403 https://rbc.ru "-"
cache.log:
2018/05/17 12:35:18.484 kid1| 28,3| Checklist.cc(70) preCheck: 0x38457c8 checking slow rules
2018/05/17 12:35:18.484 kid1| 28,5| Acl.cc(138) matches: checking http_access
2018/05/17 12:35:18.484 kid1| 28,5| Checklist.cc(400) bannedAction: Action 'DENIED/0' is not banned
2018/05/17 12:35:18.484 kid1| 28,5| Acl.cc(138) matches: checking http_access#1
2018/05/17 12:35:18.484 kid1| 28,5| Acl.cc(138) matches: checking !auth
2018/05/17 12:35:18.484 kid1| 28,5| Acl.cc(138) matches: checking auth
2018/05/17 12:35:18.484 kid1| 28,5| Acl.cc(36) AuthenticateAcl: SslBumped request: It is an encapsulated request do not authenticate
2018/05/17 12:35:18.484 kid1| 28,3| Acl.cc(158) matches: checked: auth = 1
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: !auth = 0
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: http_access#1 = 0
2018/05/17 12:35:18.485 kid1| 28,5| Checklist.cc(400) bannedAction: Action 'ALLOWED/0' is not banned
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(138) matches: checking http_access#2
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(138) matches: checking basicauth
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(36) AuthenticateAcl: SslBumped request: It is an encapsulated request do not authenticate
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: basicauth = 1
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(138) matches: checking sites1
2018/05/17 12:35:18.485 kid1| 28,3| DomainData.cc(108) match: aclMatchDomainList: checking 'www.rbc.ru'
2018/05/17 12:35:18.485 kid1| 28,3| DomainData.cc(113) match: aclMatchDomainList: 'www.rbc.ru' NOT found
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: sites1 = 0
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: http_access#2 = 0
2018/05/17 12:35:18.485 kid1| 28,5| Checklist.cc(400) bannedAction: Action 'DENIED/0' is not banned
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(138) matches: checking http_access#3
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(138) matches: checking basicauth
2018/05/17 12:35:18.485 kid1| 28,5| Acl.cc(36) AuthenticateAcl: SslBumped request: It is an encapsulated request do not authenticate
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: basicauth = 1
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: http_access#3 = 1
2018/05/17 12:35:18.485 kid1| 28,3| Acl.cc(158) matches: checked: http_access = 1
2018/05/17 12:35:18.485 kid1| 28,3| Checklist.cc(63) markFinished: 0x38457c8 answer DENIED for match
2018/05/17 12:35:18.485 kid1| 28,3| Checklist.cc(163) checkCallback: ACLChecklist::checkCallback: 0x38457c8 answer=DENIED
2018/05/17 12:35:18.485 kid1| 28,5| Gadgets.cc(83) aclIsProxyAuth: aclIsProxyAuth: called for basicauth
2018/05/17 12:35:18.485 kid1| 28,9| Acl.cc(99) FindByName: ACL::FindByName 'basicauth'
2018/05/17 12:35:18.485 kid1| 28,5| Gadgets.cc(88) aclIsProxyAuth: aclIsProxyAuth: returning 1
2018/05/17 12:35:18.485 kid1| 28,8| Gadgets.cc(51) aclGetDenyInfoPage: got called for basicauth
2018/05/17 12:35:18.485 kid1| 28,8| Gadgets.cc(70) aclGetDenyInfoPage: aclGetDenyInfoPage: no match
As you can see I hit in acl basicauth = 1 and http_access#3 = 1 despite the fact that I have a different login. If I disable SSLbump - all works fine.
Any ideas?
Thanks

You can do something like this.
For Basic Authentication:
auth_param basic program /usr/bin/python /home/test/auth.py
auth_param basic realm Please enter username and password
auth_param basic children 100
auth_param basic credentialsttl 1 second
acl AuthUsers proxy_auth REQUIRED
In the above, test.py represents you can write your custom python script for the authentication or you can also use any other method.
and for ssl-bump you can do:
http_port 3128 ssl-bump cert=/etc/squid/ssl/myca.pem generate-host-
certificates=on dynamic_cert_mem_cache_size=4MB
sslcrtd_program /usr/lib/squid/ssl_crtd -s /var/spool/squid_ssldb -M 4MB
sslcrtd_children 5
acl tcp_level at_step SslBump1
ssl_bump peek tcp_level all
ssl_bump bump all
and for allowing the access
http_access allow AuthUsers
http_access deny all

Related

I'm having a CORS Prefetch Error 400 Bad Request

I am running a Vue project on my local dev server with a firebase function also running on local dev. Whenever I try to make a fetch request to my "beckend" I get a CORS error.
PREFLIGHT REQEUST
OPTIONS /api/url HTTP/1.1
Host: localhost:5001
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
RESPONSE
HTTP/1.1 400 Bad Request
x-powered-by: Express
access-control-allow-origin: http://localhost:8080
access-control-allow-methods: POST, OPTIONS
access-control-allow-headers: Content-Type
content-type: application/json; charset=utf-8
content-length: 44
etag: W/"2c-1mdAJaORqKZ8xUSbM/cjasU4RC0"
date: Tue, 20 Jul 2021 14:40:25 GMT
connection: keep-alive
keep-alive: timeout=5
Here's my code:
FRONTEND
fetch(/api/url, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
currency: "usd",
paymentMethodType: "card",
amount: 1880,
}),
}).then();
BACKEND
exports.myFunctionName = functions.https.onRequest(async (req, res) => {
const origin = req.headers.origin;
if (ALLOWED_ORIGINS.includes(origin)) {
res.setHeader("Access-Control-Allow-Origin", origin);
}
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
const {paymentMethodType, currency, amount} = req.body;
const params = {
payment_method_types: [paymentMethodType],
amount: +amount,
currency: currency,
};
try {
// Create a PaymentIntent with the amount, currency, and a payment method type.
const paymentIntent = await stripe.paymentIntents.create(params);
// Send publishable key and PaymentIntent details to client
res.status(200).json({
clientSecret: paymentIntent.client_secret,
});
} catch (e) {
return res.status(400).json({
error: {
message: e.message,
},
});
}
}
I can't seem to figure this out, I've been working at it for a few hours. Can anyone help?
The problem is your function treats the preflight request as if it were the actual POST request, but they're separate and not sent simultaneously.
The browser automatically sends the OPTIONS preflight request (which has no body) before the POST. Your function tries to pass non-existent body parameters from OPTIONS to the Stripe API, resulting in an exception caught by your catch handler, which responds with a 400.
The backend function should respond to OPTIONS with an ok status (e.g., 200) before the browser can send the POST request:
exports.myFunctionName = functions.https.onRequest(async (req, res) => {
// Handle preflight request
if (req.method === "OPTIONS") {
// allow `POST` from all origins for local dev
res.set("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "POST");
return res.sendStatus(200);
} else {
// Handle `POST` request here...
}
}

Identity Server 4 ASP.NET Quickstart 'refused connection'

I'm following the Identity Server 4 Quickstart and I'm having a weird issue even though I followed it step by step.
It says (translated from German) connection denied by target computer.
Whats weird about this is that in the API project "we"(I) said ValidateAudience = false which I thought meant that tokens aren't being validated at all.
// call api
var apiClient = new HttpClient();
apiClient.SetBearerToken(tokenResponse.AccessToken);
var response = await apiClient.GetAsync("https://localhost:6001/identity");
if (!response.IsSuccessStatusCode)
{
Console.WriteLine(response.StatusCode);
}
else
{
var content = await response.Content.ReadAsStringAsync();
Console.WriteLine(JArray.Parse(content));
}
I am truly confused.The Client does get an accessToken so that's not the problem ... I hope.
Github-Repo
Invoking IdentityServer endpoint: IdentityServer4.Endpoints.TokenEndpoint for /connect/token
[16:15:42 Debug] IdentityServer4.Endpoints.TokenEndpoint
Start token request.
[16:15:42 Debug] IdentityServer4.Validation.ClientSecretValidator
Start client validation
[16:15:42 Debug] IdentityServer4.Validation.BasicAuthenticationSecretParser
Start parsing Basic Authentication secret
[16:15:42 Debug] IdentityServer4.Validation.PostBodySecretParser
Start parsing for secret in post body
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListParser
Parser found secret: PostBodySecretParser
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListParser
Secret id found: client
[16:15:42 Debug] IdentityServer4.Stores.ValidatingClientStore
client configuration validation for client client succeeded.
[16:15:42 Debug] IdentityServer4.Validation.ISecretsListValidator
Secret validator success: HashedSharedSecretValidator
[16:15:42 Debug] IdentityServer4.Validation.ClientSecretValidator
Client validation success
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
Start token request validation
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
Start client credentials token request validation
[16:15:42 Debug] IdentityServer4.Validation.TokenRequestValidator
client credentials token request validation success
[16:15:42 Information] IdentityServer4.Validation.TokenRequestValidator
Token request validation success, {"ClientId": "client", "ClientName": null, "GrantType": "client_credentials", "Scopes": "api1", "AuthorizationCode": null, "RefreshToken": null, "UserName": null, "AuthenticationContextReferenceClasses": null, "Tenant": null, "IdP": null, "Raw": {"grant_type": "client_credentials", "scope": "api1", "client_id": "client", "client_secret": "***REDACTED***"}, "$type": "TokenRequestValidationLog"}
[16:15:42 Debug] IdentityServer4.Services.DefaultClaimsService
Getting claims for access token for client: client
[16:15:42 Debug] IdentityServer4.Endpoints.TokenEndpoint
Token request success.
I think setting ValidateAudience = false will just ignore the audience claim, but still validate the other things in the token.
You can set the IncludeErrorDetails property to true and like this:
.AddJwtBearer(options =>
{
options.Audience = "payment";
options.Authority = "https://localhost:6001/";
//True if token validation errors should be returned to the caller.
options.IncludeErrorDetails = true;
When you set it to True, then you will get more details in the response header, like:
HTTP/1.1 401 Unauthorized
Date: Sun, 02 Aug 2020 11:19:06 GMT
WWW-Authenticate: Bearer error="invalid_token", error_description="The signature is invalid"
To further help you out, please post a sample access token and API configuration (Startup class)
See this article for further details
So in API/Properties/lauchsettings .... when generating the project it used a default sheme and in that sheme it sets a port of 43033 or smth

Symfony http cache manage dynamic expires time or how to invalidate cache?

I not understand how to invalidate cache, because my appliaction not called when I return request with Expires header in first time and then application not called when try to call same request again
$response
->setExpires($this->helper->getExpiresHttpCache());
And I added class
class CacheKernel extends HttpCache
{
protected function invalidate(Request $request, $catch = false)
{
if ('PURGE' !== $request->getMethod()) {
return parent::invalidate($request, $catch);
}
if ('127.0.0.1' !== $request->getClientIp()) {
return new Response(
'Invalid HTTP method',
Response::HTTP_BAD_REQUEST
);
}
$response = new Response();
if ($this->getStore()->purge($request->getUri())) {
$response->setStatusCode(Response::HTTP_OK, 'Purged');
} else {
$response->setStatusCode(Response::HTTP_NOT_FOUND, 'Not found');
}
return $response;
}
protected function getOptions()
{
return [
'default_ttl' => 0,
];
}
}
and in index.php add
$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
// Wrap the default Kernel with the CacheKernel one in 'prod' environment
if ('prod' === $kernel->getEnvironment()) {
$kernel = new CacheKernel($kernel);
}
but http cache works for each envirometns. Only when in browser disable checkbox Disable cache application will calling.
In browser I had correct header Expires: Fri, 01 May 2020 11:59:00 GMT. And if sent request again, with enable debug, debug not entered in application, but response contain result data. In this case General section contain Status Code: 200 OK (from disk cache)
Request URL: http://symfony.localhost/api/products/extra_fields
Request Method: GET
Status Code: 200 OK (from disk cache)
Remote Address: [::1]:80
Referrer Policy: no-referrer-when-downgrade
But wehere this point where compare current time and exprires time ? Example I want use global variables for expires time. Example after call some another api request api/product/{id} I want to change expires time for /api/products/extra_fields, but aplication not called, where I can manage it or it possible ? Could someone help me figure out how to manage it ?
Response
HTTP/1.1 200 OK
Server: nginx
Content-Type: application/json
X-Powered-By: PHP/7.3.14
Cache-Control: private, must-revalidate
Date: Fri, 01 May 2020 07:39:35 GMT
Expires: Fri, 01 May 2020 11:59:00 GMT
Request
GET /api/products/extra_fields HTTP/1.1
accept: application/json
Referer: http://symfony.localhost/api/doc
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36

squid3 TCP_MISS even even saying "Serving from cache"

I would like to setup a proxy to cache microsoft sharepoint online. However, even getting some progresses, I still could not understand why it is still TCP_MISS.
OS: Centos 7
Squid: initially 3.3.8 (centos default) and upgraded to 3.5.22 later
ssl_bump is utilised for https interception
refresh pattern:
refresh_pattern -i .(xz|rpm) 14400 50% 18000 override-expire override-lastmod ignore-reload ignore-no-cache ignore-private ignore-auth
the test file for downloading is kernel-plus-3.10.0-327.10.1.el7.centos.plus.x86_64.rpm which was uploaded to sharepoint.
with "debug_options 22,70,9", I am getting messages in cache.log as follows:
2016/12/08 16:36:10.383 kid1| ctx: exit level 0
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(291) refreshCheck: checking freshness of 'https ://xxx.sharepoint.com/sites/its/itst/int/kernel-plus-3.10.0-327.10.1.el7.centos.plus.x86_64.rpm'
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(312) refreshCheck: Matched '.(xz|rpm) 864000 50%% 1080000'
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(314) refreshCheck: age: 2225
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(316) refreshCheck: check_time: Thu, 08 Dec 2016 21:36:10 GMT
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(318) refreshCheck: entry->timestamp: Thu, 08 Dec 2016 20:59:05 GMT
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(173) refreshStaleness: STALE: expires 1481230745 < check_time 1481232970
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(338) refreshCheck: Staleness = 2225
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(362) refreshCheck: YES: Must revalidate stale object (origin set no-cache or private)
2016/12/08 16:36:10.384 kid1| 22,3| refresh.cc(654) getMaxAge: getMaxAge: 'https ://xxx.sharepoint.com/sites/its/itst/int/kernel-plus-3.10.0-327.10.1.el7.centos.plus.x86_64.rpm'
2016/12/08 16:36:12.247 kid1| ctx: enter level 0: 'https ://xxx.sharepoint.com/sites/its/itst/int/kernel-plus-3.10.0-327.10.1.el7.centos.plus.x86_64.rpm'
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(291) refreshCheck: checking freshness of 'https ://xxx.sharepoint.com/sites/its/itst/int/kernel-plus-3.10.0-327.10.1.el7.centos.plus.x86_64.rpm'
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(312) refreshCheck: Matched '.(xz|rpm) 864000 50%% 1080000'
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(314) refreshCheck: age: 63
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(316) refreshCheck: check_time: Thu, 08 Dec 2016 21:37:12 GMT
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(318) refreshCheck: entry->timestamp: Thu, 08 Dec 2016 21:36:09 GMT
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(173) refreshStaleness: STALE: expires 1481232969 < check_time 1481233032
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(338) refreshCheck: Staleness = 63
2016/12/08 16:36:12.247 kid1| 22,3| refresh.cc(497) refreshCheck: NO: Serving from cache - even though explicit expiry has passed, we enforce Min value (override-expire option)
2016/12/08 16:36:12.247 kid1| 22,3| http.cc(482) cacheableReply: YES because HTTP status 200
and TCP_MISS in access.log.
my questions are:
1. why did squid refreshcheck twice on one downloading request?
2. I guess that the squid decides to "Serving from cache" in the second refreshcheck, why still TCP_MISS in access.log?
if offline_mode is on, the cache has served the download happily with TCP_OFFLINE_HIT.
Please advise how could I fix the issue.
Thanks in advance.

Nodejs: apply headers and get response

I have the following GET request:
GET http://www.google.ie/ HTTP/1.1
Host: www.google.ie
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:5.0) Gecko/20100101 Firefox/5.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip, deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Proxy-Connection: keep-alive
Cookie: PREF=ID=0000043ea43e2426:U=204008a193b06a93:FF=0:TM=1310983818:LM=1310983985:S=HhQ3hzHoRpfrsFN4; NID=50=bT7R608p1asdflr9QiJ_cY80WjaFZ6cB-IJGLT6rpSdiH6bQwnxAEDGTJ1k4K3-A4Y6327iyepbXL6d3fnomtBcWXPQ7A5Px1zckZGBoo8gtMrixSGneodtc7IIaxSu; SID=DQAAALcAAACa0eOu2S9ezDasdfx32stdYzKQQCc7Q4dcYucZkXOaQkXKmfkr0iMlPQZkwy4PlQLzZsiO_5_lLDclyBDJsJIKU0my000owlYMX14K22pBopTN1EUlOrJ7LIkwhznasdfBleSojFfhMbn0BoYM1WAzwnpMAttoAuzG0bZXcScgZkDizC2FUHXVV3-eHZPrS2ncychNguPNZ_M9V_oEtoqJUmqasdf_kaKTOM2KnT0P5wMswKru8_KrkwK6iCc7ag; HSID=A78ACtAr9H6MYp-dn
Cache-Control: max-age=0
I want to get the reponse in node.js. Can someone please point me in the right direction as to how I might do this?
Many thanks in advance,
One place to start is the http module docs for http.request.
Is it, proxy? If so, then you can use such proxy:
var net = require('net');
// Create TCP-server
var server = net.createServer( function(soc){ // soc is socket generated by net.Server
// Incoming request processing
soc.on('data', function(data){
// Create new socket
var client = net.Socket();
// Get host from HTTP headers
var re = /[^\n]+(\r\n|\r|\n)host:\w*([^:\r\n]+)/i;
var host = data.toString('utf-8').match(re);
// Pause soc for inner socket connection
soc.pause();
// Connect to Node.js application
client.connect(80, host);
client.on('connect', function()
{
// Write request to your node.js application
client.write(data.toString('utf-8'));
});
client.on('data', function(cdata)
{
// Return socket to live
soc.resume();
// Write client data to browser
soc.write(cdata.toString('utf-8'));
soc.pipe(soc);
soc.end();
});
client.on('end', function(){
client.destroy();
});
});
}
);
server.on('error', function (err){
// Error processing i just pass whole object
console.log(err);
});
server.listen(8088);
console.log('Server is listening %d\n', 8088);

Resources