무작위 포트 소켓의 범위를 제한하는 방법은 무엇입니까?

무작위 포트 소켓의 범위를 제한하는 방법은 무엇입니까?

bind시스템에서 임의의 사용 가능한 포트를 얻으려면 포트 매개변수 0을 사용하는 바이너리를 실행해야 합니다 . 커널이 선택할 수 있는 포트 범위를 제한하는 방법이 있습니까?

답변1

Linux에서는 다음과 같은 작업을 수행합니다.

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

예를 들어, 다른 unice의 임시 포트 범위를 변경하는 방법에 대한 지침은 다음에서 찾을 수 있습니다.http://www.ncftp.com/ncftpd/doc/misc/ephemeral_ports.html

답변2

bind()소스 코드에 액세스하지 않고 바이너리가 실행되는 방식을 변경하려는 경우 때때로 shim을 사용할 수 있습니다. 이는 예에서 제공한 함수를 호출하여 실제 함수에 대한 호출을 대체하는 코드 조각입니다. 이전 데이터를 조작할 수 있습니다. 에서 확인 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);
}

관련 정보