Skip to contentSkip to conversation

Need for a specific source address selection rule ? (not neccessarily netfilter)

DISCUSSION Xavier Roche 3 participants 14 messages Aug 29, 2010 – Sep 3, 2010

lore
Share & tools
lore
#0 lore raw

Hi folks,

Following a discussion on comp.os.linux.networking (1), I am wondering if a specific rule for source address selection would be a good idea or not. The rule might NOT be a netfilter rule at all (ie. the rule would be evaluated during source address selection, that is, before packet building), but probably with a similar approach. Please redirect the discussion to a more adapted list if this is off-topic if necessary.

With the future rise or IPv6 (even if it is a damn slow rise), servers will have the opportunity to have [easily] multiple IP addresses configured by default on each interface (ip -6 addr add ..), providing new features that were difficult to have with the scarce IPv4 resource:
* one outgoing IP per service (for example, a SMTP server would have its own address for the outgoing interface - and one unique reverse IP to the declared SMTP server address)
* one outgoing IP per user (for multi-user machines) ; with optional custom reverse ("smith.users.example.com")
* one outgoing IP for specific network blocks
etc ..

The first case can sometimes be partially solved using application-specific configuration (bind to a specific address) - however this is not desirable when you need to listen to all interfaces (ie. including IPv4-only or IPv6-only ones)

This can not be easily achieved currently ;
* iproute's rt_tables can be used to select a specific route, but some ugly NATing is still necessary to rewrite the source address (we do not want to do that and can not do that with ipv6 anyway) ; ie. this is generally too late as the packet has already been built (2)
* trapping bind/connect (3) for each service using some LD_PRELOAD magic is not very clean or easy to deploy

RFC 3484 (4) specifies the way source address is selected ; with the following order (5):

