shd-tcp-tools ============= Author: Heikki Orsila Project web page: http://zakalwe.fi/~shd/foss/shd-tcp-tools/ Introduction ============ shd-tcp-tools are miscellaneous tools that operate with IPv4 and IPv6 networks with TCP protocol. These tools can be used to TCP port forwarding, network load balancing, network rate limiting, and running servers behind firewalls. The tools are called tcppipe, tcppipe-least, tcp-pf, listentwo, and connecttwo. Environment variables ===================== If environment variable INADDR_DEFAULT is set, each tool will bind incoming and outgoing sockets to that address. tcppipe usage ============= tcppipe [-b file] [-i secs] [--insert file] [-l rate] [-n file] [-p] [-w x] SOURCE DESTINATION tcppipe creates one-directional pipe using TCP. There are two operating modes. The tool moves data from one source to one destination. Both source and destination can be selected from following alternatives: '-' means stdin for SOURCE and stdout for DESTINATION 'host port' means network host and its port. The host can be just '.' and in that case host is selected from a host file given with -n. ':port' means listening socket on a port Both SOURCE and DESTINATION may not be sockets. Thus this tool can be used in a similar way as netcat, but only one-directional traffic is possible. OPTIONS: -b/--bind-file file Select local socket address (interface) from a bind host file. The interface with least amount of transfered bytes is selected. -h Print help --insert file Insert prefix data to the destination connection -l/--limit rate Limit network throughput to a maximum number of bytes per second. -i secs Set host file update interval in seconds. Default 512s. -n/--network-file file Select network host from a network host file. The host with least amount of transfered bytes is selected. -p Print network throughput -v/--version Print version information. -w x Wait x seconds before connecting incoming connection to the destination address. This could be used to slow port scanners. The host file has the following format: ip_1 byte_number_1 ip_2 byte_number_2 The byte amounts are handled with 64 bits internally so they won't overflow. Example 1: If the host file (~/.stt/default) contains: 10.0.0.1 1024 10.0.0.2 512 then tar cv *files* |tcppipe -b ~/.stt/default - targethost targetport sends a tar stream to the targethost:targetport. The local interfaced used is the interface with least amount of recorded transfers, which is 10.0.0.2 in this example. Example 2: Listens to tcp port 1234 (:1234), accepts any incoming connection, limits the network throughput to 100 KiB/s (-l), prints the network throughput (-p), and untars the incoming stream. tcppipe -p -l 102400 :1234 - |tar xv Example 3: Bind to port 2345 on an interface with least amount of transfers. And direct incoming TCP connection to stdout. tcppipe -b file :2345 - Example 5: Send some files to the host with least amount of transfers and limit rate to 100 KiB/s. tar cv *FILES* |tcppipe -n hostfile -l 102400 - . port tcppipe-least usage =================== tcppipe-least is a tool to manipulate and read host files (that contain byte amounts for hosts). It is useful for shell scripting. Read the command line help for more info: tcppipe-least -h tcp-pf usage ============ tcp-pf -s port1 [-d host:port2] [-l multiplexfile -p port2] [--lazy] [-a allowed_host] [-r rate] [--insert file] tcp-pf creates a full-duplex relay pipe between two hosts. First it waits for an incoming connection to port1, and then connects to host2:port2. Finally it sets up a full duplex tcp pipe between the two hosts. Alternatively a target host is read from a host file which lists many potential target hosts. The host with least amount of bytes in history is selected. This can be used for network load balancing when a same service is running on every host in the host file. The format of the host file is the same as with tcppipe tool. Here is an example: # file starts host1.mydomain.com 1000000000 host2.mydomain.com 0 The byte amounts are handled internally with 64 bit counters so they won't overflow. In this example, host2.mydomain.com would be chosen as the target, because it has the least amount of bytes (zero) in recorded history. Environment variable INADDR_DEFAULT can be used to bind listening port to any local interface. For example: export INADDR_DEFAULT="host3.mydomain.com" tcp-pf -s 1234 -d foo.org:2345 tcp-pf binds itself to host3.mydomain.com:1234. -a switch can be used to add 'allowed hosts' that are allowed to connect to the listening socket. For example: tcp-pf -s 1234 -a myfriend.org -d goes.here.org:2345 -r switch may be used to limit the maximum number of bytes per second going through each connection. --lazy can be used to simulate lazy connection killing like in netcat. Normally connections to both ends are killed when either source disconnects from tcp-pf. With --lazy tcp-pf doesn't close the remaining connection before a broken pipe condition is noticed on new data. --insert file is used in the same way as in tcppipe tool. To prefix a destination data connection with constant data. tcp-pf prints the data bandwidth in both directions according to IEC 60027-2 (2000-11) Ed. 2.0 symbols. KiB == 2^10 bytes, MiB == 2^20 bytes, GiB == 2^30 bytes, TiB == 2^40 bytes. listentwo/connecttwo usage ========================== listentwo and connecttwo tools can be used to run servers behind firewalled networks by using a third party non-firewalled host. Assume: - machine A is firewalled so that it can't accept incoming connections to port 22 (ssh). - machine B is not firewalled. - machine C wants to connect to ssh port of machine A. Host name of machine B is machine_b. Do this: First on machine B: listentwo -s 1234 -d 1235 --hello-dst Then on machine A: connecttwo -s machine_b:1235 -d 127.0.0.1:22 --hello-from-src Then C can use ssh: ssh -p 1234 user@machine_b What happens when C uses ssh is: B accepts the connection on port 1234 from machine C (process listentwo). Meanwhile listentwo has got a connection to port 1235 from machine A or not. If not then it waits for connection to port 1235 from machine A. When there is a connection on port 1235, the ip/port of machine C is informed to the client connecting from machine A. When machine A has received the ip/port of machine C from machine B, it connects to localhost:22 discarding the ip/port information it got. Then the data starts to flow. There is no particular reason why machine A should know the ip of machine C connecting to B. Without --hello-* that information is not relayed to machine A.