Re: Source IPv4 address selection vs BGP IX connection

2024-04-26 Thread Mike Karels
On 25 Apr 2024, at 15:56, Gregory Shapiro wrote:

>> of course, gethostid(3) is now deprecated in favour of sysctl(3), and the
>> hostid(8) command is gone, and there's now more than one flavour of
>> Internet-capable UNIX in the world, and there's more than one Internet
>> address family now. so what i did in 1990 is a guide only inasmuch as some
>> way should exist to change the default local address of a socket so that it
>> isn't the address of the interface used for the destination. if that happens
>> i hope we coordinate with Linux and with the other BSD's.
>
> Linux already has a model to give a hint for source address selection via
> route table "hints".  When adding routes (either manually via `ip route'
> or via things like bird2 BGP daemon), Linux supports setting a source IP
> for when that route is used.
>
> Interestingly, JunOS (which I believe is based on FreeBSD) also supports
> a way to specify a default IPv4 source address, preferring the primary address
> on lo0 that is not 127.0.0.1.  It is a common practice for BGP systems to
> attach their announced IPs to the loopback interface.
>
> https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/default-address-selection-edit-system.html
>
> For the Linux and bird (BGP) documentation:
>
> Linux
> -
> http://linux-ip.net/html/tools-ip-route.html#ex-tools-ip-route-add-src
>
> "The src option provides a hint to the kernel for source address selection. 
> When you are working with multiple routing tables and different classes of 
> traffic, you can ease your administrative burden, by hosting several 
> different IPs on your linux machine and setting the source address 
> differently, depending on the type of traffic.
>
> In the example below, let's assume that our masquerading host also runs a DNS 
> resolver for the internal network and we have selected all of the outbound 
> DNS packets to be routed according to table 7 [53]. Now, any packet which 
> originates on this box (or is masqueraded through this table) will have its 
> source IP set to 205.254.211.198.
>
> Example D.19. Using src in a routing command with route add
>
> [root@masq-gw]# ip route add default via 205.254.211.254 src 205.254.211.198 
> table 7
> "
>
> man ip-route
>
> "src ADDRESS
>   the source address to prefer when sending to the
>   destinations covered by the route prefix."

When you first asked this question, my first thought was that this should
be in the routing table.  It seems to me that choosing the source address
is more a function of the destination than of the process (vnet, jail,
etc).  In fact, this problem seemed familiar, so I went looking.  It turns
out that this feature has been available since 4.4BSD.

route(8) has a keyword to do just this, -ifa (interface address).  It only
seems to work when the alias is on the same interface.  It also seems to
be broken in -current and 14.0, but I got it to work with 13.3 and 12.4.
While experimenting, I tried to use -ifp as well, but it seems to be ignored;
route add -ifp foobar ... does not fail.  (12.4 got the interface wrong
when the alias was on the loopback.)

Anyone know why -ifa is ineffective in 14.0 and -current?  It could
be fallout from netlink.

The documentation is weak at best; route(8) says only "the -ifp or -ifa
modifiers may be used to determine the interface or interface address".
"route get" does not display the ifa; I think it did at one time.

I'll also note that binding the desired source address manually works;
ping -S uses this.

Mike

>
> Bird (BGP Daemon)
> 
> "The Kernel protocol defines several attributes. These attributes are 
> translated to appropriate system (and OS-specific) route attributes. We 
> support these attributes:
> ..
> ip krt_prefsrc
> (Linux) The preferred source address. Used in source address selection for 
> outgoing packets. Has to be one of the IP addresses of the router."



Re: Source IPv4 address selection vs BGP IX connection

2024-04-25 Thread Rodney W. Grimes
> > of course, gethostid(3) is now deprecated in favour of sysctl(3), and the
> > hostid(8) command is gone, and there's now more than one flavour of
> > Internet-capable UNIX in the world, and there's more than one Internet
> > address family now. so what i did in 1990 is a guide only inasmuch as some
> > way should exist to change the default local address of a socket so that it
> > isn't the address of the interface used for the destination. if that happens
> > i hope we coordinate with Linux and with the other BSD's.
> 
> Linux already has a model to give a hint for source address selection via
> route table "hints".  When adding routes (either manually via `ip route'
> or via things like bird2 BGP daemon), Linux supports setting a source IP
> for when that route is used.
> 
> Interestingly, JunOS (which I believe is based on FreeBSD) also supports
> a way to specify a default IPv4 source address, preferring the primary address
> on lo0 that is not 127.0.0.1.

