meebey / force_bind Goto Github PK
View Code? Open in Web Editor NEWExperimental library to force socket bind syscalls to use a specific IP address. Use at your own risk!
License: GNU General Public License v3.0
Experimental library to force socket bind syscalls to use a specific IP address. Use at your own risk!
License: GNU General Public License v3.0
Name: force_bind Author: Catali(ux) M. BOIE - catab at embedromix dot ro Start date: 2010-10-26 Description: Force binding on a specific IP and/or port. Works with both IPv4 and IPv6. It is useful if you have a binary application without sources and without the possibility to configure address or port to bind to. License: GPLv3 How it works: force_bind is a shared object that is loaded with LD_PRELOAD and hooks 'bind' function. Forcing an IP/port to bind to is done with environments variables. Examples: 0. Output debug stuff in a log file (for debugging): export FORCE_NET_VERBOSE=999 export FORCE_NET_LOG="xxx.log" your_program_here 1. Force bind to 127.0.0.1, port 33, verbose operations: export FORCE_NET_VERBOSE=1 export FORCE_BIND_ADDRESS_V4=127.0.0.1 export FORCE_BIND_PORT_V4=33 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 2. Force binding to 127.0.0.2, port unchanged export FORCE_BIND_ADDRESS_V4=127.0.0.2 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 3. Force binding to ::1 (IPv6), port unchanged export FORCE_BIND_ADDRESS_V6=::1 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 4. Changing TOS on all sockets to 30 export FORCE_NET_TOS=30 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 5. Force Keep alive to 60 seconds: export FORCE_NET_KA=60 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 6. Force MSS to 1400 export FORCE_NET_MSS=1400 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 7. Force bandwidth to 1000 bytes/s for _all_ connections, cumulated export FORCE_NET_BW=1000 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 8. Force bandwidth to 20000 bytes/s per socket export FORCE_NET_BW_PER_SOCKET=20000 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so scp root@machine1:/image.iso . 9. Force REUSEADDR export FORCE_NET_REUSEADDR=1 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 10. Force NODELAY export FORCE_NET_NODELAY=1 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 11. Force client connections (for example 'telnet', 'ssh', 'firefox') to connect from a specified address, not the auto selected one: export FORCE_NET_VERBOSE=1 export FORCE_BIND_ADDRESS_V4=127.0.0.2 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 12. Set a FLOWINFO (flow label + class) for a client connection: export FORCE_NET_VERBOSE=1 export FORCE_NET_FLOWINFO=0x7812345 # class 0x78, label 0x12345 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here A tcpdump of a connection will look like: 00:00:00:00:00:00 > 00:00:00:00:00:00, ethertype IPv6 (0x86dd), length 94: (class 0x78, flowlabel 0x12345, hlim 64, next-header TCP (6) payload length: 40) ::1.56981 > ::1.krb524: Flags [S], cksum 0x0030 (incorrect -> 0x91cf), seq 1154252590, win 32752, options [mss 16376,sackOK,TS val 28395104 ecr 0,nop,wscale 4], length 0 13. Force FWMARK on a connection (only root is allowed): export FORCE_NET_VERBOSE=1 export FORCE_NET_FWMARK=0x1234 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 14: Force priority (between 0 and 6 for non-root users). You can use 'tc' command from iproute to set-up 'prio' qdisc and to assign prio to queues: # 0. setup export FORCE_NET_VERBOSE=1 export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so # 1. Make sure you have a 'prio' qdisc attached to eth0, for example: tc qdisc add ev eth0 root handle 1: prio # 2. Assign applications to classed (bands): export FORCE_NET_PRIO=6 # interactive, band 0 your_voip_program_here export FORCE_NET_PRIO=0 # best effort, band 1 your_mail_program_here export FORCE_NET_PRIO=2 # bulk, band 2 your_remote_backup_program_here # 3. Run tc statistics so you can see the classification: tc -s class show dev eth0 15: Deny binding to any IPv4 sockets. The bind syscall will return -1 and errno will be set to EACCES. export FORCE_NET_VERBOSE=1 export FORCE_BIND_ADDRESS_V4=deny export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here 16: Silent fake binding to any IPv6 sockets. The bind will return success, but will never accept any connection. export FORCE_NET_VERBOSE=1 export FORCE_BIND_ADDRESS_V6=fake export LD_PRELOAD=${LD_PRELOAD}:/usr/lib/force_bind.so your_program_here Installation: - ./configure - make - make install
Hi,
I have some segfaults when using some basic commands (less, man, cat), while having force_bind.so in LD_PRELOAD.
This produces segfault :
user@host:~$ cd /tmp/
user@host:/tmp$ export LD_PRELOAD=force_bind.so:
user@host:/tmp$ touch foo
user@host:/tmp$ less foo
Segmentation fault
user@host:/tmp$
Here is an strace when running less foo
:
execve("/usr/bin/less", ["less", "foo"], [/* 19 vars */]) = 0
brk(0) = 0xad6000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a57000
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=21754, ...}) = 0
mmap(NULL, 21754, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4c31a51000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/tls/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/tls/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/tls", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
open("/usr/lib/x86_64-linux-gnu/tls/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64-linux-gnu/tls/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/tls", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64-linux-gnu/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64-linux-gnu/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
open("/lib/tls/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/tls/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/tls/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/tls", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/lib/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
open("/usr/lib/tls/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/tls/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/tls", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/x86_64/force_bind.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat("/usr/lib/x86_64", 0x7fff7b7724b0) = -1 ENOENT (No such file or directory)
open("/usr/lib/force_bind.so", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\16\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|S_ISUID|S_ISGID|0755, st_size=127107, ...}) = 0
mmap(NULL, 2116864, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4c31635000
mprotect(0x7f4c3163a000, 2093056, PROT_NONE) = 0
mmap(0x7f4c31839000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x4000) = 0x7f4c31839000
close(3) = 0
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libtinfo.so.5", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\323\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=167952, ...}) = 0
mmap(NULL, 2264608, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4c3140c000
mprotect(0x7f4c31431000, 2093056, PROT_NONE) = 0
mmap(0x7f4c31630000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24000) = 0x7f4c31630000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\357\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1595408, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a50000
mmap(NULL, 3709016, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4c31082000
mprotect(0x7f4c31202000, 2097152, PROT_NONE) = 0
mmap(0x7f4c31402000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x180000) = 0x7f4c31402000
mmap(0x7f4c31407000, 18520, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f4c31407000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY) = 3
read(3, "\177ELF\2\1\1\0\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\340\r\0\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0644, st_size=14768, ...}) = 0
mmap(NULL, 2109696, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f4c30e7e000
mprotect(0x7f4c30e80000, 2097152, PROT_NONE) = 0
mmap(0x7f4c31080000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x2000) = 0x7f4c31080000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a4f000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a4e000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a4d000
arch_prctl(ARCH_SET_FS, 0x7f4c31a4e700) = 0
mprotect(0x7f4c31080000, 4096, PROT_READ) = 0
mprotect(0x7f4c31402000, 16384, PROT_READ) = 0
mprotect(0x7f4c31630000, 16384, PROT_READ) = 0
mprotect(0x620000, 4096, PROT_READ) = 0
mprotect(0x7f4c31a59000, 4096, PROT_READ) = 0
munmap(0x7f4c31a51000, 21754) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
brk(0) = 0xad6000
brk(0xaf7000) = 0xaf7000
stat("/home/nicolas/.terminfo", 0x7fff7b771290) = -1 ENOENT (No such file or directory)
stat("/etc/terminfo", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access("/etc/terminfo/x/xterm", R_OK) = -1 ENOENT (No such file or directory)
stat("/lib/terminfo", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
access("/lib/terminfo/x/xterm", R_OK) = 0
open("/lib/terminfo/x/xterm", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=3315, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a56000
read(3, "\32\1)\0&\0\17\0\235\1Z\5xterm|xterm-debian|X"..., 4096) = 3315
read(3, "", 4096) = 0
close(3) = 0
munmap(0x7f4c31a56000, 4096) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(1, TIOCGWINSZ, {ws_row=72, ws_col=270, ws_xpixel=0, ws_ypixel=0}) = 0
ioctl(2, TIOCGWINSZ, {ws_row=72, ws_col=270, ws_xpixel=0, ws_ypixel=0}) = 0
open("/usr/bin/.sysless", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/sysless", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/home/nicolas/.less", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/locale-archive", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=2031648, ...}) = 0
mmap(NULL, 2031648, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f4c3185c000
close(3) = 0
open("/home/nicolas/.lesshst", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0600, st_size=277, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f4c31a56000
read(3, ".less-history-file:\n.search\n\"log"..., 4096) = 277
read(3, "", 4096) = 0
close(3) = 0
munmap(0x7f4c31a56000, 4096) = 0
open("/dev/tty", O_RDONLY) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
fsync(3) = -1 EINVAL (Invalid argument)
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
ioctl(3, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig -icanon -echo ...}) = 0
rt_sigaction(SIGINT, {0x414760, [INT], SA_RESTORER|SA_RESTART, 0x7f4c310b44f0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGTSTP, {0x4146e0, [TSTP], SA_RESTORER|SA_RESTART, 0x7f4c310b44f0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGWINCH, {0x414720, [WINCH], SA_RESTORER|SA_RESTART, 0x7f4c310b44f0}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGQUIT, {SIG_IGN, [QUIT], SA_RESTORER|SA_RESTART, 0x7f4c310b44f0}, {SIG_DFL, [], 0}, 8) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
open("foo", O_RDONLY) = 4
lseek(4, 1, SEEK_SET) = 1
lseek(4, 0, SEEK_SET) = 0
read(4, "", 256) = 0
lseek(4, 1, SEEK_SET) = 1
fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lseek(4, 0, SEEK_SET) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
Segmentation fault
Force bind is compiled from latest git, on a machine running Debian Wheezy amd64.
Regards,
N-Mi.
I am trying to run here with firefox/chromium browser @ Ubuntu 16.04 but after compile and try to run the first time I only got this message:
LD_PRELOAD="${LD_PRELOAD}:./force_bind.so"
export FORCE_BIND_ADDRESS_V6=2001:xxxx
firefox
/bin/sh: symbol lookup error: ./force_bind.so: undefined symbol: dlsym
Any idea/suggestion ?
Hi,
I don't know if you still maintain this code, but in doubt I fill this issue here.
I just compiled and installed force_bind from latest git, and could successfully use telnet and ping (after setuid the .so file).
I then tried to do some snmpget/snmpwalk on an equipment, and this doesn't work, while telnet and ping use the bind address configured in force_bind variables.
I checked with tcpdump and can observe that outgoing traffic for snmp requests are sourced with default interface IP, instead of the one declared in FORCE_BIND_ADDRESS_V4.
Here is the content of log file using verbose level 999 :
Init started...
Version: 0.11
Force bind to IPv4 address "172.21.17.38".
Init ended.
close(fd=3)
del(fd=3)
list...
socket(domain=IPv4, type=dgram, protocol=0)
socket_create_callback(3, IPv4, dgram)
add(fd=3, ...)
list...
fd= 3 type=dgram flags=0001 limit=0 rest=0 last=0.000000 dest=0/?/?
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
alter_sa(sockfd=3, ...)
bw(sockfd=3, bytes=45)
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
bw(sockfd=3, bytes=45)
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
bw(sockfd=3, bytes=45)
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
bw(sockfd=3, bytes=45)
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
bw(sockfd=3, bytes=45)
sendmsg(sockfd=3, ..., flags=0x4040)
change_local_binding(sockfd=3)
bw(sockfd=3, bytes=45)
close(fd=3)
del(fd=3)
list...
We can see in this trace that force_bind is loaded, and tries to bind on given address, but traffic is actually sent with another address.
I had the same behaviour trying to perform a DNS request using nslookup, so I believe the problem is with UDP in general.
Regard,
N-Mi.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.