Wie kann die Reichweite von zufälligen Port-Sockets begrenzt werden?

7

Es gibt eine Binärdatei, die ich ausführen muss und die bindmit einem Port-Argument von Null verwendet wird, um einen zufälligen freien Port vom System zu erhalten. Gibt es eine Möglichkeit, den Bereich der Ports einzuschränken, aus denen der Kernel auswählen darf?

Délisson Junio
quelle

Antworten:

4

Wenn Sie die Art und Weise ändern möchten, in der eine Binärdatei ausgeführt wird, ohne Zugriff auf ihre Quellen zu haben, können Sie manchmal einen Shim verwenden, einen Code, der in Ihrem Beispiel den Aufruf bind()durch einen Aufruf einer von Ihnen bereitgestellten Funktion ersetzt, die manipuliert werden kann die Daten vor dem Aufruf der realen Funktion. Siehe LD_PRELOADin man ld.so.

Hier ist ein C, das genau das tut, shim_bind.c, das den Port auf 7777 überschreibt und einen AF_INET-Socket annimmt. Kompilieren Sie es mit gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.cund verwenden Sie es, indem Sie es LD_PRELOAD=shim_bind.sovor Ihren Befehl stellen.

/*
 * capture calls to a routine and replace with your code
 * http://unix.stackexchange.com/a/305336/119298
 * gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.c
 * LD_PRELOAD=/path/to/shim_bind.so ./test
 */
#define _GNU_SOURCE /* needed to get RTLD_NEXT defined in dlfcn.h */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen){
    static int (*real_bind)(int sockfd, const struct sockaddr *addr,
                            socklen_t addrlen) = NULL;
    int port = 7777;
    struct sockaddr_in theaddr;

    if (!real_bind) {
        real_bind = dlsym(RTLD_NEXT, "bind");
        char *error = dlerror();
        if (error != NULL) {
            fprintf(stderr, "%s\n", error);
            exit(1);
        }
    }
    fprintf(stderr, "binding: port %d\n", port);
    memcpy(&theaddr, addr, sizeof(theaddr));
    theaddr.sin_port = htons((unsigned short)port);
    return real_bind(sockfd, (struct sockaddr*)&theaddr, addrlen);
}
meuh
quelle
Das ip_local_port_rangewird für mich jetzt einfacher einzurichten sein, aber ich werde wahrscheinlich mit anderen Aufrufen dieser Binärdatei spielen müssen, damit dies sehr nützlich aussieht, danke!
Délisson Junio