Technical Knowledgebase (unsorted)


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

rinetd new feature patch: bind to specific local sockets for new connection, fixes multihomed host problems



Hi,

this is annouce and request for comments for a new feature in
rinetd. I think this is a small but important and useful feature.

rinetd relays TCP connections. It's possible to specify local
address to listen for and to specify which host should get
connected. My patch adds the possibility to specify the local
address (bind address) used for the initiated connection. This
version should be fully compatible with the old one, so it's a
drop-in replacement.

Since this is a small package, I'll attach the source RPM based
on the SuSE 7.0 RPM (Version: 0.61 Release: 156). I changed the
SPEC file to include the patch, added a change note, incremented
the Release Number and changed Version to 0.61b.

All changes in the sources are marked with "#ifdef BINDCONN". The
patch file rinetd.BINDCONN.dif gives more details ;). The man
pages and CHANGELOG has been updated. I put a README.BINDCONN in
the Source directory, too.

This is very useful for multihomed hosts or hosts which have
alias addresses. Per default the kernel would use the first
address of the nearest interface always, but now it's possible to
change this behavoir. Firewall and VPN setups get more simple.

Please note, that I tested this version under linux but not with
windows.

I would like to hear if you could integrate this feature in the
main branch of software, since I think any people would like it
too. I hope the next release could integrate this patch.

Please mail me!

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.
diff -Nur ../rinetd.dist/CHANGES ./CHANGES
--- ../rinetd.dist/CHANGES	Mon Mar  1 19:43:24 1999
+++ ./CHANGES	Sat Jun  2 19:03:14 2001
@@ -46,3 +46,7 @@
 Version 0.61: fixed a bug in 0.6 which completely
 broke rinetd under Linux. Oops.
 
+Version 0.61b: BIND CONN version. New option to specify
+local address and port for the connections that are made
+to the target (source address and port for the connections)
+to fix multihomed host problems.
diff -Nur ../rinetd.dist/Makefile ./Makefile
--- ../rinetd.dist/Makefile	Mon Mar  1 19:41:50 1999
+++ ./Makefile	Sat Jun  2 18:51:12 2001
@@ -1,4 +1,5 @@
 CFLAGS=-DLINUX -g
+CFLAGS+=-Wall -DBINDCONN
 
 rinetd: rinetd.o match.o
 	gcc rinetd.o match.o -o rinetd
@@ -7,3 +8,5 @@
 	install -m 700 rinetd /usr/sbin
 	install -m 644 rinetd.8 /usr/man/man8
 
+tags:
+	ctags *.c *.h
diff -Nur ../rinetd.dist/README.BINDCONN ./README.BINDCONN
--- ../rinetd.dist/README.BINDCONN	Thu Jan  1 01:00:00 1970
+++ ./README.BINDCONN	Sat Jun  2 18:33:24 2001
@@ -0,0 +1,15 @@
+BINDCONN patch: bind connections local too
+
+Steffen Dettmer <steffen@dett.de> Sam Jun  2 18:20:47 MEST 2001
+
+This version allows to specify the local bind address 
+which is used as source for connections. This fixes some
+strange multi host problems. Usually it's not needed, but
+when working with VPNs or other non-trivial setups this
+feature may be neccesary. This feature works fine for alias
+addresses, too.
+
+The changes are active only if compiled with -DBINDCONN.
+
+If you have any questions, mail me.
+
diff -Nur ../rinetd.dist/rinetd.8 ./rinetd.8
--- ../rinetd.dist/rinetd.8	Sat Jun  2 16:37:03 2001
+++ ./rinetd.8	Sat Jun  2 19:02:57 2001
@@ -12,7 +12,7 @@
 .Sh SYNOPSIS
 .Nm /usr/sbin/rinetd
 .Sh VERSION
-Version 0.61, 3/1/1999.
+Version 0.61b, 6/2/2001.
 .Sh DESCRIPTION
 .Nm rinetd
 redirects TCP connections from one IP address and port to another. rinetd
@@ -34,7 +34,7 @@
 Most entries in the configuration file are forwarding rules. The
 format of a forwarding rule is as follows:
 .Pp
-bindaddress bindport connectaddress connectport
+bindaddress bindport connectaddress connectport [localaddress] [localport]
 .Pp
 For example:
 .Pp
@@ -64,6 +64,24 @@
 Both IP addresses and hostnames are accepted for
 bindaddress and connectaddress.
 .Pp
