allow source IP binding (#12)

* allow source IP binding

* Update README.md

* Update README.md

* Update bindToInterface.c

---------

Co-authored-by: JsBergbau <37013344+JsBergbau@users.noreply.github.com>
This commit is contained in:
Çağrı 2023-10-24 10:45:22 +03:00 committed by GitHub
parent 785b646713
commit d477326d85
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 3 deletions

View File

@ -37,6 +37,14 @@ Especially when using more complex scripts or programs, that use another working
This is the essential part. If not specified program will warn you, however it will not refuse the connection.
### BIND_SOURCE_IP (unreliable / only on some systems)
On some systems you can also set the source IP in case multiple IP addresses are attached to your interface, like this: `BIND_INTERFACE=eth0 BIND_SOURCE_IP=1.2.3.4 LD_PRELOAD...`
**Warning**: It highly depends on which system you are using BIND_SOURCE_IP. Kernel versions 5.10 seem not to work, whereas Kernel 5.15 seems to work, see https://github.com/JsBergbau/BindToInterface/pull/12#issuecomment-1776647513
**Use at your own risk and try if it works on your system**!
### DNS_OVERRIDE_IP
When you have multiple interfaces you normally also have multiple DNS servers. Since your program is bound to specified interface, also DNS traffic has to go through that interface.

View File

@ -9,12 +9,23 @@
#include <arpa/inet.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
//#define DEBUG
//compile with gcc -nostartfiles -fpic -shared bindToInterface.c -o bindToInterface.so -ldl -D_GNU_SOURCE
//Use with BIND_INTERFACE=<network interface> LD_PRELOAD=./bindInterface.so <your program> like curl ifconfig.me
int bind_to_source_ip(int sockfd, const char *source_ip)
{
struct sockaddr_in source_addr;
memset(&source_addr, 0, sizeof(source_addr));
source_addr.sin_family = AF_INET;
source_addr.sin_addr.s_addr = inet_addr(source_ip);
return bind(sockfd, (struct sockaddr *)&source_addr, sizeof(source_addr));
}
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
int *(*original_connect)(int, const struct sockaddr *, socklen_t);
@ -80,6 +91,8 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
char *bind_addr_env;
bind_addr_env = getenv("BIND_INTERFACE");
char *source_ip_env;
source_ip_env = getenv("BIND_SOURCE_IP");
struct ifreq interface;
int errorCode;
@ -118,9 +131,16 @@ int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
};
}
}
else
{
printf("Warning: Programm with LD_PRELOAD startet, but BIND_INTERFACE environment variable not set\n");
if(source_ip_env != NULL && strlen(source_ip_env) > 0){
if (bind_to_source_ip(sockfd, source_ip_env) < 0){
perror("bind_to_source_ip failed");
return -1;
}
}
if(!(source_ip_env != NULL && strlen(source_ip_env) > 0) && !(bind_addr_env != NULL && strlen(bind_addr_env) > 0)){
printf("Warning: Programm with LD_PRELOAD started, but BIND_INTERFACE environment variable not set\n");
fprintf(stderr, "Warning: Programm with LD_PRELOAD startet, but BIND_INTERFACE environment variable not set\n");
}
}