The part of JunOS which is FreeBSD based runs inside a VM on Juniper
routers and is a control plane only thing, what your probably
seing is an artifact of the switch to Linux by Juniper.

> It is a common practice for BGP systems to
> attach their announced IPs to the loopback interface.
These routers are almost always reject type routes and used to
hold the routes 'UP' even if the IGP of an AS flaps them.
This is not done to effect source IP address selection.

> 
> https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/default-address-selection-edit-system.html
> 
> For the Linux and bird (BGP) documentation:
> 
> Linux
> -
> http://linux-ip.net/html/tools-ip-route.html#ex-tools-ip-route-add-src
> 
> "The src option provides a hint to the kernel for source address selection. 
> When you are working with multiple routing tables and different classes of 
> traffic, you can ease your administrative burden, by hosting several 
> different IPs on your linux machine and setting the source address 
> differently, depending on the type of traffic.
> 
> In the example below, let's assume that our masquerading host also runs a DNS 
> resolver for the internal network and we have selected all of the outbound 
> DNS packets to be routed according to table 7 [53]. Now, any packet which 
> originates on this box (or is masqueraded through this table) will have its 
> source IP set to 205.254.211.198.

This is in effect what someone else suggested using multiple route tables in 
freeBSD and ipfw rules, iirc.

> 
> Example D.19. Using src in a routing command with route add
> 
> [root@masq-gw]# ip route add default via 205.254.211.254 src 205.254.211.198 
> table 7
> "
> 
> man ip-route
> 
> "src ADDRESS
>   the source address to prefer when sending to the
>   destinations covered by the route prefix."
> 
> 
> Bird (BGP Daemon)
> 
> "The Kernel protocol defines several attributes. These attributes are 
> translated to appropriate system (and OS-specific) route attributes. We 
> support these attributes:
> ..
> ip krt_prefsrc
> (Linux) The preferred source address. Used in source address selection for 
> outgoing packets. Has to be one of the IP addresses of the router."

This is for the purpose of bird process only and does not effect other 
processes.  This is mainly used to control the source addressed used for eBGP 
sessions, though this can fail misserably when you have multiple interfaces 
speaking eBGP.

Though I can see some merit in what your suggesting to do, I also know that it 
comes with a many problems as it might solve, like ping would stop working on a 
local link if the assigned "src IP" is not routable by the entity your trying 
to ping, which for me would be the case in many places as the IX IP only 
appears on the IX interface and nothing any place inside or outside my AS has a 
route to it.  I believe this is the intent of the IX IP policy on use of 
unrouteable IP addresses.

-- 
Rod Grimes rgri...@freebsd.org



Re: Source IPv4 address selection vs BGP IX connection

2024-04-25 Thread Gregory Shapiro
> of course, gethostid(3) is now deprecated in favour of sysctl(3), and the
> hostid(8) command is gone, and there's now more than one flavour of
> Internet-capable UNIX in the world, and there's more than one Internet
> address family now. so what i did in 1990 is a guide only inasmuch as some
> way should exist to change the default local address of a socket so that it
> isn't the address of the interface used for the destination. if that happens
> i hope we coordinate with Linux and with the other BSD's.