+If localaddress is specified, this address is used as source of
+the new connections. This fixes multihomed host problems. Per default,
+the kernel uses the nearest address as source for the connection.
+This can made firewall setups more complex and may generate
+problems when working with IPSec VPN tunnels. For example:
+.Pp
+10.1.1.1 23 10.1.2.2 23 10.1.1.1
+.Pp
+10.1.1.1 is a multihomed host which has additionally the IP
+10.1.2.1. In this case, the initiated connection would use that
+IP as source. By specifying 10.1.1.1, this local address is used
+as source. This feature works fine for alias addresses, too.
+.Pp
+You may specify localport too, but this will
+work well for the first connection only. After a timeout it's
+possible to made a second connection, but only one at a
+time.
+.Pp
 .Sh ALLOW AND DENY RULES
 Configuration files can also contain allow and deny rules. 
 .Pp
@@ -210,6 +228,10 @@
 .Sh CONTACT INFORMATION
 See http://www.boutell.com/rinetd/ for the latest release.
 Thomas Boutell can be reached by email: boutell@boutell.com
+.Sh
+This version is modified by Steffen Dettmer <steffen@dett.de> to
+allow the user to specify the source address which is used for
+new connections, too.
 .Sh THANKS
 Thanks are due to Bill Davidsen, Libor Pechachek, Sascha Ziemann, the
 Apache Group, and many others who have contributed advice
diff -Nur ../rinetd.dist/rinetd.BINDCONN.dif ./rinetd.BINDCONN.dif
--- ../rinetd.dist/rinetd.BINDCONN.dif	Thu Jan  1 01:00:00 1970
+++ ./rinetd.BINDCONN.dif	Sat Jun  2 19:16:59 2001
@@ -0,0 +1,102 @@
+diff -Nur ../rinetd.dist/CHANGES ./CHANGES
+--- ../rinetd.dist/CHANGES	Mon Mar  1 19:43:24 1999
++++ ./CHANGES	Sat Jun  2 19:03:14 2001
+@@ -46,3 +46,7 @@
+ Version 0.61: fixed a bug in 0.6 which completely
+ broke rinetd under Linux. Oops.
+ 
++Version 0.61b: BIND CONN version. New option to specify
++local address and port for the connections that are made
++to the target (source address and port for the connections)
++to fix multihomed host problems.
+diff -Nur ../rinetd.dist/Makefile ./Makefile
+--- ../rinetd.dist/Makefile	Mon Mar  1 19:41:50 1999
++++ ./Makefile	Sat Jun  2 18:51:12 2001
+@@ -1,4 +1,5 @@
+ CFLAGS=-DLINUX -g
++CFLAGS+=-Wall -DBINDCONN
+ 
+ rinetd: rinetd.o match.o
+ 	gcc rinetd.o match.o -o rinetd
+@@ -7,3 +8,5 @@
+ 	install -m 700 rinetd /usr/sbin
+ 	install -m 644 rinetd.8 /usr/man/man8
+ 
++tags:
++	ctags *.c *.h
+diff -Nur ../rinetd.dist/README.BINDCONN ./README.BINDCONN
+--- ../rinetd.dist/README.BINDCONN	Thu Jan  1 01:00:00 1970
++++ ./README.BINDCONN	Sat Jun  2 18:33:24 2001
+@@ -0,0 +1,15 @@
++BINDCONN patch: bind connections local too
++
++Steffen Dettmer <steffen@dett.de> Sam Jun  2 18:20:47 MEST 2001
++
++This version allows to specify the local bind address 
++which is used as source for connections. This fixes some
++strange multi host problems. Usually it's not needed, but
++when working with VPNs or other non-trivial setups this
++feature may be neccesary. This feature works fine for alias
++addresses, too.
++
++The changes are active only if compiled with -DBINDCONN.
++
++If you have any questions, mail me.
++
+diff -Nur ../rinetd.dist/rinetd.8 ./rinetd.8
+--- ../rinetd.dist/rinetd.8	Sat Jun  2 16:37:03 2001
++++ ./rinetd.8	Sat Jun  2 19:02:57 2001
+@@ -12,7 +12,7 @@
+ .Sh SYNOPSIS
+ .Nm /usr/sbin/rinetd
+ .Sh VERSION
+-Version 0.61, 3/1/1999.
++Version 0.61b, 6/2/2001.
+ .Sh DESCRIPTION
+ .Nm rinetd
+ redirects TCP connections from one IP address and port to another. rinetd
+@@ -34,7 +34,7 @@
+ Most entries in the configuration file are forwarding rules. The
+ format of a forwarding rule is as follows:
+ .Pp
+-bindaddress bindport connectaddress connectport
++bindaddress bindport connectaddress connectport [localaddress] [localport]
+ .Pp
+ For example:
+ .Pp
+@@ -64,6 +64,24 @@
+ Both IP addresses and hostnames are accepted for
+ bindaddress and connectaddress.
+ .Pp
++If localaddress is specified, this address is used as source of
++the new connections. This fixes multihomed host problems. Per default,
++the kernel uses the nearest address as source for the connection.
++This can made firewall setups more complex and may generate
++problems when working with IPSec VPN tunnels. For example:
++.Pp
++10.1.1.1 23 10.1.2.2 23 10.1.1.1
++.Pp
++10.1.1.1 is a multihomed host which has additionally the IP
++10.1.2.1. In this case, the initiated connection would use that
++IP as source. By specifying 10.1.1.1, this local address is used
++as source. This feature works fine for alias addresses, too.
++.Pp
++You may specify localport too, but this will
++work well for the first connection only. After a timeout it's
++possible to made a second connection, but only one at a
++time.
++.Pp
+ .Sh ALLOW AND DENY RULES
+ Configuration files can also contain allow and deny rules. 
+ .Pp
+@@ -210,6 +228,10 @@
+ .Sh CONTACT INFORMATION
+ See http://www.boutell.com/rinetd/ for the latest release.
+ Thomas Boutell can be reached by email: boutell@boutell.com
++.Sh
++This version is modified by Steffen Dettmer <steffen@dett.de> to
++allow the user to specify the source address which is used for
++new connections, too.
+ .Sh THANKS
+ Thanks are due to Bill Davidsen, Libor Pechachek, Sascha Ziemann, the
+ Apache Group, and many others who have contributed advice
diff -Nur ../rinetd.dist/rinetd.c ./rinetd.c
--- ../rinetd.dist/rinetd.c	Sat Jun  2 19:16:39 2001
+++ ./rinetd.c	Sat Jun  2 19:11:20 2001
@@ -1,4 +1,4 @@
-#define VERSION "0.61"
+#define VERSION "0.61b" /* BINDCONN by Steffen Dettmer <steffen@dett.de> */
 
 #ifdef WIN32
 #include <windows.h>
