Invalid hostname on mvc site - IIS 8 - asp.net-mvc

I have an mvc app that has been deployed to our production server. It works well under IIS 8.5 using an IP and an asigned port. But the moment I try to bind it to a subdomain the app starts showing the invalid hostname error.
Tried to see if there was something off in the applicationhost.config but the binding is in the correct format. IP:Port:Binding.
The redirection also works fine, it lands on the page, but it shows the error instead of the login page.
I have deployed sites before, but not MVC apps, and bind them to subdomains and its usually a 2 step process. I dont know what im missing here.
Edit. Here is the screen of the error. Does not say a lot.

I'm not familiar with MVC or IIS, but base on my experience with other products, you very likely need to tell IIS to preserve the Host header.
Eg. https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers
In order to be able to modify the HTTP Location header it is necessary to preserve the original value of the HTTP host header. The outbound rewrite rule will use the preserved value when modifying the response. To preserve the original value you will store it in a temporary server variable ORIGINAL_HOST.
You should also make yourself aware about the security vulnerabilities that can result with regard to Host headers. https://techcommunity.microsoft.com/t5/iis-support-blog/host-header-vulnerability/ba-p/1031958

Related

Traefik Path Based Routing

I have two backends I want to serve from one Host. One from host.domain.com and the other from host.domain.com/path. The first frontend rule is straightforward: Host:host.domain.com.
The second is giving me some trouble. Based on the documentation I believe I should be using Host:host.domain.com;PathPrefixStrip:/path. This returns a 200 on host.domain.com/path, but when I click the link to somepage.html, it sends me to host.domain.com/somepage.html, so it returns a 404. If I go directly to host.domain.com/path/somepage.html it returns a 200. The link to somepage.html behaves correctly when I go directly to host.domain.com/path/index.html.
Are my assumptions/interpretations of the documentation incorrect or is this not an issue with Traefik at all?
This isn't really specific to traefik, any virtual path based reverse proxy that doesn't rewrite the contents of the web page returned (and few do this) have problems when the contents of that web page have absolute paths. The web page needs to either know about the "/path" and modify all the links it gives you, or use relative links, without a leading "/". This should be fixed within your website, web application, or hopefully a configuration for a web application. Depending on the application, once reconfigured, you may need to adjust the traefik rule to just "PathPrefix" instead of "PathPrefixStrip".
You should use a PathPrefix instead a PathPrefixStrip . The Strip rules remove the path before presenting it to the backend.
Since the path is stripped prior to forwarding, your backend is expected to listen on /.

Route 53 - Special domain for a single page on existing server

