> I have no idea how to control which address is used for outgoing > communications other than by configuring your network gateway to go through > the preferred device, which may not do exactly what you want.
I've just read through the whole thread. People seems to be getting confused about a couple of concepts. Firstly, consider the need to be able to manually specify the outbound IPv4 address of "Client" connections from a daemon _as well_ as the inbound address on which to listen for incoming service requests. In most shops, in almost all but the most basic configurations, the generally accepted practice is to create abstraction between the "system" and the "service" provided by it. Even if a system has a single service/function, it still binds the service to a "Service VIP", or "IP Alias (BSD)". I.e., almost all machines have a "Management Address" and "Service VIP", especially in non-RFC1918-space-only shops. To give you an idea why this is a policy in most places: For example, if a system crashes, you can pick up the VIP and move it to a different system in the same VLAN. ...OR, if that service VIP has a CNAME pointing to it, you can simply cut over the CNAME destination to a service VIP in a different VLAN without breaking all your clients. Thus, "System-Service Abstraction" This becomes especially paramount in High Availability configurations where at service VIP dangles between two or more servers. Consider the Linux-HA system. It is also extremely important when you're trying to manage firewall rule growth. At present, if you have multiple VIPs/IP Aliases on Bacula, you can control which one "Listening Sockets" bind to, but say for example, when writing rules that would permit the Director to send control messages to File Daemons, or Storage Daemons to send messages to Directors, or Consoles to Directors, you want your rules to reflect the source address of the service VIP for "new client sockets". Consider ISC BIND named(8): It's got all kinds of crazy options for binding listening sockets for incoming requests and specifying the source _port_ and _address_ for outbound connections the daemon is making in the capacity of a "client": Example: options { directory "/"; listen-on { 1.2.3.4/32; }; query-source address 2.4.5.6 port 12346; transfer-source 7.8.9.1; notify-source 2.3.3.5; .... } All kinds of control. ----------------- Secondly, "Socket Source Address/Port" v.s. "Routing" These are *completely autonomous concepts*. I just went through this bringing "-b" from FreeBSD syslogd(8) over to NetBSD(8): http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.sbin/syslogd/syslogd.c.diff?r1=1.78&r2=1.79&f=h Check out lines 2107->2111 This is an example with UDP, but the song remains the insane for TCP. When you bind(2)/listen(2) a socket(2), there are two modes: Passive and active. The address which a socket listens/binds is wildcard by default. You can set it though with getaddrinfo(2)...intuitive function call name, huh?! >:} Another good example are present in Apache's HTTP CVS: srclib/apr/network_io/unix/sockaddr.c There's no reference to any of this in any of Stevens` because those were all written before the advent of HA and Distributed Systems, possibly even IP Aliases/VIPs. Per my notes on "Service/System" abstraction, if a system has multiple interfaces, there are two possibilities: *) The interfaces could have addresses in different subnets *) The interfaces could have addresses in the same subnets A system could also have multiple VIPs or "IP Aliases" (BSD) on the same interface within the same Subnet (the most likely scenario). When you specifically bind the source address of an outgoing TCP socket to a specific VIP or Primary IP on an interface, the decision as to which interface to transmit the outgoing packets is not made in the TCP code, it is made at the next layer down on the OSI model -- the underlying IPv4/IPv6 protocol. Example, if a system has two NICs. One within a management subnet with RFC1918 address space, we'll say 10.0.0.100, and another with two IPs, a primary IP and a service VIP in a public subnet, we'll say 216.239.37.99 and 216.239.37.100. Consider the routing: Assume for the sake of sanity that the subnet masks on both interfaces are /25 on the public interface and /23 on the RFC1918 interface. Via "Directly Connected Interfaces", the system knows about 216.239.37.0/25 via "Ext", and 10.0.0.0/23 via "Int". It may also have a "Default Gateway" configured of 215.239.37.1/32. He may also know about a greater 10.0.0.0/8 via a "Static Route" via some internal router/firewall at 10.0.0.1 -- manually configured "route add -net 10.0.0.0/8 gw 10.0.0.1". Obviously, the default semantics apply to most modern operating systems: *) A layer 4 socket number discriminator is of course always required for UDP/TCP, but not for ICMP/TCP/ESP/AH/etc. *) For outbound UDP/ICMP/TCP/ESP/AH etc layer 3 protocols (/etc/protocols) sockets, if the source address is not specified, the layer 4 default address of the interface "closest" to the remote address is used. *) The layer 2 interface used for transmission is that of the one used in the default layer 3 protocol address acquisition algorithm. The kernel makes this decision though based on the routing table and weighted priories and metrics. I.e, connected > static > null > learned via IGP/BGP (2) *) The layer 3 address could be specified in the code / by the user, in which case, a one of many VIPs within the same subnet on the same interface could be used, but the layer 2 transmit interface remains the same. *) The exception to the previous two rules are as follows: -) The remote address of the outbound TCP socket is in a subnet known via "Directly Connected Route" on an interface other than the source address the user specified the local socket -) The remote address of the outbound TCP socket is in a subnet known by "Static Route" via a gateway/interface on an interface in a subnet other than the address of the local socket. In these instances, the behavior is OS independent, but connect(2) or bind(2) should fail miserably, even if functions themselves return successfully. (1) *) For incoming passive listen sockets, if no bind address is specified, it becomes a wildcard bind (examples: vintage inetd(8), etc.) -- unintelligent daemons like this were the reasons behind tcpwrappers. 1. Consider the routing: Assume for the sake of sanity that the subnet masks on the interfaces are /25 on the public interface and /23 on the RFC1918 interface. Via "Directly Connected Interfaces", the system knows about 216.239.37.0/25 via "Ext", and 10.0.0.0/23 via "Int". It may also have a "Default Gateway" configured of 215.239.37.1/32. He may also know about a greater 10.0.0.0/8 via a "Static Route" via some internal router/firewall at 10.0.0.1 -- manually configured "route add -net 10.0.0.0/8 gw 10.0.0.1". On this system, a random client program ("foo") could very easily bind it's TCP socket source address to the VIP 216.239.37.100, then connect(2) in active mode to a foreign destination address 10.0.3.101. Or maybe tries to "ping -B 216.239.37.100 10.0.3.100". The operating system will very happily transmit that IPv4 packet containing the TCP/ICMP packet out of the "Int" private interface with the "Ext" VIP address as the source address. That datagram makes its way onto the ethernet segment. As long as router 10.0.0.1/32, and all of the corresponding routers en route to 10.0.3.101/32 are willing to forward the packet (i.e., they know a return route to 216.239.37.100/32 via 10.0.0.100/32), it will actually work. If they dont, the socket will time out tranmitting IPv4 packets (which contain a TCP SYN packet) that 10.0.0.1/32 will discard due to perhaps a BOGON list. Next, vanquish all thoughts about using a Linux kernel specific kernel hacks like IPCHAINs. Obviously a OS kernel-specific solution is not optimal. There are some cheap tricks that you could do with OpenBSD's pf(4) as well, but I certainly wouldn't go recommending those to anyone. Background on that: A lot of this confusion is Linux's fault. I've seen some Linux-specific hacks that like to accept command line arguments for "Transmit Interface", like "./foo.bar -interface=eth0". This has a lot to do with the fact that Linux considers VIPs separate logical interface structures, thus verily easily blurring the distinction. Clearly, this is just a lot of smoke and mirrors around choosing a proper source address for the socket/ICMP/ESP/layer 3 datagram. In summary: You cant control the "Transmit Interface", you can control the layer 4 socket number and the layer 3 transmit address; -- the kernel will make the outbound layer 2 physical interface encapsulation for you, based on your directly connected routes, static routes, default gateway, IGPs, etc. 2. See table: http://www.cisco.com/warp/public/105/21.html#building Finally, consider the practical examples: *) Bconsole will almost always run on a workstation with a single IP address with a single default gateway. Outbound TCP connection source address auto-determination applies 99% of time. However, if for some internal security policy compels it, the Administrator would certainly enjoy the ability to source the Concsole->Dir socket from an alternative VIP. *) The FileDaemon running on a workstation will only use one source address available to talk to Dir and StorageD. *) The FileDaemon running a HA or multi-homed server will almost always want to use it's "Management" address on a private/RFC1918 network to initiate outbound TCP connections for: - Messages from FileDir->Director (logs) - Backup date from FileDir->StorageDir However, there is always the remote but entirely reasonable possibility that the server has a dedicated backup network interface in a subnet that overlaps with a static route assigned to the Management network. Example: "Ext0": 1.2.3.4/25. "Default gw": 1.2.3.1/32 "Mngmnt0" 10.0.100.200/24" "Static 10.0.0.0/8 via 10.0.100.1" "Backup0": 10.0.200.200/24 "Storage Dir": 10.0.200.100/32 In this complicated but entirely possible scenario, being able to specify the source address of the backup network interface helps the kernel pick the proper transmit interface by allowing it to discriminate the route known via directly connected over the metric/weight of the static route. *) And of course, the StorageDir->Director and Director->StorageDir connections, which could reside in HA/Load-Balanced configurations, rely on the source address of the remote host to authenticate. Consider: 192.168.100.0/23 [B-SD-Active .101][B-SD-Standby .102] [B-SD-HA VIP .100] | | \ / Router {192.168.100.1/32} {192.168.200.1/32} / \ | | [B-Dir-HA .100] [B-Dir-Active .101][B-Dir-Standby .102] In this config, the HA VIP for both is an IfAlias on the active system. When it transmits to the configured HA address of the SD or Dir resource, the remote active will fail to authenticate because the source address will be that of the Active "Primary IP" and not the service VIP. Another great example of the need for source address specification is a POSIX/Linux/BSD/UNIX system deployed as a remote VPN tunnel termination point / router appliance. Details: - The remote private RFC1918 subnet is 172.16.100.0/24 at the branch office. - The local subnet at the HQ where the Dir/StorageD is is 172.16.99.0/24 - The HQ has a WAN connection 1.2.3.4, the Branch has a WAN connection 2.3.4.5 - The IPSEC/ISAKMP ACLs will stipulate 172.168.0.0/12 on the HQ side and 172.16.100.0/24 on the branch. - When the branch office receives packets on it's internal interface from LAN hosts matching 172.16.100.0/24 destined for 172.16.0.0/12, it knows to ESP/AH them and transmit them out it's Ext., if not, NAT/PAT to 2.3.4.5/32 - However, the remote branch machine/router/appliance whatever, when generating packets itself destined for 172.16.0.0/12 will not attempt to ESP/AH encapsulate unless you specify a source address of it's internal interface. By default, kernel routing semantics will attempt to transmit those packets out the Ext interface using NAT/PAT via the default gateway. Consider it: The kernel has no way of knowing any kind of inverse / reverse routing decision such as: "Hey Locally initiated traffic destined for a subnet I know via an ESP/GRE tunnel, use this source address if you wish to qualify for the VPN ACL and reach your destination." That simply doesn't work. ~BAS > > In any event, unless I am misunderstanding something, Bacula has no mechanism > for controlling outgoing addresses. ------------------------------------------------------------------------- Take Surveys. Earn Cash. Influence the Future of IT Join SourceForge.net's Techsay panel and you'll get the chance to share your opinions on IT & business topics through brief surveys -- and earn cash http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV _______________________________________________ Bacula-users mailing list Bacula-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/bacula-users