1. Prefer same address. (i.e. destination is local machine)
2. Prefer appropriate scope. (i.e. smallest scope shared with the destination)
3. Avoid deprecated addresses.
4. Prefer home addresses.
5. Prefer outgoing interface. (i.e. prefer an address on the interface we're sending out of)
6. Prefer matching label.
7. Prefer public addresses.
8. Use longest matching prefix.

However, [RFC 3484] "If the eight rules fail to choose a single address, some unspecified tie-breaker should be used". The current default, if I am not mistaken, is to select the last address added to "the" selected interface ; as the only remaining choice is to select addresses within a single interface. This seem to be the current "unspecified tie-breaker".

The code logic appears to be in net/ipv6/addrconf.c ; the IPV6_SADDR_RULE_PREFIX is the 8th rule, and is used in ipv6_get_saddr_eval()

[ip6_dst_lookup()/ip6_sk_dst_lookup()] => ip6_dst_lookup_tail() => ipv6_dev_get_saddr() => ipv6_get_saddr_eval() [ For an UDP packet, the udpv6_sendmsg() directly uses ip6_sk_dst_lookup() to get the source address ]

This "unspecified tie-breaker" could be a new rule ; maybe a new "netfilter" (or pre-netfilter) rule specific to each interface ; ie. when the source address is selected using the RFC 3484 specification, a 9th rule would select the source address within this interface. (such as "IPV6_SADDR_RULE_NETFILTER")

Any remark is welcome (including obvious solutions to the problem, which would be great)

Xavier.

(1) <news:[email protected]>

(2) <news:[email protected]>

(3) <news:0cc95c92-eae3-4891-8f5e-8f1a414f8ec5@l38g2000pro.googlegroups.com>

(4) <http://www.ietf.org/rfc/rfc3484.txt>

(5) <http://www.davidc.net/networking/ipv6-source-address-selection-linux>

#1 lore raw
Quoted 8 lines · Xavier Roche

1. one outgoing IP per service (for example, a SMTP server would have its own address for the outgoing interface - and one unique reverse IP to the declared SMTP server address)

The first case can sometimes be partially solved using application-specific configuration (bind to a specific address) - however this is not desirable when you need to listen to all interfaces (ie. including IPv4-only or IPv6-only ones)

You are confusing incoming with outgoing connections. bind is correct. For the incoming one you bind to [::]:25, for the outgoing one you bind to [2a01::desired]:0. Problem solved.

Quoted 2 lines

3. one outgoing IP for specific network blocks
etc ..

Hosts uses their assigned address as outgoing source address.

Quoted 12 lines

RFC 3484 (4) specifies the way source address is selected ; with the following order (5):

1. Prefer same address. (i.e. destination is local machine)
2. Prefer appropriate scope. (i.e. smallest scope shared with the destination)
3. Avoid deprecated addresses.
4. Prefer home addresses.
5. Prefer outgoing interface. (i.e. prefer an address on the interface we're sending out of)
6. Prefer matching label.
7. Prefer public addresses.
8. Use longest matching prefix.

And somewhere in between is /etc/gai.conf.

#2 lore raw

Jan Engelhardt a écrit :

Quoted 1 line

You are confusing incoming with outgoing connections.

Yes, my mistake.

Quoted 2 lines

correct. For the incoming one you bind to [::]:25, for the outgoing one you bind to [2a01::desired]:0. Problem solved.

What would happend for v4 destinations ? Both v4/v6 destinations may exist at the same time.

Quoted 1 line

And somewhere in between is /etc/gai.conf.

Yes, this allows to change the ordering of the rules (RFC 5014 if I am correct), but not to add a specific rule depending on various parameters (destination, owner, etc.) at all.

#3 lore raw
Quoted 10 lines · Xavier Roche

Jan Engelhardt a écrit :

Quoted 1 line

You are confusing incoming with outgoing connections.

Yes, my mistake.

Quoted 2 lines

correct. For the incoming one you bind to [::]:25, for the outgoing one you bind to [2a01::desired]:0. Problem solved.

What would happend for v4 destinations ? Both v4/v6 destinations may exist at the same time.

A socket is generally only responsible for a single protocol. In other words, that makes two sockets, one is [::]:25, the other is 0.0.0.0:25. Now since IPv6 was designed - as is usual for IETF, resp it working groups - a bit whacky, there exists the possibility to receive v4 connections on v6... but thank god there is a IPV6_V6ONLY socket option.

Quoted 2 lines

but not to add a specific rule depending on various parameters (destination, owner, etc.) at all.

ip route add $(address of google.com) src $(my alternate address)

should do it. IPsec already does so if I am not mistaken.

#4 lore raw

Jan Engelhardt a écrit :

Quoted 1 line

ip route add $(address of google.com) src $(my alternate address)

Yes, but not for protocol, owner, and any other rule. This is direct routine from a network to another one.

#5 lore raw
Quoted 5 lines · Xavier Roche

Jan Engelhardt a écrit :

Quoted 1 line

ip route add $(address of google.com) src $(my alternate address)

Yes, but not for protocol, owner, and any other rule. This is direct routine from a network to another one.

Well no, routing only concerns itself with layer-3 factors.

#6 lore raw
In reply to Jan Engelhardt

Jan Engelhardt a écrit :

Quoted 2 lines

ip route add $(address of google.com) src $(my alternate address) should do it. IPsec already does so if I am not mistaken.

Note: it does not appear to work (unless my fingers did something wrong), for multiple addresses within an interface. The selected source address is still the same. I suspect the only thing you can change is the outgoing interface ; source address selection logic then remains the same.

#7 lore raw

Hello again,

Quoted 5 lines · Xavier Roche
Quoted 2 lines · Jan Engelhardt

ip route add $(address of google.com) src $(my alternate address) should do it. IPsec already does so if I am not mistaken.

Note: it does not appear to work

IME, it works for IPv4 but not for IPv6 ; only IPv4 routes seem to support the "src" attribute, and IME src is silently ignored for IPv6 routes.

#8 lore raw

Pascal Hambourg a écrit :

Quoted 3 lines

IME, it works for IPv4 but not for IPv6 ; only IPv4 routes seem to support the "src" attribute, and IME src is silently ignored for IPv6 routes.

The conclusion seems to be "Yes, there is a need for a specific source address selection rule" to decide which IP address should be selected within a single interface, based on arbitrary rules. (especially for IPv6)

The question is now: is there a chance such feature could be included one day in the kernel ?

#9 lore raw
Quoted 4 lines · Xavier Roche

Pascal Hambourg a écrit :

Quoted 3 lines

IME, it works for IPv4 but not for IPv6 ; only IPv4 routes seem to support the "src" attribute, and IME src is silently ignored for IPv6 routes.

That's a bug then, I suppose.

#10 lore raw
Quoted 5 lines · Jan Engelhardt
Quoted 4 lines
Quoted 3 lines · Pascal Hambourg

IME, it works for IPv4 but not for IPv6 ; only IPv4 routes seem to support the "src" attribute, and IME src is silently ignored for IPv6 routes.

That's a bug then, I suppose.

Maybe. But in all cases, the other problem would still remain: the source address.

The src attribute is supported in V4, but only for routing.

Source address remains the same. (reason for the ugly NAT hacks in such cases)

#11 lore raw
Quoted 1 line · Xavier Roche

The src attribute is supported in V4, but only for routing.

Ha. Look at that. A src attribute in the routing table. Who would have thought it had /anything/ to do with routing? Inconceivable!

Of course it is for routing. That is why it is in the *drumroll* routing table!

It's not like the src attribute had any other function in V6.

#12 lore raw

Jan Engelhardt a écrit :

Quoted 2 lines

Of course it is for routing. That is why it is in the *drumroll* routing table!

Sure. But my point was related to the main topic of this thread: the damn source address is NOT at all concerned. Obvious or not, routing won't help.

#13 lore raw
Quoted 6 lines · Xavier Roche

Jan Engelhardt a écrit :

Quoted 2 lines

Of course it is for routing. That is why it is in the *drumroll* routing table!

Sure. But my point was related to the main topic of this thread: the damn source address is NOT at all concerned. Obvious or not, routing won't help.

So, either you agree that ignoring the src attribute in ipV6 is the bug, or you have an alternate theory that I have not yet groked.