gethostbyname을 사용하여 루트 액세스 없이 호스트 이름에 별칭을 추가하려면 어떻게 해야 합니까?

gethostbyname을 사용하여 루트 액세스 없이 호스트 이름에 별칭을 추가하려면 어떻게 해야 합니까?

나는 (소스 코드에서) 프로그램을 실행하고 있습니다:

gethostbyname("whatever");

로컬 컴퓨터의 주소를 사용하고 싶습니다. 소스를 변경할 수 없습니다. 루트라면 쉽습니다. /etc/hosts에 이름의 별칭을 지정하기만 하면 됩니다. 하지만 – 인간으로서 내가 할 수 있는 일이 있을까요?호스트가 아닌사용자가 내 통화에 gethostbyname()동일한 영향을 미치나요 ?

/etc/nsswitch.conf가지다:

hosts:      files nis dns myhostname

경우에.

답변1

컨테이너에서 실행

사용팟캐스트(또는 루트가 없는 Docker) 별칭이 설정된 컨테이너 내에서 코드를 실행할 수 있습니다. 예를 들어 다음을 호출하는 코드가 있습니다 gethostbyname.

#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h>

int main(int argc, char **argv) {
  for (int i = 1; i < argc; i++) {
    struct hostent *entry = gethostbyname(argv[i]);

    for (int j = 0; entry->h_addr_list[j] != NULL; j++) {
      printf("%s: %s\n", entry->h_name,
             inet_ntoa(*(struct in_addr *)entry->h_addr_list[j]));
    }
  }
  return 0;
}

이것을 명령으로 컴파일 lookuphost한 후 실행하면 다음과 같은 ./lookuphost google.com결과가 나타납니다.

$ ./lookuphost google.com
google.com: 142.251.32.110

google.com문제를 해결 하고 싶다면 1.2.3.4다음과 같이 할 수 있습니다.

$ podman run -it --rm \
  --add-host google.com:1.2.3.4 \
  -v $PWD:$PWD -w $PWD fedora:37 \
  ./lookuphost google.com
google.com: 1.2.3.4

함수를 사용하여 삽입

당신은 그것을 사용할 수 있습니다함수 삽입gethostbyname자신만의 코드로 통화를 마무리하세요. 예를 들어, 다음을 입력하면 gethostbyname.c:

#define _GNU_SOURCE

#include <arpa/inet.h>
#include <dlfcn.h>
#include <netdb.h>
#include <netinet/in.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>

struct hostent *gethostbyname(const char *name) {
  static struct hostent *(*real_gethostbyname)(const char *) = NULL;

  if (!real_gethostbyname) {
    real_gethostbyname = dlsym(RTLD_NEXT, "gethostbyname");
  }

  struct hostent *entry = real_gethostbyname(name);

  if (strcmp(name, "google.com") == 0) {
    struct in_addr inp;

    inet_aton("1.2.3.4", &inp);
    entry->h_addr_list[0] = (char *)&inp;
  }

  return entry;
}

그런 다음 공유 라이브러리에 빌드합니다.

gcc -c -fPIC gethostbyname.c
gcc -shared -ldl -fPIC gethostbyname.o -o gethostbyname.so

LD_PRELOAD실행 하여 lookuphost예상되는 답변을 얻을 수 있습니다.

$ LD_PRELOAD=./gethostbyname.so ./lookuphost google.com
google.com: 1.2.3.4

답변2

  • 사용nss_wrapper라이브러리를 미리 로드합니다. @larsks의 제안과 유사하지만 약간 낮은 수준에서 작동합니다(passwd 및 호스트 에뮬레이션 제공). Samba는 이를 테스트 스위트에 사용합니다.

    export LD_PRELOAD=libnss_wrapper.so
    export NSS_WRAPPER_HOSTS=/path/to/your/hosts
    
  • glibc에 익숙해이를 위한 특정 기능이 있습니다. $HOSTALIASES쌍 목록 alias real.hostname.tld(즉, 추가 수준의 간접 참조,아니요IP 주소를 가리킵니다).

    $ export HOSTALIASES=~/.hosts
    $ cat > $HOSTALIASES <<!
    whatever   real.example.net
    !
    

    그러나 나는 이 기능을 제거할 계획이 있다고 생각하며, 적어도 내 시스템에서는 더 이상 작동하지 않는 것 같습니다 getent hosts. 이전 Glibc를 사용하여 배포판을 실행하는 경우 이 기능은 여전히 ​​작동할 수 있습니다.

관련 정보