@@ -7,7 +7,8 @@
 #else
 #include <sys/types.h>
 #include <sys/socket.h>
-#include <sys/ioctl.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <getopt.h>
@@ -27,6 +28,7 @@
 #include <fcntl.h>
 #include <time.h>
 #include <ctype.h>
+#include <unistd.h>
 
 #ifndef WIN32
 /* Windows sockets compatibility defines */
@@ -101,6 +103,10 @@
 /* In network order, for network purposes */
 struct in_addr *seLocalAddrs = 0;
 unsigned short *seLocalPorts = 0;
+#ifdef BINDCONN
+struct in_addr *seLocalBindAddrs = 0;
+unsigned short *seLocalBindPorts = 0;
+#endif /* BINDCONN */
 /* In ASCII and local byte order, for logging purposes */
 char **seFromHosts;
 int *seFromPorts;
@@ -326,6 +332,10 @@
 		free(seFds);
 		free(seLocalAddrs);
 		free(seLocalPorts);
+#ifdef BINDCONN
+		free(seLocalBindAddrs);
+		free(seLocalBindPorts);
+#endif /* BINDCONN */
 		free(seFromHosts);
 		free(seFromPorts);
 		free(seToHosts);
@@ -422,6 +432,18 @@
 	if (!seLocalPorts) {
 		goto lowMemory;
 	}
+#ifdef BINDCONN    
+	seLocalBindAddrs = (struct in_addr *) malloc(sizeof(struct in_addr) *
+		seTotal);	
+	if (!seLocalBindAddrs) {
+		goto lowMemory;
+	}
+	seLocalBindPorts = (unsigned short *) 
+		malloc(sizeof(unsigned short) * seTotal);	
+	if (!seLocalBindPorts) {
+		goto lowMemory;
+	}
+#endif /* BINDCONN */    
 	seFromHosts = (char **)
 		malloc(sizeof(char *) * seTotal);
 	if (!seFromHosts) {
@@ -491,8 +513,12 @@
 		char *connectAddress;
 		char *bindPortS;
 		char *connectPortS;
-		unsigned short connectPort;
-		struct in_addr iaddr;
+#ifdef BINDCONN            
+                char *bindConnAddr; /* local bind addr for connect */
+                char *bindConnPortS; /* local bind addr for connect */
+#endif /* BINDCONN */
+		unsigned short connectPort, connectBindPort;
+		struct in_addr iaddr, iBindAddr;
 		struct sockaddr_in saddr;
 		struct servent *service;
 		int j;
@@ -690,6 +716,18 @@
 					"specified on line %d.\n", lnum);	
 				continue;
 			}
