WSO2 APIM gateway is setting Host header as host:port - wso2

APIM gateway is setting Host header as host:port to call backend, like this:
GET /api/category HTTP/1.1 Accept-Language:
en-US,en;q=0.8,pt;q=0.6 token:
6785ea7b-#######-#######-93f06834660a Accept-Encoding: gzip,
deflate, sdch X-Forwarded-Server: server01 X-Forwarded-For:
172.XX.XXX.XX User-Agent: Mozilla/5.0 (X11; Linux x86_64) Postman-Token: ece4261e-d610-655c-f06c-f24a99f007c8 Accept:
/ X-Forwarded-Host: server01 Cache-Control: no-cache
Host: api.empresa.net:80 Connection: Keep-Alive
This causes problems with Web Application Firewall, how can I change this?
Enviroment: RedHat Linux 6.7, APIM 1.9.1
Thanks

I know your pain. We were running into the same problem with our load balancer. I believe there is a fix coming from WSO2 for this. In the meantime, you will need to create a custom "in" sequence under "/_system/governance/apimgt/customsequences/in" with the following content:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="remove_port_In">
<property name="REQUEST_HOST_HEADER" value="api.empresa.net" scope="axis2"/>
</sequence>
You can then associate this with your API as an inbound custom sequence through the publisher application prior to publishing.

As per the protocol specification,
The Host request-header field specifies the Internet host and port
number of the resource being requested, as obtained from the original
URI given by the user or referring resource.
Host = "Host" ":" host [ ":" port ] ; Section 3.2.2
A "host" without any trailing port information implies the default
port for the service requested (e.g., "80" for an HTTP URL). For
example, a request on the origin server for
http://www.w3.org/pub/WWW/ would properly include:
GET /pub/WWW/ HTTP/1.1
Host: www.w3.org

Related

Blazor Server Side - Frequent 504 errors in AWS environment

After deploying a blazor server side project to an Amazon Web Services environment via AWS Elastic Beanstalk, the website experiences frequent disconnects that I do not understand.
These disconnects do not happen locally when testing.
Errors:
[2020-04-30T16:29:18.326Z] Error: Connection disconnected with error 'Error'.
and
Failed to load resource: the server responded with a status of 504 ()
The request causing the 504 errors has a header like so:
Request URL: https://mywebserver/_blazor?id=UOPQELxzuEcaGbpNUQA01Q&_=1588264098305
Request Method: GET
Status Code: 504
Remote Address: 3.11.236.203:443
Referrer Policy: no-referrer-when-downgrade
content-length: 550
content-type: text/html
date: Thu, 30 Apr 2020 16:29:20 GMT
server: awselb/2.0
status: 504
:authority: mywebserver
:method: GET
:path: /_blazor?id=UOPQELxzuEcaGbpNUQA01Q&_=1588264098305
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-GB,en-US;q=0.9,en;q=0.8
content-type: text/plain;charset=UTF-8
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-origin
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36
x-requested-with: XMLHttpRequest
This issue seems remarkably similar to a Github issue posted here, that is currently being investigated by Microsoft, although this issue is not AWS-related: https://github.com/dotnet/aspnetcore/issues/19094
Any help would be vastly appreciated!
i managed to fix this in the end.
Apparently the issue was caused by the use of LongPolling. LongPolling issues requests and waits 100 seconds before cancelling the request. By setting the timeout to be greater than the default of 60 seconds in the Elastic Load Balancer in my AWS settings, the disconnects stopped. 110 seconds was recommended as a safe timeout value.
Issue on Asp.NET github that I opened for those interested: https://github.com/dotnet/aspnetcore/issues/21369

Azure Application Gateway blocks SOAP 1.2 request

