• Welcome to Hurricane Electric's IPv6 Tunnel Broker Forums.

Choose a source IP for browser (or other app) to bind to...

Started by Ninho, July 04, 2010, 08:45:13 AM

Previous topic - Next topic

Ninho

Hi! Here's one that still eludes me : running Windows (2000) the browser (or other app) "chooses" to bind its sockets to the IP address of the tunnel end - or rather, methinks, the apps do not choose (a design defect IMHO) but the OS does choose for them. Anyway, is there a way for me as an end user to tell Windows and/or tell IE or Firefox or Chrome, etc, that I want them to use another IP v6 address - viz one that I assigned to the LAN adapter rather than the tunnel end ?

As above said, I'm here using MS's older IPv6 implementation on Windows 2000, which has "ipv6.exe" but no "netsh" for IPv6 configuration. I'm also interested in how-to do the above in newer MS OSes, and in Linuces as well...

Regards, etc!

--
Ninho

jimb

You can't really do this unless the application supports specifying the IP to use, which unfortunately many don't.

The way it works is if the application doesn't specify an IP to use in the socket structure, when you connect, the system chooses the closest interface to the destination to connect, and it uses that interface's IPv6 address.

There are ways of choosing which source IPv6 to use (ip addrlist, /etc/gai.conf, netsh's prefixpolicy), but that only seems to apply for picking a source address to use if an interface has multiple source addresses.

There might be some "unnatural acts" you could do if you wanted to force the issue, such as perhaps pointing the default route to a loopback, then using policy routing to re-point it to the tunnel or something (never tried anything like this, not sure if it'd work).  Or you could run your IPv6 router in a virtual machine.  Or perhaps do some shenanigans with the TUN or TAP virtual interfaces.  This is all just off the top of my head.  Windows?  No idea.

The virtual machine idea seems the simplest to me though.  Run virtualbox or whatever, and stick a minimal install of linux or BSD into a VM with a bridged interface, set up your IPv6 tunnel router in that VM, then on the same box, your host interface just gets an IPv6 out of the routed /64, default router pointing to the VM's routed /64 (which is of course on the same box).  Then traffic from your "real" box would use a routed /64 address instead of the tunnel interface.

Note of this really seems worth it to me though.  There's no harm in using the tunnel interface, unless for some reason you NEED your IPv6 to have a custom RDNS or something.  But most cases I can think of which would need that (email server, etc) have ways of specifying the IPv6 to use anyway.

Ninho

Quote from: jimb on July 04, 2010, 03:09:06 PM
You can't really do this unless the application supports specifying the IP to use, which unfortunately many don't.
(snipped....)


Thanks. App developpers don't seem to be too preoccupied either at the moment. Actually I filled a bug with bugzilla re. Firefox a fortnight or so ago, that was quickly dismissed as not-a-bug or won't-fix, I don't recall which :=(

I wouldn't be surprised if this attitude had to be revised some time in the future. There are reasons I can think of for wanting precise control of the source, plus probably a few ones I can't imagine right now. Of course the problem also exists, in principle, when using only IPv4, but then you generally don't have so many addresses to choose from...

Re; virtual machines, you're absolutely right, while running my windows in VMware under Linux it gets IPv6 addresses from the host so that the problem stated in O.P. does not happen.

Regarding prefix policy, does someone know if it can be altered on Windows 2000 (or XP pre-service pack) ?

--
Ninho

snarked

If you were using a unix-type OS, then the command to help the OS determine the address to use would be "ip addrlabel" (there's an RFC for it out there too - RFC 3484 Section 2.1 "Policy table").  However, I don't know of any equivalent for Windows.

jimb

Quote from: snarked on July 07, 2010, 01:30:47 PM
If you were using a unix-type OS, then the command to help the OS determine the address to use would be "ip addrlabel" (there's an RFC for it out there too - RFC 3484 Section 2.1 "Policy table").  However, I don't know of any equivalent for Windows.
Have you ever gotten this to work?  I played with it for a bit, even with multiple v6s on the same interface, and no matter what I did it would always choose whatever the latest address added to the interface and use that as a source.

Also, I vaguely remember reading that it only applied in the case where you're picking among several IP sources from a single interface.  If it chooses another interface, it will use an IP from that one, and it doesn't seem you can force it to use an IP from a different interface.

The windows equivalent is "netsh int ipv6 {add|delete|set} prefixpolicy".

snarked

RE: "ip addrlabel" - Yes, I have it working.  The following may work with the Windows version too.  I use Linux with kernels of the 2.6 series (currently .34.1).  The 2.4 kernel series generally does not have the feature (unless recently backported after 2.4.31).

Define the entire /64 with some "high" label.  As the default table comes with values 0-7 in use, I assign values in the 90's just to make certain its sufficiently high.  I also throw in a value for 2001:DB8::/32 for good measure (so it matches only itself).  Then, I add the specific addresses (/128 - and one per interface) that I want used for outbound sessions with a label value which ties with the label for "::/0".  Within the same label, the algorithm will still pick the longest matching prefix between source and destination.  I have two outbound addresses because I'm multihomed (an HE tunnel and a native IPv6 allocation where routing is unreliable (and currently down)).

You are correct that the subset of addresses assigned to the interface is selected first, before applying the above.  However, when an interface has multiple global IPv6 addresses, the above narrows the choices to one.

Applications which have selected an address on their own still get to use that address.  This only affects the choice of address where an application has specified the "unspecified" address, thus leaving the OS to decide.

jimb

Quote from: snarked on July 08, 2010, 01:35:07 PM
RE: "ip addrlabel" - Yes, I have it working.  The following may work with the Windows version too.  I use Linux with kernels of the 2.6 series (currently .34.1).  The 2.4 kernel series generally does not have the feature (unless recently backported after 2.4.31).

Define the entire /64 with some "high" label.  As the default table comes with values 0-7 in use, I assign values in the 90's just to make certain its sufficiently high.  I also throw in a value for 2001:DB8::/32 for good measure (so it matches only itself).  Then, I add the specific addresses (/128 - and one per interface) that I want used for outbound sessions with a label value which ties with the label for "::/0".  Within the same label, the algorithm will still pick the longest matching prefix between source and destination.  I have two outbound addresses because I'm multihomed (an HE tunnel and a native IPv6 allocation where routing is unreliable (and currently down)).
Ah!  I just got it to work.  When I was playing with it, I must have misunderstood the RFC on source address selection.  I was adding just the 128 which matched the address I wanted it to use to the table, and making sure the label value matched the label value for "::/0".  I remember trying a bunch of other things too and didn't get it to work.  The key was to add the /64 in there too with that high label value.  I'm still not sure why that's required though.  

I don't remember the details, but I sort of remember thinking that the address label table entry just had to have the longest match with the interface address one wanted to use, and the matching label value also had to match something with low label in the table, such as "1" which is used on "::/0".  Something like "the selected address will have the longest match with a table entry with the lowest label value" is how I thought it worked (vague memory). But I guess that's incorrect!

snarked

The reason for throwing the entire /64 in there is so that your preferred address and the others on your host TIE for the "longest match", and we need to break that tie.

If I have 2001::/16 addresses and try to reach a 2600::/16 address, the longest match is /6 to ALL of my addresses - so this means that ANY of my addresses may be used (without the feature) since they all equally match at the 6 MSBs.  Therefore, the OS will pick one at random.

jimb

Quote from: snarked on July 09, 2010, 02:13:03 AM
The reason for throwing the entire /64 in there is so that your preferred address and the others on your host TIE for the "longest match", and we need to break that tie.
Hrm.  I'll have to read over the RFC again.  I sort of remember the "tie breaking" stuff in the source address selection algorithm, but I think I thought it'd already match something in the list by default, and that having the /128 in there would break the tie.

QuoteIf I have 2001::/16 addresses and try to reach a 2600::/16 address, the longest match is /6 to ALL of my addresses - so this means that ANY of my addresses may be used (without the feature) since they all equally match at the 6 MSBs.  Therefore, the OS will pick one at random.
Hrm.  Although wouldn't the longest be /5 (0010 0|000 against 0010 0|110, | = match position)?  

Eh.  I think I'm confused and have to reread that RFC.  I thought the source address selection didn't have anything to do with the destination address, and instead matched the list of source addresses with the addrlabel table and compared label values, and whichever matched the lowest label value won.

Maybe that is right?  Is that why one puts the whole /64 in as a label 90?  So that all but your chosen /128 get a high label, and the chosen /128 gets a lower label than the rest of the addresses in the /64, and thus gets selected?  That makes sense to me.  But is it correct?  You need to "push" the whole /64 up to a label 90, otherwise maybe they all still match say, label 1 (by matching ::/0 or something) and tie?  Hrm.

Also, I've found in my experimentation that when one has multiple "active" IPv6s on an interface, Linux always seems to use the latest one added as source in the absence of an addrlabel match.  I suppose technically (RFC wise perhaps) it could choose an address at random, but in Linux at least the behavior seems to be the "latest" added IPv6.

snarked

QuoteAlthough wouldn't the longest be /5 (0010 0|000 against 0010 0|110, | = match position)?
OK, so I can't count, but you got the point. ::)

Ninho

Concerning address & interface selection, and just for the record,
that oldish document from NTT: <http://www.nttv6.net/dass/>

has confirmed what I suspected, Windows 2000 (prior to XP) doesn't have Policy Table.

Too bad, will survive anyway !



snarked


Ninho

Just for completeness, I'm reporting I've just found that the (client side of) the tunnel interface
does not need to be XXXX::2, but can be pretty anything but XXXX::1, which of course
is reserved server-side. The server doesn't care what the client address of the tunnel is as long as there is one !

This is a way to change the default source address used by browsers and other client software without using prefix policies.  FWIW

Also reported in a vaguely related thread in the Linux section