Steve Polyack wrote:
Back to the drawing board.
I redid this patch to utilize two new config options: FDSourceAddress
(bacula-fd.conf) and DirSourceAddress (bacula-dir.conf). When either of
these are not set, the connection behavior does not change; bind(2) is
not called and the kernel chooses the outgoing address. If you specify
a source address Bacula will now choose that address to source
connections from.
Here's an example for the Director and SD of where this becomes useful:
You have a Bacula director with several IP addresses available.
10.0.0.100 is a management address (firewall lets authorized users/IPs
ssh to the server at this address), and 10.0.0.200 is the backup VIP. I
have a storage daemon on anothermachine listening on a VIP 10.0.0.250.
Previously, since 10.0.0.100 is the first address on the interface, when
the Bacula director tries to connect, (whether it's to a storage daemon
or file daemon) this connection will come from 10.0.0.100. This makes
writing firewall rules in "default deny" environment unintuitive.
Instead of just using the address the storage daemon and director are
listening on ("bound" to) and writing firewall rules like:
allow $clients to $director on port 9102
allow $director to $storageDaemon on port 9103
I have to make exceptions to account for bacula connecting *from* the
management address.
allow $clients to $director on port 9102
allow $director-Mgmt to $storageDaemon on port 9103
But now, I can tell the director to source it's connections from the
same VIP it is listening on:
DirAddress = 10.0.0.200
DirSourceAddress 10.0.0.200
and corresponding "rules":
allow $clients to $director on port 9102
allow $director to $storageDaemon on port 9103
This preserves a 1:1 mapping of the Bacula services to the Bacula VIP.
Let me know if you need any further clarifications. The patch is attached.
diff -ru bacula-2.4.4/src/dird/dird_conf.c
bacula-2.4.4-patched/src/dird/dird_conf.c
--- bacula-2.4.4/src/dird/dird_conf.c 2008-06-19 15:44:34.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/dird_conf.c 2009-03-27 08:02:05.000000000
-0400
@@ -112,6 +112,7 @@
{"dirport", store_addresses_port, ITEM(res_dir.DIRaddrs), 0,
ITEM_DEFAULT, 9101},
{"diraddress", store_addresses_address, ITEM(res_dir.DIRaddrs), 0,
ITEM_DEFAULT, 9101},
{"diraddresses",store_addresses, ITEM(res_dir.DIRaddrs), 0,
ITEM_DEFAULT, 9101},
+ {"dirsourceaddress",store_addresses_address, ITEM(res_dir.DIRsrc_addr), 0,
ITEM_DEFAULT, 0},
{"queryfile", store_dir, ITEM(res_dir.query_file), 0, ITEM_REQUIRED,
0},
{"workingdirectory", store_dir, ITEM(res_dir.working_directory), 0,
ITEM_REQUIRED, 0},
{"scriptsdirectory", store_dir, ITEM(res_dir.scripts_directory), 0, 0, 0},
@@ -1001,6 +1002,9 @@
if (res->res_dir.DIRaddrs) {
free_addresses(res->res_dir.DIRaddrs);
}
+ if (res->res_dir.DIRsrc_addr) {
+ free_addresses(res->res_dir.DIRsrc_addr);
+ }
if (res->res_dir.tls_ctx) {
free_tls_context(res->res_dir.tls_ctx);
}
diff -ru bacula-2.4.4/src/dird/dird_conf.h
bacula-2.4.4-patched/src/dird/dird_conf.h
--- bacula-2.4.4/src/dird/dird_conf.h 2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/dird_conf.h 2009-03-27 07:53:22.000000000
-0400
@@ -106,6 +106,7 @@
public:
RES hdr;
dlist *DIRaddrs;
+ dlist *DIRsrc_addr; /* address to source connections from */
char *password; /* Password for UA access */
char *query_file; /* SQL query file */
char *working_directory; /* WorkingDirectory */
diff -ru bacula-2.4.4/src/dird/fd_cmds.c bacula-2.4.4-patched/src/dird/fd_cmds.c
--- bacula-2.4.4/src/dird/fd_cmds.c 2008-08-15 12:58:28.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/fd_cmds.c 2009-03-27 08:03:14.000000000
-0400
@@ -79,7 +79,7 @@
int connect_to_file_daemon(JCR *jcr, int retry_interval, int max_retry_time,
int verbose)
{
- BSOCK *fd;
+ BSOCK *fd = new_bsock();
char ed1[30];
utime_t heart_beat;
@@ -93,8 +93,11 @@
char name[MAX_NAME_LENGTH + 100];
bstrncpy(name, _("Client: "), sizeof(name));
bstrncat(name, jcr->client->name(), sizeof(name));
- fd = bnet_connect(jcr, retry_interval, max_retry_time, heart_beat,
- name, jcr->client->address, NULL, jcr->client->FDport, verbose);
+ if (!fd->connect(jcr,retry_interval,max_retry_time, heart_beat, name,
jcr->client->address,
+ NULL, jcr->client->FDport, verbose, director->DIRsrc_addr)) {
+ fd->destroy();
+ fd = NULL;
+ }
if (fd == NULL) {
set_jcr_job_status(jcr, JS_ErrorTerminated);
return 0;
diff -ru bacula-2.4.4/src/dird/msgchan.c bacula-2.4.4-patched/src/dird/msgchan.c
--- bacula-2.4.4/src/dird/msgchan.c 2008-09-08 15:21:08.000000000 -0400
+++ bacula-2.4.4-patched/src/dird/msgchan.c 2009-03-27 08:03:02.000000000
-0400
@@ -76,7 +76,7 @@
bool connect_to_storage_daemon(JCR *jcr, int retry_interval,
int max_retry_time, int verbose)
{
- BSOCK *sd;
+ BSOCK *sd = new_bsock();
STORE *store;
utime_t heart_beat;
@@ -102,9 +102,11 @@
*/
Dmsg2(100, "bnet_connect to Storage daemon %s:%d\n", store->address,
store->SDport);
- sd = bnet_connect(jcr, retry_interval, max_retry_time, heart_beat,
- _("Storage daemon"), store->address,
- NULL, store->SDport, verbose);
+ if (!sd->connect(jcr, retry_interval, max_retry_time, heart_beat,
_("Storage daemon"),
+ store->address, NULL, store->SDport, verbose,
director->DIRsrc_addr)) {
+ sd->destroy();
+ sd = NULL;
+ }
if (sd == NULL) {
return false;
}
diff -ru bacula-2.4.4/src/filed/filed_conf.c
bacula-2.4.4-patched/src/filed/filed_conf.c
--- bacula-2.4.4/src/filed/filed_conf.c 2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/filed_conf.c 2009-03-27 07:41:45.000000000
-0400
@@ -91,6 +91,7 @@
{"fdport", store_addresses_port, ITEM(res_client.FDaddrs), 0,
ITEM_DEFAULT, 9102},
{"fdaddress", store_addresses_address, ITEM(res_client.FDaddrs), 0,
ITEM_DEFAULT, 9102},
{"fdaddresses", store_addresses, ITEM(res_client.FDaddrs), 0,
ITEM_DEFAULT, 9102},
+ {"fdsourceaddress", store_addresses_address, ITEM(res_client.FDsrc_addr),
0, ITEM_DEFAULT, 0},
{"workingdirectory", store_dir, ITEM(res_client.working_directory), 0,
ITEM_REQUIRED, 0},
{"piddirectory", store_dir, ITEM(res_client.pid_directory), 0,
ITEM_REQUIRED, 0},
@@ -260,6 +261,9 @@
if (res->res_client.FDaddrs) {
free_addresses(res->res_client.FDaddrs);
}
+ if (res->res_client.FDsrc_addr) {
+ free_addresses(res->res_client.FDaddrs);
+ }
if (res->res_client.pki_keypair_file) {
free(res->res_client.pki_keypair_file);
diff -ru bacula-2.4.4/src/filed/filed_conf.h
bacula-2.4.4-patched/src/filed/filed_conf.h
--- bacula-2.4.4/src/filed/filed_conf.h 2008-06-18 15:22:03.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/filed_conf.h 2009-03-27 07:53:38.000000000
-0400
@@ -75,6 +75,7 @@
struct CLIENT {
RES hdr;
dlist *FDaddrs;
+ dlist *FDsrc_addr; /* address to source connections from */
char *working_directory;
char *pid_directory;
char *subsys_directory;
diff -ru bacula-2.4.4/src/filed/job.c bacula-2.4.4-patched/src/filed/job.c
--- bacula-2.4.4/src/filed/job.c 2008-06-30 08:56:49.000000000 -0400
+++ bacula-2.4.4-patched/src/filed/job.c 2009-03-27 07:50:12.000000000
-0400
@@ -1292,7 +1292,7 @@
int stored_port; /* storage daemon port */
int enable_ssl; /* enable ssl to sd */
BSOCK *dir = jcr->dir_bsock;
- BSOCK *sd; /* storage daemon bsock */
+ BSOCK *sd = new_bsock(); /* storage daemon bsock */
Dmsg1(100, "StorageCmd: %s", dir->msg);
if (sscanf(dir->msg, storaddr, &jcr->stored_addr, &stored_port,
&enable_ssl) != 3) {
@@ -1303,8 +1303,14 @@
Dmsg3(110, "Open storage: %s:%d ssl=%d\n", jcr->stored_addr, stored_port,
enable_ssl);
/* Open command communications with Storage daemon */
/* Try to connect for 1 hour at 10 second intervals */
- sd = bnet_connect(jcr, 10, (int)me->SDConnectTimeout,
me->heartbeat_interval,
- _("Storage daemon"), jcr->stored_addr, NULL,
stored_port, 1);
+
+ if (!sd->connect(jcr, 10, (int)me->SDConnectTimeout, me->heartbeat_interval,
+ _("Storage daemon"), jcr->stored_addr, NULL, stored_port, 1,
me->FDsrc_addr)) {
+ sd->destroy();
+ sd = NULL;
+ }
+
+
if (sd == NULL) {
Jmsg(jcr, M_FATAL, 0, _("Failed to connect to Storage daemon: %s:%d\n"),
jcr->stored_addr, stored_port);
diff -ru bacula-2.4.4/src/lib/bnet.c bacula-2.4.4-patched/src/lib/bnet.c
--- bacula-2.4.4/src/lib/bnet.c 2008-07-19 11:50:38.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bnet.c 2009-03-17 10:13:04.000000000 -0400
@@ -523,7 +523,7 @@
{
BSOCK *bsock = new_bsock();
if (!bsock->connect(jcr, retry_interval, max_retry_time, heart_beat,
- name, host, service, port, verbose)) {
+ name, host, service, port, verbose, NULL)) {
bsock->destroy();
bsock = NULL;
}
diff -ru bacula-2.4.4/src/lib/bsock.c bacula-2.4.4-patched/src/lib/bsock.c
--- bacula-2.4.4/src/lib/bsock.c 2008-07-19 11:50:38.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bsock.c 2009-03-27 09:54:06.000000000
-0400
@@ -93,7 +93,7 @@
bool BSOCK::connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
utime_t heart_beat,
const char *name, char *host, char *service, int port,
- int verbose)
+ int verbose, dlist *src_addrs)
{
bool ok = false;
int i;
@@ -107,7 +107,7 @@
tid = start_thread_timer(pthread_self(), (uint32_t)max_retry_time);
}
- for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal);
+ for (i = 0; !open(jcr, name, host, service, port, heart_beat, &fatal,
src_addrs);
i -= retry_interval) {
berrno be;
if (fatal || (jcr && job_canceled(jcr))) {
@@ -162,11 +162,11 @@
*
*/
bool BSOCK::open(JCR *jcr, const char *name, char *host, char *service,
- int port, utime_t heart_beat, int *fatal)
+ int port, utime_t heart_beat, int *fatal, dlist *src_addr_list)
{
int sockfd = -1;
dlist *addr_list;
- IPADDR *ipaddr;
+ IPADDR *ipaddr, *src_addr;
bool connected = false;
int turnon = 1;
const char *errstr;
@@ -185,7 +185,7 @@
*fatal = 1;
return false;
}
-
+
foreach_dlist(ipaddr, addr_list) {
ipaddr->set_port_net(htons(port));
char allbuf[256 * 10];
@@ -202,6 +202,18 @@
ipaddr->get_family(), ipaddr->get_port_host_order(),
be.bstrerror());
continue;
}
+
+ if (src_addr_list) {
+ src_addr = (IPADDR *) src_addr_list->first();
+ if (bind(sockfd, src_addr->get_sockaddr(),
src_addr->get_sockaddr_len()) < 0) {
+ berrno be;
+ save_errno = errno;
+ *fatal = 1;
+ Pmsg2(000, _("Source address bind error. proto=%d. ERR=%s\n"),
src_addr->get_family(), be.bstrerror() );
+ continue;
+ }
+ }
+
/*
* Keep socket from timing out from inactivity
*/
diff -ru bacula-2.4.4/src/lib/bsock.h bacula-2.4.4-patched/src/lib/bsock.h
--- bacula-2.4.4/src/lib/bsock.h 2008-07-22 10:48:21.000000000 -0400
+++ bacula-2.4.4-patched/src/lib/bsock.h 2009-03-17 10:12:26.000000000
-0400
@@ -66,7 +66,7 @@
void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int
port,
struct sockaddr *lclient_addr);
bool open(JCR *jcr, const char *name, char *host, char *service,
- int port, utime_t heart_beat, int *fatal);
+ int port, utime_t heart_beat, int *fatal, dlist* srcaddrs);
public:
uint64_t read_seqno; /* read sequence number */
@@ -93,7 +93,7 @@
void free_bsock();
bool connect(JCR * jcr, int retry_interval, utime_t max_retry_time,
utime_t heart_beat, const char *name, char *host,
- char *service, int port, int verbose);
+ char *service, int port, int verbose, dlist *srcaddrs);
int32_t recv();
bool send();
bool fsend(const char*, ...);
------------------------------------------------------------------------------
_______________________________________________
Bacula-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/bacula-devel