I'm re-configuring an existing SOAP web service to run behind an Azure Application Gateway with Web Application Firewall.
The SOAP web service is written in C# and runs in Azure as a web role within an Azure Cloud Service. It supports both SOAP 1.1 and SOAP 1.2 at present.
I have configured an Azure Application Gateway, with the Web Application Firewall enabled, to run in front of this service. The WAF is using the OWASP 3.0 rule set.
Sending test requests from SoapUI, it appears that the Application Gateway WAF is allowing SOAP 1.1 requests through, but is blocking SOAP 1.2 requests (returning a 403 error). I can't find any reference to why this might be happening in the documentation or anything else. I know it's the WAF, because disabling it allows the SOAP 1.2 requests through.
The HTTP headers for the (working) SOAP 1.1 request look like this (service and namespace URLs removed):
POST http://{serviceURL}/{service}.asmx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "http://{namespaceURL}/{method}"
Content-Length: 3672
Host: {serviceURL}
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
The HTTP header for the (not working) SOAP 1.2 request looks like this:
POST http:/{serviceURL}/{service}.asmx HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://{namespaceURL}/{method}"
Content-Length: 3652
Host: {serviceURL}
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
Looking at the WAF logs, I think that the issue is the change to the Content-Type, which based on my (not in-depth) understanding of SOAP 1.2, is correct.
Any thoughts appreciated. It seems like SOAP remains in wide enough use that the Azure Appliction Gateway / WAF should support it.

invoking a SOAP webservice with telnet command

I came across a situation where I have to invoke a SOAP webservice (deployed in another server) from one of the production server manually and check whether everything is fine.
as these are all live servers there are no network tools like wget, curl and nc are available. I tried checking for a solution is google but no luck.
As a workaround I can write a java client socket and invoke the service but even that is not allowed in here.
telnet is there but am not sure how to make it work for my case.
Is there any other way to invoke remote services without these tools?
After trying few hours finally, I was able to invoke SOAP service with telnet as below
first open a TCP connection to the remote server as below.
$> telnet hostname portname
Once it is connected, frame a request as one of the below methods and paste on the screen and press enter key two times.
There are two ways we can call a service.
Method 1: instead of mentioning endpoint path in POST header, we can give it in SOAPAction header.
POST / HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: "<endpoint URL from WSDL>"
Content-Length: <number of bytes you are sending in body section>
Host: <hostname>:<port>
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<SOAP Request payload>
Method 2: mentioning endpoint path in the request header itself, so we can give empty value in "" SOAPAction header (it means request path itself is the Endpoint path).
POST /soap/server HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Content-Length: <payload size>
Host: hostname:port
Proxy-Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
<SOAP Request payload>
Response: Once the call invoked successfully, the response will be printed as below
HTTP/1.1 200 OK
Content-Type: text/xml;charset=UTF-8
Content-Length: <response payload size>
<SOAP response payload>
For more information on SOAPHeader check this link
Note: Make sure the length of the request payload is correct before sending it.

MS Http Server API (< Win 8) and WebSockets

