In HTTPS request , Request.IsSecureConnection return false - c#

I have an asp.net application working in https (SSL). This is working well in my local computer and Amazon AWS(production environment).
But when I host this application in office (for testing) some strange things happens.
I can see the https in browser and the lock sign.
Fiddler also showing that the output is encrypted and shows port 443.
But HttpContext.Current.Request.IsSecureConnection returns false
And HttpContext.Current.Request.Url.Scheme returns http.
In the office we are using Juniper SSG firewall and TMG 2010 (Forefront Threat Management Gateway 2010). So server receive request through Juniper and TMG 2010. Thanks in advance.

To reduce costs I suspect that the SSL certificate is installed on the TMG Gateway and that this gateway is simply rewriting the request to standard HTTP when passing it to the actual web server. So by the time the request hits IIS and your web application it is a standard plain HTTP request.

This tripped my up after deploying to Amazon's Elastic Beanstalk environment. I couldn't see any way to get the load-balancer to allow the SSL request straight through to the server. Instead it was always terminating the SSL at the load-balancer and passing plain http back to the server.
I found this documentation: Elastic Load Balancing Concepts - X-Forwarded Headers.
Essentially the load-balancer injects a number of additional HTTP Headers into each request before forwarding it to the back-end server. The most relevant one is X-Forwarded-Proto which tracks the protocol used to connect from the client's browser to the load-balancer. This can be checked like so:
var loadbalancerReceivedSSLRequest = string.Equals(Request.Headers["X-Forwarded-Proto"], "https");
var serverReceivedSSLRequest = Request.IsSecureConnection;
if (loadbalancerReceivedSSLRequest || serverReceivedSSLRequest)
{
// SSL in use.
}
else
{
// SSL not in use.
}

Well another way to check is to check the port
if(context.Request.Url.Port == 443)
Note: check which port is used for secure connections, usually it is 443

Related

Connect directly to Kestrel behind IIS

I have a web app made in C# using asp.net core 2.0.
This app is hosted in IIS, as this is the recommended way to expose it to the internet.
I am now making some services hosted in the same local lan as the webapp, which need to connect to the above webappp. I can connect to the public iis server which of course works. However, would it also be possible to directly connect to the Kestrel server managed by IIS? So instead of connecting to public_ip/somewhere, connect to kestrel-local-ip:port/somewhere. The advantages would be:
avoid an extra hop
the kestrel app is still hosted and managed by IIS, so no worrying about self-hosting/management.
Reading the documentation here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/aspnet-core-module?view=aspnetcore-2.1 it states: "Additional checks are performed, and requests that don't originate from the module are rejected.". Reading the Github repro, this seems to be an HTTP header called "MS-ASPNETCORE-TOKEN".
So is this scenario possible somehow? To connect directly to IIS but ALSO to kestrel directly?
If it is possible, should I do this? The performance gains seem immense as I have a lot of small requests which Kestrel can handle really well.
I have test this scenario。
when APP kestrel behind iis,
you can use netstat command get the kestrel process "port".
and then curl the "localhost:port" , you will get the 400 bad request, also you can get a error log indicate the MS-ASPNETCORE-TOKEN token .
you can curl the "localhost:port"again with the MS-ASPNETCORE-TOKEN request header.

Xsockets.NET over proxy server

I have written a winforms client, that connects to a Windows service establishing a connection with XSockets.Net. This is working fine for a direct connection to the internet.
But when there is a proxy server, it will fail.
As I checked the XSockets API I have not found any settings, that allows me to use a proxy server.
Also for the websockets protocol I have not found a sufficient answer.
Any ideas?
Use WSS:// for connection, that is the equivalent to HTTPS in WebSocket.
The WebSocket protocol handshake sends the HTTP headers "Upgrade:websocket" and "Connection:Upgrade", meaning that the proxy will probably remove the "Upgrade" header because is set as a "Connection" header. By using a secure protocol, the proxy won't be able of intercept the request and will just let it pass.
Cheers.

How to distinguish http and https by http-header

