Link to home
Start Free TrialLog in
Avatar of jcritzer
jcritzerFlag for United States of America

asked on

Binding IIS OUTGOING traffic

We have a web server sitting in a DMZ, running IIS.  The purpose of this server is to accept NAT'd traffic from our public IP and, based on the originating IP/vendor IP, route said traffic to one of three separate IPs on IIS to then be routed internally.  So, specifically speaking, on this DMZ box, we have a single vNic with 3 IPs bound to it - each IP is for a separate site within IIS.

For clarity's sake, let's say the IPs bound to this single vNic are:

10.1.1.1/24
10.1.1.2/24
10.1.1.3/24

Once the traffic hits IIS and is pushed forward, all OUTGOING traffic is being pushed forward via 10.1.1.1/24, resulting in something similar to this:

Vendor 1 --> 10.1.1.1/24 (Incoming) --> 10.1.1.1/24 (Outgoing) --> Server 1
Vendor 2 --> 10.1.1.2/24 (Incoming) --> 10.1.1.1/24 (Outgoing) --> Server 2
Vendor 3 --> 10.1.1.3/24 (Incoming) --> 10.1.1.1/24 (Outgoing) --> Server 3

To keep traffic separate for security measures, our desire is to configure IIS or the OS to forward traffic from the IP to which it was sent, rather than all traffic coming into our internal network from 10.1.1.1/24.

Something like:

Vendor 1 --> 10.1.1.1/24 (Incoming) --> 10.1.1.1/24 (Outgoing) --> Server 1
Vendor 2 --> 10.1.1.2/24 (Incoming) --> 10.1.1.2/24 (Outgoing) --> Server 2
Vendor 3 --> 10.1.1.3/24 (Incoming) --> 10.1.1.3/24 (Outgoing) --> Server 3

How would you go about configuring this setup on the DMZ server using either IIS or the OS?
Avatar of Systech Admin
Systech Admin
Flag of India image

you can do it via running the below command to use all IPs as Outbound IPs

Netsh int ipv4 add address <Interface Name> <ip address> skipassource=false
Avatar of jcritzer

ASKER

It says the object already exists when running that command for any of the alternate IPs.

Also, when specifying a source for ping (e.g. ping -s 3 x.x.x.x), no matter the interface number, 1-4, it resolves to the base IP for the vNic.

I'm told Server will always default to the lowest IP available on the NIC for outgoing traffic.  I'm simply thinking there has to be a way around this.  The problem seems to be having 3 IPs on a single interface, all operating on the same subnet.
You should be binding the individual websites to a specific IP in IIS.  If you are using the * default configuration, then IIS can use what ever IP it wants to service incoming requests.

So:

Site1 is directly bound to 10.1.1.1
Site2 is directly bound to 10.1.1.2
Site3 is directly bound to 10.1.1.3

Dan
ASKER CERTIFIED SOLUTION
Avatar of jcritzer
jcritzer
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
So, just to clarify... binding a specific website to a specific IP will force the website to use the IP address configured in IIS Manager in the site bindings.

So, if you bind site01 to IP 10.1.1.1, it will respond on 10.1.1.1.  If a second site, site02, is bound to a 2nd IP on the same server, 10.1.1.2... then http(s) requests sent to site02 will respond from IP 10.1.1.2.

You can confirm this with any developer tools in either IE, FF or Chrome.

See attached images...

Isn't this what you were describing?

Dan
IIS8.5-sites-multiple-ips.JPG
IIS8.5-Site-Bindings.JPG
IIS8.5-site01.JPG
IIS8.5-site02.JPG
In short, yes and no.  I wasn't very clear this morning due to time constraints at the time.  Sorry.

This is the way it played out for us.  If there's an easier way to do it, I'm all ears because I'm sure we'll have more pass-through traffic being stood up on this box.

In my original post, I described our issue in which a single vNic - in this case "Microsoft Hyper-V Network Adapter," was bound to three IPs: the interface IP along with two alternate IP bindings on the vNIC.  These IPs can be referred to as:

10.1.1.1 (primary), 10.1.1.2 (alt), 10.1.1.3 (alt)

Doing a route print at this point - with three IPs bound to a single vNic - you'll find that there is a single interface number associated with this vNic in the Interface List, not three interface numbers associated with the individual IPs, and also that in the IPv4 Route Table the interface IP for all three IP bindings is the same - the primary IP.

So, for argument's sake, let's say the interface list shows:
13... xx xx xx xx xx xx ......Microsoft Hyper-V Network Adapter (where 13 is the interface number and xx is the MAC)

For incoming traffic, this is fine because IIS will push the traffic to its destination predicated upon the address in the packet header.

However, at this point in time, outgoing traffic is still all being routed directly to interface 13, which is configured by default to use the primary interface for all outgoing traffic since the three IPs are all on the same vNic.

After diagramming it, the only way which we found to circumvent the routing issue was to disassociate the two alternate IPs and assign them to new vNics to provide individual interface numbers through which we could route outgoing traffic.

Once the new vNics were created we could then do a route print and see the following in the interface list:
13... xx xx xx xx xx xx ......Microsoft Hyper-V Network Adapter
14... xx xx xx xx xx xx ......Microsoft Hyper-V Network Adapter #2
15... xx xx xx xx xx xx ......Microsoft Hyper-V Network Adapter #3

Once the interfaces were separated out, we then did the following to push traffic, via the appropriate interface to the desired destination:
route add 172.1.1.1 mask 255.255.255.255 172.1.1.50 if 13
route add 172.1.1.2 mask 255.255.255.255 172.1.1.50 if 14
route add 172.1.1.3 mask 255.255.255.255 172.1.1.50 if 15