I try to realize WebSocket protocol at MS Http Server API under win server 2008 (haven't HTTP_SEND_RESPONSE_FLAG_OPAQUE flag).
HTTP_RESPONSE response={0};
const char upgrade_val[]="Websocket";
response.Headers.KnownHeaders[HttpHeaderUpgrade].RawValueLength=strlen(upgrade_val);
response.Headers.KnownHeaders[HttpHeaderUpgrade].pRawValue =upgrade_val;
const char connection_val[]="Upgrade";
response.Headers.KnownHeaders[HttpHeaderConnection].RawValueLength=strlen(connection_val);
response.Headers.KnownHeaders[HttpHeaderConnection].pRawValue =connection_val;
HTTP_UNKNOWN_HEADER unknown[1];
response.Headers.UnknownHeaderCount=1;
response.Headers.pUnknownHeaders =unknown;
const char accept_name[]="Sec-WebSocket-Accept";
unknown[0].NameLength =_countof(accept_name)-1;
unknown[0].pName =accept_name;
unknown[0].RawValueLength=HANDSHAKE_KEY_LENGTH;
unknown[0].pRawValue =base64_key;
response.Version.MajorVersion=1;
response.Version.MinorVersion=1;
response.StatusCode =HTTP_SWITCHING_PROTOCOLS;
const char reason[] ="Switching Protocols";
response.ReasonLength =strlen(reason);
response.pReason =reason;
HttpSendHttpResponse(iocp,RequestId,HTTP_SEND_RESPONSE_FLAG_MORE_DATA,&raw_response,NULL,NULL,NULL,NULL,NULL,NULL);
Browser send header (from Fiddler)
GET http://server.host/ HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: server.host
Origin: null
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: V86c1TFOwWfZqhS42C0arA==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
server's response (from Fiddler)
HTTP/1.1 101 Switching Protocols
Upgrade: Websocket
Server: Microsoft-HTTPAPI/2.0
Sec-WebSocket-Accept: 3io2SU7uJIeFlwy0+OFJUDNrA44=
Date: Tue, 28 May 2013 09:27:59 GMT
EndTime: 13:27:59.006
ReceivedBytes: 0
SentBytes: 0
and browser shows 1016 error.
Assuming your Sec-WebSocket-Accept header value is calculated correctly, and assuming your response variable is supposed to be named raw_response instead, then your response is missing the required Connection: Upgrade header despite your code assigning a value for it.
HTTP_SEND_RESPONSE_FLAG_OPAQUE (Windows 8 and later) is required for WebSockets.
WebSocket servers on Windows Server (2011-12-20)
As it stands right now, Server 2008/R2 boxes cannot host WebSockets.
At least, not whilst sharing ports 80 and 443 with IIS web server
Re: [hybi] WebSocket protocol as it stands (2010-11-06)
we need to tweak http.sys to recognize what is really a non-HTTP
request, as an HTTP request

qt soap client + ASP.net Web service

I'm writing Qt client for ASP.NET web service with FORMS based authentication.
The service consists of 3 methods:
Login(user,pass)
Helloworld() - this method returns info about authenticated user.
Logout()
Every thing working fine on the dot.net client with CookieContainer.
The problem begins with HelloWorld() methods. it returns null because I can't access server session.
I'm doing the following:
from the response of Login() request I'm getting the cookies which are sent to client:
QNetworkAccessManager *manager = http.networkAccessManager();
cookie = manager->cookieJar();
When sending the second soaprequest for HelloWorld method I adding these cookies
to QtSoapHttpTransport http:
http.networkAccessManager()->setCookieJar(cookie)
but the request which is going from server is empty.
I moved further with my investigation and monitored HTTP traffic coming to server from Qt client and .NET client.
The HTTP Header for both SOAP requests are different:
This is Request coming from .NET client
POST /test/service1.asmx HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.3053)
VsDebuggerCausalityData: uIDPoyhZznNkbItPkJSR3EA+zEIAAAAAUkpe7URduE6nmhnT8f uQeqCQBMlX0zxCm65yW4ZPBkUACQAA
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://localhost/test/HelloWorld"
Host: localhost:8080
Cookie: MyAuthenCookie=DC7620DA79E080FECA37AC6866BF2690D57 B37443506F0D7EEA9DF209827360894D80D37E1B121D73EE44 766BDAEE16BA3FB0E8B95ADB1252AB00A76706930ACDC87CF9 F26744B7E9E3EB7FBB3812997
Content-Length: 291
Expect: 100-continue
and this is Request coming from Qt SOAP client:
POST /test/Service1.asmx HTTP/1.1
Content-Type: text/xml;charset=utf-8
SOAPAction: http://localhost/test/HelloWorld
Content-Length: 350
Cookie: MyAuthenCookie=9AFB2B22EE78D19DFD52BD2193A3D71627C F7303C15E4354E43CC2F31AECBDFFAD09176AA45F33B35C3C3 73891F1FE994580E8EE70FD4D01507670743138E74E152CFF4 EB3C37D90D3A7A0E272A804C3
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: Mozilla/5.0
Host: localhost:8080
Does any body have any idea what might be the problem and hoe to solve it?
How can I modify Headers for HTTP POST request in QtSoapHttpTransport object in order to make it identical to .NET request?
Thank you in advance,
Danny.
Are you running IIS or the ASP.NET Development server?
I was able to recreate a similar problem where everything worked fine using ASP.NET Development server but under IIS the session was null.
One thing to look for is when you invoke the session-enabled-service you should see the ASP.NET_SessionId being set in the response headers
Set-Cookie: ASP.NET_SessionId=5vxqwy45waoqma45lbbozj45; path=/; HttpOnly
Set-Cookie: MyAuthenCookie=510969D70201B358F8B0BBEEE7E79316B7ABCCC74312B0BD678DA4BE90E5C51CD6E7CDCA486DDB41BCBF489DB7280B3B979FD70B78D7F63B03C33431ADDAFDCA; expires=Mon, 07-Dec-2009 06:41:04 GMT; path=/; HttpOnly
To get sessions working under IIS, I had to add the following to web.config under system.web:
<sessionState mode="InProc" cookieless="false" timeout="20" />
<httpModules>
<add name="Session" type="System.Web.SessionState.SessionStateModule"
</httpModules>
This was under Windows 2003.