I am writing a proxy with TcpListener in C#.
This proxy listens a port that users send request to. And when accepted a user request, it will parse the request header and find the host name. Then it creates a TcpClient to the host server.
Here comes the problem. When http request comes, it should connect the port 80 of the server; while https request comes, it should connect the port 443 of the server. But I have no idea of how to distinguish http request and https request.
Question in one sentence: how to know it is a http request or https request that TcpListener accepted?
Many thanks!
You've stepped in a problem that has flustered web server administrators for a long time.
Here's the process:
Web browser establishes a TCP connection to a particular IP on the web server.
The web server knows what IP it's getting a connection from, knows that that IP is only ever used for secure.example.com, and so loads the SSL certificate for secure.example.com.
The web server and web browser negotiate a SSL connection.
The web browser sends vanilla HTTP headers down the SSL pipe, which include the "HOST: secure.example.com" line that indicates the virtual host to use.
The web server processes the request and sends the response using vanilla HTTP headers sent down the SSL pipe.
The web server has to decide which virtual host to use before it has any HTTP headers. This is because it has to negotiate an SSL connection first, and it has to know which certificate to use first. The vanilla solution is to use IP-based virtual hosts - run the web server on IP address X; whenever the server gets a request sent to address X, it knows the request belongs to the configured vhost for that address.
The problem with that scheme is that the server has to have separate IP addresses for each secure website it runs. That might be many, many IP addresses, and is either costly or impractical.
Step in Server Name Indication. When the web browser is negotiating the SSL connection to the web server, the web browser includes the hostname it wants to connect to in the SSL negotiation information. Now the web server can use that information to do normal name-based virtual hosts, and so the web server can run a thousand different secure websites each with their own SSL certificates all on exactly one IP address. Everything is right in the world again.
You want to get in the middle of this, which means that you have to understand the SSL/TLS negotiation phase, parse the server name information, and forward the request down to the right web server.
Your new flow looks something like this:
Web browser establishes a TCP connection to the proxy.
Proxy begins recording the SSL exchange.
Web browser starts to do SSL negotiation, and as part of such, sends the Server Name Information down.
The proxy parses the Server Name Information, decides which web server should handle the request, and forwards the SSL negotiation information to the web server.
The proxy does not otherwise participate in the negotiation; it reads the SNI, but otherwise is completely "pass-through".
The web browser and server complete the SSL negotiation, the server picks the right vhost, and the browser sends vanilla http headers for a request.
The web server reads the vanilla headers via the SSL connection, and processes the request.
Now that that's been said, you might realize that sticking your nose in the SSL connection negotiation might be more trouble than it's worth. Turns out a few other people have already had the same idea as you and have implemented a few programs that seem to do exactly what you're trying to do - do a search for "http sni proxy" - I came up with this: https://github.com/dlundquist/sniproxy
The headers are entirely encrypted. The only information going over the network 'in the clear' is related to the SSL setup and D/H key exchange. This exchange is carefully designed not to yield any useful information to eavesdroppers, and once it has taken place, all data is encrypted.
Update By the way After the SSL negotiation, normal HTTP headers will travel inside the encrypted stream, so there is really no difference between the two.

Is it possible to use Fiddler to debug Http traffic issue?

I am using ASP.Net + .Net 3.5 + VS 2008 + IIS 7.0 + C# to develop a web application. I want to use Fiddler to debug (i.e. monitor request and response Http traffic) local traffic -- i.e. when I test web application inside VSTS 2008's built-in test ASP.Net web server. Is that feasible? If yes, how to monitor such traffic? For example, in VSTS 2008's built-in ASP.Net test web application server, the Url I want to monitor request traffic sent to http://localhost:1870/Default.aspx and its response (i.e. when F5 is pressed in VSTS 2008).
BTW: I previously think Fiddler could only be used to monitor port 80 Http traffic, not sure whether port 1870 could be monitored?
Have you tried adding a dot after the localhost? Quick test on my machine seems to indicate this is needed in IE but might not be in Firefox actually.
If you change your URL to 'http://ipv4.fiddler:1870/..' instead of 'http://localhost:1870/...' then fiddler will intercept your traffic and display the requests. Localhost doesn't go through wininet (I believe) which fiddler will then ignore. Fiddler registers ipv4.fiddler as localhost so you can monitor local traffic.
You can also add an entry to your hosts file and direct some URL (e.g. mysite.com 127.0.0.1) and use it as your URL (e.g. http://mysite.com:1870/...) and fiddler will pick that up, too.
Doesn't fiddler ignore 'Localhost' try changing the url's to your machines hostname.

How can I configure Cassini web server to accept requests to different hosts?

See duplicate: Customizing the cassini webserver
I have a web service hosted using Cassini web server. It works fine if I reference it by localhost, but when I use my machine's name (even using the browser locally), I get:
Server Error in '/' Application.
HTTP Error 403 - Forbidden.
Version Information: Cassini Web Server 1.0.40305.0
How can I configure it to accept all requests?
Cassini is specifically build to reject any outside connections. You could rebuild from sourcecode if you want it to accept outside connections.
Edit:
In reply to the below comment on what to edit in the sourcecode, you'd probably want to change the following in Server.cs on line 88:
_socket = CreateSocketBindAndListen(AddressFamily.InterNetwork,
IPAddress.Loopback, _port);
Into something like this:
_socket = CreateSocketBindAndListen(AddressFamily.InterNetwork,
IPAddress.Any, _port);
This will bind the listening socket to all available IP addresses on the system instead of only to the localhost address (127.0.0.1).
To update this answer, IIS Express is a new alternative that allows this.
http://weblogs.asp.net/scottgu/archive/2010/06/28/introducing-iis-express.aspx
To avoid anyone else having to go further, if you need a lightweight web server for production use, IIS-Express is not recommended (by themselves) for that purpose .

Categories

Resources