web-dev-qa-db-ja.com

ランダムなポートソケットの範囲を制限する方法は?

システムからランダムな空きポートを取得するために、ポート引数を0にしてbindを使用して実行する必要のあるバイナリがあります。カーネルが選択できるポートの範囲を制限する方法はありますか?

7
Délisson Junio

linuxでは、あなたは次のようなことをするでしょう

Sudo sysctl -w net.ipv4.ip_local_port_range="60000 61000" 

他のuniceのエフェメラルポート範囲を変更するための指示は、たとえば http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html にあります。

7
Matija Nalis

ソースにアクセスせずにバイナリの実行方法を変更したい場合は、シムを使用できます。これは、例ではbind()の呼び出しを実際の関数を呼び出す前にデータを操作できる、提供する関数。 LD_PRELOADman ld.soをご覧ください。

これを正確に実行するいくつかのC、shim_bind.c、ポートを7777にオーバーライドし、AF_INETソケットを想定しています。 gcc -Wall -O2 -fpic -shared -ldl -o shim_bind.so shim_bind.cでコンパイルし、コマンドの前にLD_PRELOAD=shim_bind.soを付けて使用します。

/*
 * 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);
}
4
meuh