+#ifdef BINDCONN            
+			bindConnAddr = strtok(0, " \t\r\n");
+			if (!bindConnAddr) {
+                                bindConnAddr = "0.0.0.0";
+                                /* no error */
+			}
+			bindConnPortS = strtok(0, " \t\r\n");
+			if (!bindConnPortS) {
+                                bindConnPortS = "0";
+				/* no error */
+			}
+#endif /* BINDCONN */
 			service = getservbyname(connectPortS, "tcp");	
 			if (service) {
 				connectPort = ntohs(service->s_port);
@@ -701,6 +739,19 @@
 					"or out of range on line %d.\n", lnum);
 				continue;
 			}
+#ifdef BINDCONN            
+			service = getservbyname(bindConnPortS, "tcp");	
+			if (service) {
+				connectBindPort = ntohs(service->s_port);
+			} else {
+				connectBindPort = atoi(bindConnPortS);
+			}
+			if (connectBindPort >= 65536) {
+				fprintf(stderr, "rinetd: bind conn port missing "
+					"or out of range on line %d.\n", lnum);
+				continue;
+			}
+#endif /* BINDCONN */
 			/* Turn all of this stuff into reasonable addresses */
 			if (!getAddress(bindAddress, &iaddr)) {
 				fprintf(stderr, "rinetd: host %s could not be "
@@ -708,6 +759,18 @@
 					bindAddress, lnum);
 				continue;
 			}	
+#ifdef BINDCONN            
+			if (!getAddress(bindConnAddr, &iBindAddr)) {
+				fprintf(stderr, "rinetd: (local) host %s could not be "
+					"resolved on line %d.\n", 
+					bindAddress, lnum);
+				continue;
+			}	
+#ifdef DEBUG               
+			fprintf(stderr, "local: %s:%d\n",
+				inet_ntoa(iBindAddr), connectBindPort);
+#endif /* DEBUG */
+#endif /* BINDCONN */
 			/* Make a server socket */
 			seFds[i] = socket(PF_INET, SOCK_STREAM, 0);
 			if (seFds[i] == INVALID_SOCKET) {
@@ -759,6 +822,10 @@
 			}	
 			seLocalAddrs[i] = iaddr;
 			seLocalPorts[i] = htons(connectPort);
+#ifdef BINDCONN            
+			seLocalBindAddrs[i] = iBindAddr;
+			seLocalBindPorts[i] = htons(connectBindPort);
+#endif /* BINDCONN */            
 			seFromHosts[i] = malloc(strlen(bindAddress) + 1);
 			if (!seFromHosts[i]) {
 				goto lowMemory;
@@ -1390,8 +1457,23 @@
 #endif /* WIN32 */
 	/* Bind the local socket */
 	saddr.sin_family = AF_INET;
+#ifdef BINDCONN
+    /* bind to specified addr */
+	saddr.sin_port = INADDR_ANY;
+        memcpy(&saddr.sin_addr, &seLocalBindAddrs[se], sizeof(struct in_addr));
+   	saddr.sin_port = seLocalBindPorts[se];
+        if (saddr.sin_port != 0) {
+                j = 1;
+	        setsockopt(loFds[i], SOL_SOCKET, SO_REUSEADDR, &j, sizeof(j));
+        }
+#ifdef DEBUG        
+        fprintf(stderr, "bind local on %s:%d\n",
+            inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));
+#endif /* DEBUG */        
+#else  /* not BINDCONN */
 	saddr.sin_port = INADDR_ANY;
 	saddr.sin_addr.s_addr = 0;