Linux already has a model to give a hint for source address selection via
route table "hints".  When adding routes (either manually via `ip route'
or via things like bird2 BGP daemon), Linux supports setting a source IP
for when that route is used.

Interestingly, JunOS (which I believe is based on FreeBSD) also supports
a way to specify a default IPv4 source address, preferring the primary address
on lo0 that is not 127.0.0.1.  It is a common practice for BGP systems to
attach their announced IPs to the loopback interface.

https://www.juniper.net/documentation/us/en/software/junos/cli-reference/topics/ref/statement/default-address-selection-edit-system.html

For the Linux and bird (BGP) documentation:

Linux
-
http://linux-ip.net/html/tools-ip-route.html#ex-tools-ip-route-add-src

"The src option provides a hint to the kernel for source address selection. 
When you are working with multiple routing tables and different classes of 
traffic, you can ease your administrative burden, by hosting several different 
IPs on your linux machine and setting the source address differently, depending 
on the type of traffic.

In the example below, let's assume that our masquerading host also runs a DNS 
resolver for the internal network and we have selected all of the outbound DNS 
packets to be routed according to table 7 [53]. Now, any packet which 
originates on this box (or is masqueraded through this table) will have its 
source IP set to 205.254.211.198.

Example D.19. Using src in a routing command with route add

[root@masq-gw]# ip route add default via 205.254.211.254 src 205.254.211.198 
table 7
"

man ip-route

"src ADDRESS
  the source address to prefer when sending to the
  destinations covered by the route prefix."


Bird (BGP Daemon)

"The Kernel protocol defines several attributes. These attributes are 
translated to appropriate system (and OS-specific) route attributes. We support 
these attributes:
..
ip krt_prefsrc
(Linux) The preferred source address. Used in source address selection for 
outgoing packets. Has to be one of the IP addresses of the router."





Re: Source IPv4 address selection vs BGP IX connection

2024-04-24 Thread Paul Vixie
agreed. and one of my mods to the ultrix (~4.3bsd) kernel for 
gatekeeper.dec.com back in ~1990 was to use the result of gethostid(3) 
if that result was nonzero and if a socket was not already bound. so 
named(8) and ntpd(8) and anything else that used explicit binding got 
what they expected, but the vast majority who just used INADDR_ANY (or 
more often just bzero(3)'d the sockaddr) would get what the sysadmin 
wanted. multihoming wasn't well understood and has gotten worse since.


of course, gethostid(3) is now deprecated in favour of sysctl(3), and 
the hostid(8) command is gone, and there's now more than one flavour of 
Internet-capable UNIX in the world, and there's more than one Internet 
address family now. so what i did in 1990 is a guide only inasmuch as 
some way should exist to change the default local address of a socket so 
that it isn't the address of the interface used for the destination. if 
that happens i hope we coordinate with Linux and with the other BSD's.


Gregory Shapiro wrote on 2024-04-24 11:00:

I still see value in source IP selection, even outside of the IX use
case.



--
P Vixie




Re: Source IPv4 address selection vs BGP IX connection

2024-04-24 Thread mike tancsa

On 4/23/2024 10:12 PM, Gregory Shapiro wrote:

Short version:

Using FreeBSD as a BGP router has network issues caused by suboptimal
default IPv4 source address selection when connected to Internet
Exchanges (which are required to use IPs that aren't routable on the
Internet).  I was hoping to find more elegant workarounds or encourage
FreeBSD to add source IPv4 selection akin to the existing IPv6 source
address selection (no_prefer_iface and prefer_source).

I assume that there is a group of BGP enthusiasts using FreeBSD lurking
on freebsd-net.  What have you done to solve this problem?

For DNS in such situations I start unbound locally and bind it to an 
internal interface or an IP on lo0 and then tell unbound to just use 
that IP only  (outgoing-interface IIRC) that is advertised out as a work 
around.  Its not a proper solution, but will get your resolver working 
at least. I run into this problem in layered networks where the next hop 
is often RFC 1918 addrs. I bind applications to internal NICs that have 
addresses that have routing to/from.


    ---Mike


Re: Source IPv4 address selection vs BGP IX connection

2024-04-24 Thread Gregory Shapiro
> The mistake your making, IMHO, is that an IX connected eBGP FreeBSD
> router _SHOULD NOT_ be doing ANYTHING other than BGP on the IX
> connected interface, and anything like DNS and outbound SMTP should be
> going inward on the AS, not outward to the internet.

Fair point and thank you for the advice.  I am locking it down to an
extent (denying all inbound ports except 22, 179 from an ipfw table list
of trusted hosts/peers/upstreams/downstreams) but not as tightly as you
suggest as I do use some on-Internet services.  Specifically, port 25 to
my own mail server (not unwashed Internet service, but sitting off of a
different network) for system generated mail (cron, /etc/periodic/ script
output), 53 to admittedly "unwashed" Google DNS, and 123 to
FreeBSD's NTP pool (again "unwashed" to an extent).

I will look at using local instances for the latter two.

I still see value in source IP selection, even outside of the IX use
case.



Re: Source IPv4 address selection vs BGP IX connection

2024-04-24 Thread Gregory Shapiro
On Wed, Apr 24, 2024 at 07:10:51AM +0200, Marek Zarychta wrote:
> W dniu 24.04.2024 o 04:12, Gregory Shapiro pisze:
> > Short version:
> > 
> > Using FreeBSD as a BGP router has network issues caused by suboptimal
> > default IPv4 source address selection when connected to Internet
> > Exchanges (which are required to use IPs that aren't routable on the
> > Internet).  I was hoping to find more elegant workarounds or encourage
> > FreeBSD to add source IPv4 selection akin to the existing IPv6 source
> > address selection (no_prefer_iface and prefer_source).

> In this case, probably best solution will probably be using multiple FIBs.
> Running a BGP routing daemon under not default FIB after assigning its
> interface to this FIB should solve the problem but it might create
> eventually new problems to solve (for example in which FIB should imported
> routes be stored).

Thank you for sharing the ideas.  This first idea seems to negate the
positive impact of multihoming and connecting to the IX for peering and
additional transit.  If the routes aren't usable in the default routing
RIB (for downstream/LAN hosts or the router itself), then there doesn't
seem to be a purpose of having multiple routes.

> It's also possible to set and use non-default FIB for DNS lookups and
> maintenance tasks like pkg upgrade (setfib -1 pkg ). This approach is
> probably more straightforward to conduct.

Until you consider that not all work is done from the command line such that
'setfib' can proceed every command.  What if cron wants to send a message
with output from a cron job?  What if a system service needs to connect to
another host (e.g., ntpd)?  Even to ssh into the system, sshd needs DNS
for PTR lookups.

I really think this isn't an issue with routing (and therefore can't be
fixed elegantly by changing routing).  It is an issue with source IP
selection (one that has been addressed for IPv6, just not IPv4).

I'll try to dig into how FreeBSD does source IP selection and see if I
can add code to tune that process.



Re: Source IPv4 address selection vs BGP IX connection

2024-04-24 Thread Rodney W. Grimes
> Short version:
> 
> Using FreeBSD as a BGP router has network issues caused by suboptimal
> default IPv4 source address selection when connected to Internet
> Exchanges (which are required to use IPs that aren't routable on the
> Internet).  I was hoping to find more elegant workarounds or encourage
> FreeBSD to add source IPv4 selection akin to the existing IPv6 source
> address selection (no_prefer_iface and prefer_source).
> 
> 
> Long version:
> 
> Unless I'm mistaken, today, there is no way to set the default
> IPv4 source address for connections like there is with IPv6 (using
> no_prefer_iface and prefer_source).
> 
> It appears the default source IP is chosen based on IP address of
> the outbound interface for the packet.  This presents a problem on
> FreeBSD systems acting as BGP routers that have connections to Internet
> exchanges (IX).  One of the rules of IX IP addresses is that they are
> must not be routable on the Internet.
> 
> As a simple example, a system with two Ethernet interfaces, one to the
> transit provider and one to an IX would look like this:
> 
> vtnet0: flags=1008843 metric 
> 0 mtu 1500
>   description: Uplink
>   inet 193.148.250.141 netmask 0xff00 broadcast 193.148.250.255
> vtnet1: flags=1008843 metric 
> 0 mtu 1500
>   description: IX
>   inet 185.1.147.211 netmask 0xff00 broadcast 185.1.147.255
> 
> Then if /etc/resolv.conf contains 8.8.8.8 and BGP selects a route for
> 8.8.8.0/24 over the IX, you end up with:
> 
> # route  -n get 8.8.8.8
>route to: 8.8.8.8
> destination: 8.8.8.0
>mask: 255.255.255.0
> gateway: 185.1.147.22
> fib: 0
>   interface: vtnet1
>   flags: 
>  recvpipe  sendpipe  ssthresh  rtt,msecmtuweightexpire
>0 0 0 0  1500 1 0
> 
> And DNS on the system doesn't work as all DNS requests go out with a
> source address of 185.1.147.211 (the IX endpoint) which isn't exported
> as an Internet route.
> 
> While I can set a static route for 8.8.8.8 for this particular case, it
> would be messy to have to set up static routes for every possible local
> connection (other DNS servers, outbound SMTP for periodic/cron mail,
> etc.).

The mistake your making, IMHO, is that an IX connected eBGP FreeBSD
router _SHOULD NOT_ be doing ANYTHING other than BGP on the IX
connected interface, and anything like DNS and outbound SMTP should be
going inward on the AS, not outward to the internet.

I must ask why your using 8.8.8.8 and not your own nameservers?
Why would you want or even allow outbound SMTP from such a
critical infustructure point go out over the unwashed internet?

One of the reasons for using the non-routable IP on IX connected
eBGP routers is to minimize the exposure footprint, and what you
seem to be doing is defeating that minimization by wanting to
expose another IP on that very box to the public internet.

> 
> I assume that there is a group of BGP enthusiasts using FreeBSD lurking
> on freebsd-net.  What have you done to solve this problem?

I only trust AS internal objects from my eBGP routers,
they have no need to speak to the unwashed internet other
than to IX peers.
 
> I'd also love to hear other tips for running BGP on FreeBSD.

Lock it down as tight as you can if your IX connected.
I dont even allow inbound BGP connection setup, all eBGP
sessions have to be initiated by my router.

ipfw -a list 20179
20179 23854  1131316 deny log tcp from any to any 179

This is at an ISP peer, not an IX, so not a private IX IP range,
but 23854 attempts to connect to my bgp.

-- 
Rod Grimes rgri...@freebsd.org



Re: Source IPv4 address selection vs BGP IX connection

2024-04-23 Thread Marek Zarychta

W dniu 24.04.2024 o 04:12, Gregory Shapiro pisze:

Short version:

Using FreeBSD as a BGP router has network issues caused by suboptimal
default IPv4 source address selection when connected to Internet
Exchanges (which are required to use IPs that aren't routable on the
Internet).  I was hoping to find more elegant workarounds or encourage
FreeBSD to add source IPv4 selection akin to the existing IPv6 source
address selection (no_prefer_iface and prefer_source).


Long version:

Unless I'm mistaken, today, there is no way to set the default
IPv4 source address for connections like there is with IPv6 (using
no_prefer_iface and prefer_source).

It appears the default source IP is chosen based on IP address of
the outbound interface for the packet.  This presents a problem on
FreeBSD systems acting as BGP routers that have connections to Internet
exchanges (IX).  One of the rules of IX IP addresses is that they are
must not be routable on the Internet.

As a simple example, a system with two Ethernet interfaces, one to the
transit provider and one to an IX would look like this:

vtnet0: flags=1008843 metric 0 
mtu 1500
description: Uplink
inet 193.148.250.141 netmask 0xff00 broadcast 193.148.250.255
vtnet1: flags=1008843 metric 0 
mtu 1500
description: IX
inet 185.1.147.211 netmask 0xff00 broadcast 185.1.147.255

Then if /etc/resolv.conf contains 8.8.8.8 and BGP selects a route for
8.8.8.0/24 over the IX, you end up with:

# route  -n get 8.8.8.8
route to: 8.8.8.8
destination: 8.8.8.0
mask: 255.255.255.0
 gateway: 185.1.147.22
 fib: 0
   interface: vtnet1
   flags: 
  recvpipe  sendpipe  ssthresh  rtt,msecmtuweightexpire
0 0 0 0  1500 1 0

And DNS on the system doesn't work as all DNS requests go out with a
source address of 185.1.147.211 (the IX endpoint) which isn't exported
as an Internet route.

While I can set a static route for 8.8.8.8 for this particular case, it
would be messy to have to set up static routes for every possible local
connection (other DNS servers, outbound SMTP for periodic/cron mail,
etc.).

I assume that there is a group of BGP enthusiasts using FreeBSD lurking
on freebsd-net.  What have you done to solve this problem?

I'd also love to hear other tips for running BGP on FreeBSD.

In this case, probably best solution will probably be using multiple 
FIBs. Running a BGP routing daemon under not default FIB after assigning 
its interface to this FIB should solve the problem but it might create 
eventually new problems to solve (for example in which FIB should 
imported routes be stored).


It's also possible to set and use non-default FIB for DNS lookups and 
maintenance tasks like pkg upgrade (setfib -1 pkg ). This approach 
is probably more straightforward to conduct.


--
Marek Zarychta