So the problem seemed to be the fact we had three IPs associated with a single vNic and Windows didn't know how to differentiate outgoing traffic because there was only one interface to route traffic through in the table.
OK, so I understand the issue.  I'm still of the opinion that this is a configuration issue in possibly several areas.

How are the websites in IIS configured?  Are the individual sites bound to a dedicated IP or are they default configured?  Meaning are they using the "All Unassigned" option in the binding config.

Also, have you allowed the server to register the vNIC address in DNS?

Link to an article describing what sounds like your issue:

http://blogs.technet.com/b/heyscriptingguy/archive/2013/01/24/use-powershell-to-change-ip-behavior-with-skipassource.aspx

Can you post the output of this command:

Get-NetIPAddress | where AddressFamily -eq IPv4

Open in new window


Essentially, what appears to be your issue is, that all IP interfaces are allowed to be a source when responding to inbound requests.  Meaning that with multiple IPs on a single NIC, there is no longer a primary IP.  You need to manually configure the primary IP.

When setting SkipAsSource, the IP address is only used when an application is specifically bound to use that IP.

If you do an NSLOOKUP on the server's name, I'll assume you get back a hostname with more than 1 IP associated.  A possible solution would be to reconfigure the IP stack without using the GUI. Instead using the netsh command referenced in the article.

Remove all IPs from the server and verify that there are no references in DNS to and of the IPs to be associated with the websites.

Add a 4 IPs to the server.  3 for the websites and 1 for management.

Allow the management IP to register its name in DNS.  Enable the SkipAsSource flag for the 3 IPs to be used for the websites.

Doing an NSLOOKUP should only result in the management IP being returned.

In DNS, manually add A records under appropriate hostnames and domains for the 3 website IPs.

No changes to the route table should be necessary.

My wireshark trace shows the websites responding on the IP that was used to hit the website.

Dan

PS:  I know you are closing the question, but the issue was bothering me and became a sort of challenge.  Hopefully this helps out.
No worries, I'm kind of curious if there is a better way to do this so I'll run with it; however, the box is currently running with live traffic so I can't do much in the form of testing at the moment.

"How are the websites in IIS configured?  Are the individual sites bound to a dedicated IP or are they default configured?  Meaning are they using the "All Unassigned" option in the binding config."

The sites are bound to individual IPs.

Also, have you allowed the server to register the vNIC address in DNS?  If you do an NSLOOKUP on the server's name, I'll assume you get back a hostname with more than 1 IP associated.  

This is a DMZ box and all internal traffic is IP-based.  DNS records for the public sites are held by a state organization and aren't presenting an issue since all incoming traffic from the web gets to IIS on the box.

Essentially, what appears to be your issue is, that all IP interfaces are allowed to be a source when responding to inbound requests.  Meaning that with multiple IPs on a single NIC, there is no longer a primary IP.  You need to manually configure the primary IP.

We played with the SKIPASSOURCE flag and ran into the following problem...  If we set the three site IPs to true then all outgoing traffic defaults back to the management IP, not the bound IP as set in IIS.  Not gonna lie, I didn't wireshark any sessions at the time but the Barracuda sure didn't like it.

I don't know IIS too well - whereas your profile indicates you're an IIS wizard so I'll defer to you on this - but wouldn't outbound communications be initiated by an App Pool and not a website?  Does the website binding automatically transfer to the App Pool associated with that site?  If so, what would explain outbound traffic not following the bound IP unless we add route statements?  Strong host model?  Lower numeric IP on individual interface is default?  Something else?
Questions...

1. what role does your Barracuda play in your web infrastructure?
---- Firewall, Load Balancer, Web Filter, Web Application Firewall...
2. what is meant by "but the Barracuda sure didn't like it" statement?
---- can you give specific errors or explain what occurred?

These are key questions/answers in the solution.

As for your other questions in your response...

The web site binding is held by IIS and its http.sys.  An AppPool is a process which acts as a container for executing actions based on in bound http(s) requests.  It isolates site and their code execution from each other and helps prevent a complete IIS meltdown if a website experiences a crash.  One AppPool crashing only kills other website that are using the same AppPool.  AppPool 1 crashing, does not affect AppPool 2 running in the same IIS Instance.

link:  https://technet.microsoft.com/en-us/library/cc735247(v=ws.10).aspx

Nice explanation of website -vs- AppPool:

link:  http://blogs.technet.com/b/chrad/archive/2010/01/24/understanding-iis-bindings-websites-virtual-directories-and-lastly-application-pools.aspx

A typical request has this path (simple summary):

1. client http get sent to IP 10.1.1.10
2. server at destination 10.1.1.10 receives request
3. if the IP is associated with IIS, then  http.sys services that request based on IIS cfg.
4. http.sys hands off http get to website bound to IP 10.1.1.10
5. website services http get... code execution is handed to/run in the configured AppPool
6. AppPool executes action, passes data back up to http.sys
7. IIS sends response to client

If there are load balancers in between the client and web server then depending on how the LBs are configured, the client (of the web server) can be either the LB or the device making the http request.

It would be interesting to understand what the Barracuda's objection to the traffic was.

Dan
I presented this issue to multiple forums and it doesn't appear to be something which can be addressed within IIS - outgoing traffic as opposed to incoming traffic that is.  Most comments in response to our problem addressed incoming traffic, which I mentioned multiple times is not what we were trying to route.

Why a B instead of an A?

Because the fix doesn't work within the application it should.  It's more of a workaround in my opinion.