+#endif /* not BINDCONN */
 	if (bind(loFds[i], (struct sockaddr *) &saddr, sizeof(saddr)) == SOCKET_ERROR) {
 		closesocket(loFds[i]);
 		closesocket(reFds[i]);
Binary files ../rinetd.dist/rinetd.o and ./rinetd.o differ
BINDCONN patch: bind connections local too

Steffen Dettmer <steffen@dett.de> Sam Jun  2 18:20:47 MEST 2001

This version allows to specify the local bind address 
which is used as source for connections. This fixes some
strange multi host problems. Usually it's not needed, but
when working with VPNs or other non-trivial setups this
feature may be neccesary. This feature works fine for alias
addresses, too.

The changes are active only if compiled with -DBINDCONN.

If you have any questions, mail me.

#
# spec file for package rinetd (Version 0.61)
# 
# Copyright  (c)  2000  SuSE GmbH  Nuernberg, Germany.
#
# please send bugfixes or comments to feedback@suse.de.
#

# neededforbuild 
# usedforbuild    aaa_base aaa_dir autoconf automake base bash bindutil binutils bison bzip compress cpio cracklib devs diff ext2fs file fileutil find flex gawk gcc gdbm gettext gpm gppshare groff gzip kbd less libc libtool libz lx_suse make mktemp modules ncurses net_tool netcfg nkita nkitb nssv1 pam patch perl pgp ps rcs rpm sendmail sh_utils shadow shlibs strace syslogd sysvinit texinfo textutil timezone unzip util vim xdevel xf86 xshared

Vendor:       SuSE GmbH, Nuernberg, Germany
Distribution: SuSE Linux 7.0 (i386)
Name:         rinetd
Release:      157
Packager:     feedback@suse.de

Copyright:    GPL
Group:        Networking/Daemons
Provides:     rinetd 
Autoreqprov:  on
Version:      0.61b
Summary:      TCP redirection server
URL:          http://www.boutell.com/rinetd/
Source:       ftp://ftp.boutell.com/pub/boutell/rinetd/rinetd.tar.gz
Patch0:  rinetd.dif
Patch1:  rinetd.BINDCONN.dif

%description
rinetd redirects TCP connections from one IP address and port to another.
rinetd is a single-process server which handles any number of connections
to the address/port pairs specified in the file /etc/rinetd.conf.
Since rinetd runs as a single process using nonblocking I/O, it is able
to redirect a large number of connections without a severe impact on
the machine. This makes it practical to run TCP services on machines
inside an IP masquerading firewall.
Note: rinetd can not redirect FTP, because FTP requires more than one socket.

Authors:
--------
    Thomas Boutell <boutell@boutell.com>

SuSE series: n

%prep
%setup -n rinetd
%patch0
%patch1

%build
make

%install
install -m 700 rinetd /usr/sbin
install -m 644 rinetd.8 %{_mandir}/man8
install -m 755 rc.rinetd /sbin/init.d/rinetd
ln -s ../rinetd /sbin/init.d/rc2.d/S20rinetd
ln -s ../rinetd /sbin/init.d/rc2.d/K10rinetd
ln -s ../rinetd /sbin/init.d/rc3.d/S20rinetd
ln -s ../rinetd /sbin/init.d/rc3.d/K10rinetd
ln -s ./init.d/rinetd /sbin/rcrinetd
install -m 644 rc.config.rinetd /var/adm/fillup-templates/rc.config.rinetd
%{?suse_check}

%post 
echo "Updating etc/rc.config..."
if [ -x bin/fillup ] ; then
  bin/fillup -q -d = etc/rc.config var/adm/fillup-templates/rc.config.rinetd
else
  echo "ERROR: fillup not found. This should not happen. Please compare"
  echo "etc/rc.config and etc/rc.config.rinetd and update by hand."
fi

%files
%doc CHANGES README index.html rinetd.conf.sample 
%doc %{_mandir}/man8/rinetd.8.gz
/sbin/rcrinetd
/sbin/init.d/rc2.d/K10rinetd
/sbin/init.d/rc2.d/S20rinetd
/sbin/init.d/rc3.d/K10rinetd
/sbin/init.d/rc3.d/S20rinetd
/sbin/init.d/rinetd
/usr/sbin/rinetd
/var/adm/fillup-templates/rc.config.rinetd

%changelog -n rinetd
* Sat Jun  2 2001 - steffen@dett.de
- added BINDCONN patch to fix multi-homed host problems
* Thu Feb 17 2000 - grimmer@suse.de
- added patch from kus@suse.de to enable logging via syslog
- added Group tag
- added URL
- use manpage macro
* Mon Sep 13 1999 - bs@suse.de
- ran old prepare_spec on spec file to switch to new prepare_spec.
* Mon May 31 1999 - grimmer@suse.de
- update to 0.61
* Tue Mar 02 1999 - grimmer@suse.de
- new version
- specfile update
* Tue Nov 10 1998 - grimmer@suse.de
- new version (0.52)
- new init script (for 6.0)
* Mon Oct 05 1998 - grimmer@suse.de
- New Package (version 0.51)

rinetd-0.61b-157.src.rpm