IIS7 URL Rewrite to router webadmin from child of default website - iis

The Mission:
To access my home router's web admin site through my main website on my home server via IIS URL Rewrite/ARR. So instead of typing in http://192.168../index.cgi to get to my router, I can go to my home site http://example.com/index.html and then click on a link to go to http://example.com/router1/index.cgi.
The Journey
So far I have been able to redirect and rewrite in a number of ways. However, success only comes when I don't use a "sub-folder" in the URL. I have found that this is due to the router's website utilizing root relative links. I have tried with little success to write some outbound rules to get around this. When I use a little regex to strip that first forward slash like this
(replaces equals sign, double or single quotation mark, and a forward slash with equals and quote)
<outboundRules>
<rule name="gallifrey-out" preCondition="IsHTML">
<match filterByTags="None" customTags="" pattern="=(\"|\')\/" />
<action type="Rewrite" value="={R:1}" />
</rule>
<preConditions>
<remove name="IsHTML" />
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
all the images appear correctly, but the links to pages are still missing the "router1" subfolder portion and therefore throw a 404 (not found) error.
I had read somewhere that the base tag would solve this. Seeing how there was no base tag for URL Rewrite to find and rewrite, I tried injecting it into the page via the style tag like so
<outboundRules>
<rule name="gallifrey-out" preCondition="IsHTML" stopProcessing="true">
<match filterByTags="CustomTags" customTags="baseInject" pattern="(.*)" />
<action type="Rewrite" value="text/css"></style><base href="http://example.com/router1/images"><style type="text/css" />
</rule>
<preConditions>
<remove name="IsHTML" />
<preCondition name="IsHTML">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
</preConditions>
<customTags>
<tags name="baseInject">
<tag name="style" attribute="type" />
</tags>
</customTags>
</outboundRules>
Sadly this didn't work either, like .... not at all. It did inject though, here's a look at the source
Source code screenshot
Over the past few days I have looked at a ton of sites and videos on how to accomplish this. And while I have learned a lot in the process, I still can't get this done. Everyone else seem to have different way to go about it. Eventually I will go live with this on the main server and will need access to it outside my home which means the way the page is rendered to the client needs to be route-able from the public network.
Test Bench:
An extremely old Sony VIAO laptop running Win7 Ultimate with IIS7
ActionTec MI424WR rev i with Verizon/Frontier firmware
The Don't Wannas:
Don't want to open yet another port to the public on the router
Don't want to purchase yet another domain name
Don't want to purchase a wildcard SSL cert (only a single)
The Big Question
Does anyone have any idea on how to work around root-relative hyperlinks when redirecting with url rewrite?

Related

IIS 10 - ULR Rewrite rule for stopping Image Hotlinking - when working also affects the domain host itself

Windows 2016 Server running IIS 10 with the URL Rewrite Module installed.
The servers are set up in a server Farm.
I've been messing around with this for the last 48 hours and cannot, for the life of me, figure out why it is not working as it is supposed to work.
I've looked at a video showing how to set it up and how it works, and I've mimicked what was done in the video, and nothing, still cannot get it to work.
This is what happens.
Using this code below will work; as you notice, it has the pattern="Pattern: "
However, the leading site that hosts the images has its images replaced with the stop-hotlinking.png image as well.
So, in theory, it works, but the hosting site has no access to its images to display.
If I remove (pattern="Pattern: "), it does not work.
To sum it up.
The below code will display the "stop-hotlinking.png" image on all outside sites, as well as the hosting site.
<rewrite>
<rules>
<rule name="STOP-Hot-Linking" enabled="true" stopProcessing="true">
<match url=".*\.(gif|jpg|png)$" />
<conditions>
<add input="{HTTP_REFERER}" pattern="Pattern: ^$" negate="true"/>
<add input="{HTTP_REFERER}" pattern="Pattern: ^https?://(www\.)?domain\.com/.*$" negate="true"/>
</conditions>
<action type="Rewrite" url="/graph/stop-hotlinking.png" />
</rule>
</rules>
</rewrite>
I even tried it with the pattern as this, and it will display the stop-hotlinking.png on all sites including the hosting site.
<add input="{HTTP_REFERER}" pattern="^http://(.*\.)?domain\.com/.*$" negate="true"/>
Below is the sample you could refer:
let's say I have 2 sites in my iis server and I would like to set a rule in the test site to not allow other domain sites to use images so I will set a URL rewrite rule in the test site.
test site index page contact:
<html>
<head>
<title>test.com title page</title>
</head>
<body>
<h2>test.com</h2>
<img src="http://test.com/img.jpg">
</html>
now i am trying to access image from the test site to the test2 site:
below is the rule i have set in my test site:
<rule name="Prevent Image Hotlinking" enabled="true" stopProcessing="true">
<match url=".*\.(jpg|jpeg|png|gif|bmp)$" />
<conditions>
<add input="{HTTP_REFERER}" pattern="^$" negate="true" />
<add input="{HTTP_REFERER}" pattern="^http://test.com/.*$" negate="true" />
</conditions>
<action type="Rewrite" url="/hotlink.jpg" logRewrittenUrl="true" />
</rule>
Note: hard refresh your page in bwroser if it does not work or you could try to open page in private mode.
I was assisted on another forum, and this was the issue.
I was testing the same image on multiple domains we own.
And that was the biggest problem, was the image would get cached, even when Google Tools was open, it would still cache it for whatever reason, we never could figure it out.
I changed to another image from the hosting site, and it started working.
We also found out that Google Chrome needed a referral meta tag in the head of the hosting sites page.
<meta name="referrer" content="origin">
Once all the above was taken care of and the following code in place. It started working.
<rule name="Prevent Image Hotlinking" enabled="true" stopProcessing="true">
<match url=".*\.(jpg|jpeg|png|gif|bmp)$" />
<conditions>
<add input="{HTTP_REFERER}" pattern="^https?://(www\.)?(?:DomainOne\.com|DomainTwo\.com|DomainThree\.com)/.*$" negate="true"/>
</conditions>
<action type="Rewrite" url="/graph/stop-hotlinking.png" logRewrittenUrl="true" />
</rule>
In the above, you will see there are multiple domains, this is to allow images to be hosted on their domains, and all other domains will get the STOP image.
This is completed.
I want to think Jalpa for trying to assist.
And gr8gonzo from the other forum for helping me out in this long venture.