I have a complex web app at example-app.com, hosting fully on AWS using ELB and Route 53 for DNS. It's a Rails app.
I'm running an experiment that I'm using in the rails app, at example-app.com/test. I want to set up new-domain-app.com, to point at example-app.com/test, and have the URL cloacked to always be new-domain-app.com. It's a single page site, so it shouldn't require any navigation.
I'm having a lot of trouble figuring out how to set up my DNS on Route 53 to accomplish this. Does anyone have good ideas on what this Route 53 configuration should look like?
AWS offers a very simple way to implement this -- with CloudFront. Forget about the fact that it's marketed as a CDN. It's also a reverse proxy that can prepend a fixed value onto the path, and send a different hostname to the back-end server than the one typed into the browser, which sounds like what you need.
Create a CloudFront web distribution.
Configure the new domain name as an alternate domain name for the distribution.
For the origin server, put your existing hostname.
For the origin path, put /test -- or whatever string you want prefixed onto the path sent by the browser.
Configure the cache behavior as needed -- enable forwarding of the query string or cookies if needed and any headers your app wants to see, but not Host.
Point your new domain name at CloudFront... But before you do that, note that your CloudFront distribution has a dxxxexample.cloudfront.net hostname. After the distribution finishes setting up (the "In Progress" status goes away, usually in 5 to 20 minutes) your site should be accessible at the cloudfront.net hostname.
How this works: When you type http://example.com into the browser, CloudFront will add the origin path onto the path the browser sends, so GET / HTTP/1.1 becomes GET /test/ HTTP/1.1. This configuration just prefixes every request's path with the string you specified as the origin path, and sends it on to the server. The browser address bar does not change, because this is not a redirect. The host header sent by the browser is replaced with the hostname of the origin server when the request is sent to the origin.
What you are trying to do is not possible. Route53 is a DNS system, and you can not configure a hostname (e.g. new-domain-app.com) to point to URL (e.g. http://example-app.com/test) using DNS.
However, you are probably using a wrong tool for the job. If example-app.com/test is indeed a simple, static, single page site, then you do not need to host it inside Rails app. Instead, you can host it on AWS S3 bucket, and then you can point new-domain-app.com to that bucket using Route53.
See the following for details:
http://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html
http://docs.aws.amazon.com/Route53/latest/DeveloperGuide/RoutingToS3Bucket.html
DNS knows about Domains, not url's. DNS simply converts names to IP addresses.
You can't do what you are asking for just using DNS and ELB, however, what you can do is have a seperate VHOST for new-domain-app.com that points to your example-app.com site and accomplishes what you want using some sort of redirection rule that only fires for new-domain-app.com.
I'm not sure that this qualifies as an SO question, and more likely is a serverfault question. Specifics about your webserver and OS platform would be helpful in getting more specific advice.
So here's some details:
You already have example-app.com setup and working
You create a CNAME entry pointing new-domain-app.com to example-app.com or you can make an A record pointing to the same IP. If you already have example-app.com pointing to a different IP address, then use a subdomain (test.example-app.com) to isolate it.
Setup a new vhost on your server that basically duplicates the existing vhost for new-domain-app.com. The only thing you need to change is the server name configuration.
Why does this work? Because HTTP 1.1 included the HOST header that browsers send along, and web servers use in vhosting to determine which virtual host to route an incoming request to. When it sees that the client browser wanted "example-app.com" it routes the request to the appropriate vhost.
Rather than having to do some fancy proxying, which certainly can be used to get to a similar result, you can just add a redirection rule that looks for requests for the host example-app.com and redirects those to example-app.com. In apache that uses mod_rewrite which people often utilize by putting rules in the ubiquitous .htacess file, but can also be done in nginx and other common web servers. The specifics are slightly different for each.

Incorrect port in Request.URL with Azure Compute emulator

I am using VS 2013. IIS 8.0 Express and Azure .NET SDK v2.2
With a simple WebAPI template project I am able to repro this. When I locally debug the project in the azure compute emulator, it starts up the web page in https://127.0.0.1. However, in the request, the URI comes up with port 444.
Is there any known fix / workaround for this bug?
I could find similar issues for others at following pages but their workarounds don't work for me. Nothing in Request object or Request.RequestContext.HttpContext.Request object has the right URL. For e.g. if I try to open https://127.0.0.1:444/, I get "page not found" error.
Wrong port number in mvc 4 windows Azure Request.Url
Request.Url has wrong port information
Thanks!
After reading through this, I think this might be by design. The request is associated with DIP rather than VIP since it is just been forwarded from the Load balancer.
However, this would still mean that I need to keep 443 unused for my service to function normally. My service redirect users to live login page and it has to provide the VIP domainname port as redirect url in order to get the request.
During local debugging, requests to url:port provided in Request.Url doesn't work. Overall this azure local debugging setup still looks like a mess.
Let me know if there is any other workaround/fix.

Mvc 4 Proxy Server/Controller

I am trying to implement the Jonathon Kresner
"Asp .net Mvc 4 Proxy Server/Controller (For help with Cross Domain Request)" https://gist.github.com/jkresner/3982746 .
Could anyone indicate how to call it from jquery please?
the coffescript call with the article gist.github.com/jkresner, leaves me perplexed.
The coffeescript basicaly says that for clients who can't connect to the remote url by themselves, swap out the specified remote URL reference (i.e. http://api.othersite.com/Widget/7 ) with a reference to http://myoriginalpagehost.com/proxy and let the server side proxy the content from the http://myoriginalpagehost.com/proxy URI over to the http://api.othersite.com/Widget/7 URL.
One thing to note on that proxy is that it appears that cache control mechanisms will likely be subverted causing a potentially significant system load. Something to think about before boilerplate copy / paste of someones code. :-/
This article discusses another solution to the proxy issue that makes use of IIS's URL rewriting mechanisms. No coding, just configuring.

Switching between http and https for images located on a sub-domain

My ASP.NET MVC3 site, www.mysite.com, pulls images from images.mysite.com. When I'm not logged into my site and using SSL, it works flawlessly. However, when logged in, it get the
Only secure content is displayed.
message in IE9. I understand that. What's the best way to deal with switching URL's for my images? Should I check to see if I'm currently using SSL and point my images to https://images.mysite.com, otherwise http://images.mysite.com?
EDIT: This is an e-commerce site, so most of the time the site is browsed unsecured. But after login, I still need to pull some of those same images, and of course if they browse back to a regular catalog page, it would need to access images. Perhaps I will just have to always use https://images.mysite.com. Just seemed like overkill.
I believe the problem only happens when you're in a secure page accessing content over http. So, for pages that can be seen both in http or https, might be as easy as always using https to get the images, regardless if you're in http or https.
You will always get that message if you are pulling content from a non-SSL site when viewing over SSL. If you site is mostly SSL protected, just always pull images from https://images.mysite.com as you do not get the error if you pull SSL content into a non-SSL site.
Otherwise, you will need to know which pages are only viewable over SSL and which ones are not, and link appropriately.
Lastly, if you site is available over both, you will probably need to look at the HTTPS server variable to determine if you are on SSL or not and use this to determine your link (http or https).
Did you try prefixing with ~instead of ../ or /?
This worked for me.

Resources