나는 (소스 코드에서) 프로그램을 실행하고 있습니다:
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를 사용하여 배포판을 실행하는 경우 이 기능은 여전히 작동할 수 있습니다.