IIS URLrewrite: How to preserve original host name for internal redirects?

I have a web application running on one server and use IIS with rewriteURL on another server as a reverse proxy.
I configured the incoming rules to rewrite the reverse proxy address with the address of the web application server. This works fine.
However, the application allows users to download some content and redirects them to the download address. Right now, users get forwarded to the local IP address of the web application server, not the public address of the reverse proxy.
I understand, I need to edit the outbounding rules as well to catch this, but I somehow don't get it right.
I followed the instructions here
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/modifying-http-response-headers
and my current rewrite rules look like this
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="er-platform" stopProcessing="true">
<match url="^er-platform(.*)" />
<conditions>
<add input="{CACHE_URL}" pattern="^(https?)://" />
</conditions>
<action type="Rewrite" url="{C:1}://192.168.80.6:8443/{R:0}" />
<serverVariables>
<set name="ORIGINAL_HOST" value="{HTTP_HOST}" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="er-platform" preCondition="IsRedirection" enabled="true">
<match serverVariable="RESPONSE_LOCATION" pattern="^(https?)://[^/]+/(.*)" />
<conditions logicalGrouping="MatchAny">
<add input="{ORIGINAL_HOST}" pattern=".+" />
</conditions>
<action type="Rewrite" value="{R:1}://{ORIGINAL_HOST}/{R:2}" />
</rule>
<preConditions>
<preCondition name="IsRedirection">
<add input="{RESPONSE_STATUS}" pattern="3\d\d" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
I still get redirected to the local IP when trying to download something.
How do I need to change the rules to get this right?
Thanks,
Thomas
I don't think your outbound rule is incorrect. I have a couple of guesses for why it is failing.
First: Your inbound rule must match for your outbound rule to work. This is because ORIGINAL_HOST is captured when the inbound rule executes. Right now, your inbound rule is match the URL against ^er-platform(.*). I am going to assume that since this is a reverse proxy, that it is working because you wouldn't be able to start the download if it wasn't.
Second: The output rule only triggers on a 3xx code. This isn't the only way to redirect though. It's possible that you're redirecting using JavaScript. E.g. `window.location = 'http://wrongaddress'. In which case your outbound rule wouldn't work.
Next steps for debugging this:
Turn on Logging for the inbound rule.
Your logs will be written to %SystemDrive%\inetpub\logs\LogFiles\. Verify the inbound rule is being hit.
Verify what's happening on the wire:
Fiddler is a great tool for understanding what's actually happening on the wire. Use this to confirm that the URL rewrite rules should be hitting. I.e. that the request URL matches ^er-platform(.*) and that the response code is in the 300s.
Alternatively to Fiddler you could just get away with using Chrome Developer Tools Network tab. Turn on the 'Preserve log' checkbox so that it doesn't clear after you've been redirected. Verify what you think should be happening is actually happening.

Return 410 Error Based on Part of Query String in ASP.NET MVC

Looking for a method we can use in our ASP.NET MVC-5 IIS-8 site to return a 410 error response (gone) based on a list of phrases contained in the querystrings.
Why? We're receiving a few hundred daily junk hits from reputable bots (e.g., Google, Bing, Yahoo) for ridiculously named pages that we've never had on our site. I'm thinking that for most of these pages I can test if a given key-phrase exists and, if it does, return the 410. I'd like to return the 410 to tell the bots they can remove their listing permanently thereby providing a gradually improved SEO environment.
Here's a few examples of URL's we're receiving with the key-phrase I would test for in bold.
https://www.example.com:443/apple-touch-icon-precomposed.png
http://ww.w.example.com:80/zdjqhhmtkatt.html
I know this is very do-able with .htaccess in other programming environments so I'm hoping there's also an elegant solution for ASP.MVC.
You can do that with URL rewrite module. The rule in your web.config should be like that:
<rewrite>
<rules>
<rule name="410response" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAny">
<add input="{REQUEST_URI}" pattern="apple-touch" />
<add input="{REQUEST_URI}" pattern="zdjqhhmtkatt" />
</conditions>
<action type="CustomResponse" statusCode="410" statusReason="System unavailable" statusDescription="Gone. The requested resource is no longer available." />
</rule>
</rules>
</rewrite>

