私は(ソースコードで)プログラムを実行しています:
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を使用してディストリビューションを実行している場合、この機能はまだ機能できます。