Redirect visitors to the canonical URL for a page using IIS

I want to ensure that anybody who goes to http://example.com/* gets automatically redirected to http://www.example.com/*. Currently, IIS allows either URL form to work, meaning that any page can be accessed at multiple URLs, which has a number of disadvantages (SEO, etc).
Is there any way to do this built into IIS (especially IIS 6) without setting up a third-party rewriting engine like this? It seems like a bazooka to kill a mosquito.
The easy way would be to simply remove the DNS entries for 'www.mysite.com', so the only DNS entries that exist are for 'mysite.com'.
Alternatively, here's a couple of techiques for redirecting to a canonical URI:
http://www.kalyani.com/2010/01/redirecting-to-canonical-url-in-iis7/
https://web.archive.org/web/20211020203216/https://www.4guysfromrolla.com/articles/072810-1.aspx
http://www.stevenhargrove.com/redirect-web-pages/
Basically you want to hand back a 301 Moved Permanently status for the non-canonical URIs, along with the canonical URI so the user agent may load it instead.
I have another solution for you:
<rule name="Canonical domain name" enabled="true" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{HTTP_HOST}" negate="true" pattern="^www\.([.a-zA-Z0-9]+)$" />
</conditions>
<action type="Redirect" url="http://www.{HTTP_HOST}/{R:0}" appendQueryString="true" redirectType="Permanent" />
</rule>

How exactly do you configure httpOnly Cookies in ASP Classic?

I'm looking to implement httpOnly in my legacy ASP classic sites.
Anyone knows how to do it?
If you run your Classic ASP web pages on IIS 7/7.5, then you can use the IIS URL Rewrite module to write a rule to make your cookies HTTPOnly.
Paste the following into the section of your web.config:
<rewrite>
<outboundRules>
<rule name="Add HttpOnly" preCondition="No HttpOnly">
<match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
<action type="Rewrite" value="{R:0}; HttpOnly" />
<conditions>
</conditions>
</rule>
<preConditions>
<preCondition name="No HttpOnly">
<add input="{RESPONSE_Set_Cookie}" pattern="." />
<add input="{RESPONSE_Set_Cookie}" pattern="; HttpOnly" negate="true" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
See here for the details: http://forums.iis.net/t/1168473.aspx/1/10
For background, HTTPOnly cookies are required for PCI compliance reasons. The PCI standards folks (for credit card security) make you have HTTPOnly on your sessionID cookies at the very least in order to help prevent XSS attacks.
Also, at the current time (2-11-2013), all major browser support the HTTPOnly restriction on cookies. This includes current versions of IE, Firefox, Chrome and Safari.
See here for more info on how this works and support by various browser versions:
https://www.owasp.org/index.php/HTTPOnly
Response.AddHeader "Set-Cookie", "mycookie=yo; HttpOnly"
Other options like expires, path and secure can be also added in this way. I don't know of any magical way to change your whole cookies collection, but I could be wrong about that.
You need to append ";HttpOnly" to the Response cookies collection.
Response.AddHeader "Set-Cookie", ""&CStr(Request.ServerVariables("HTTP_COOKIE"))&";path=/;HttpOnly"&""
If you are using IIS7 or IIS7.5 and install the URL Rewriting add-in then you can do this. You can create a rewriting rule that adds "HttpOnly" to any out going "Set-Cookie" headers. Paste the following into the <system.webServer> section of your web.config. I then used Fiddler to prove the output.
Regards, Jeremy
<rewrite>
<outboundRules>
<rule name="Add HttpOnly" preCondition="No HttpOnly">
<match serverVariable="RESPONSE_Set_Cookie" pattern=".*" negate="false" />
<action type="Rewrite" value="{R:0}; HttpOnly" />
<conditions>
</conditions>
</rule>
<preConditions>
<preCondition name="No HttpOnly">
<add input="{RESPONSE_Set_Cookie}" pattern="." />
<add input="{RESPONSE_Set_Cookie}" pattern="; HttpOnly" negate="true" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
HttpOnly does very little to improve the security of web applications. For one thing, it only works in IE (Firefox "supports" it, but still discloses cookies to Javascript in some situations). For another thing, it only prevents a "drive-by" attack against your application; it does nothing to keep a cross-site scripting attack from resetting passwords, changing email addresses, or placing orders.
Should you use it? Sure. It's not going to hurt you. But there are 10 things you should be sure you're doing before you start messing with HttpOnly.

Resources