Linuxã¢ããã³ãã«ã¬ã³ãã¼13æ¥ç®ã®æææ¥ã®è¨äºã§ãã
ä»æ¥ã¯ä»¥åããæ°ã«ãªã£ã¦ããNSS pluginã®ä»æ§ã«ã¤ãã¦èª¿ã¹ã¦ã¾ã¨ããç°¡åãªãã®ãæ¸ãã¦ã¿ããã¨æãã¾ããã¨ããã®ããå®ã¯ ååã äºäººã NSS pluginãéçºãã¦å ¬éãã¦ããããã£ã¨è² ãã¦ãããªããªã¨æã£ã¦ãã¾ããã
GNU Name Service Switch (NSS) ã¨ã¯
ãã¦ãOSã使ã£ã¦ããã¨ãååã®æ£ä½ãä½è ãªã®ãããããã¯ãã®IDã¯äººéãã©ãããååãã¤ãã¦ããã®ãããããã確èªããæ©ä¼ãé »ç¹ã«ããã¾ãã
Linuxã®å ´åããã®ã人éã使ãååã¨ãOSã使ãIDãã®ç¸äºè§£æ±ºãName Service Switchã¨ãããã®ããã£ã¦ããã¾ã*1ã
Linuxãæ§ç¯éç¨ãã¦ã㦠/etc/nsswitch.conf
ã¨ãããã¡ã¤ã«ãããã£ãçµé¨ãããæ¹ãå¤ãã§ãããããã®ããã¥ã¢ã«ã« ã©ãããåå解決ãããæã«NSSã使ãããããä¸è¦§ããã¦ãã¾ããä¾ãã°ãpasswdï¼ã¦ã¼ã¶åâIDãªã©ï¼ãgroupãhostsï¼ãã¹ãåâIPãªã©ï¼ãªã©ã代表çãã¨æãã¾ãã
ããã¨ä¸ç·ã«ãã©ãããé¢æ°ãèªãã æã«ã©ã®è¨å®ã使ãããããã¨ãã対å¿ã¥ããåãããã¨æãã¾ãã
ä¾ãã°ä¸è¿°ã®manã®hostsã®é ç®ã«ã¯
Host names and numbers, used by gethostbyname(3) and related functions.
ã¨æ¸ããã¦ãã¾ããããã°ã©ã ã®ä¸ã§ãã¹ãåã解決ããé¢æ°ã§ãã gethostbyname(3)
ã¨ãä¼¼ãæ©è½ã®é¢æ°ï¼ä¾ãã° gethostbyname_r(3)
ãªã©ï¼ãå¼ã¶æã«ãnsswitchãåç
§ããã©ã®é åºã§NSSãã©ã°ã¤ã³ãå¼ã³åºããã決ããå®éã®åå解決ãè¡ãã¾ãã
NSSã®é¢æ°å¼ã³åºãã追ãããã
å®éã©ãããçµç·¯ã§å¼ã³åºããã¦ããã®ã§ããããã観å¯ãã¦ã¿ã¾ãã
id(1)
ã¯ãã¦ã¼ã¶IDããã¦ã¼ã¶ãã°ã«ã¼ãã«é¢ããpasswdæ
å ±ï¼ã¦ã¼ã¶åããã¼ã ãã£ã¬ã¯ããªãªã©...ï¼ãå¼ãã¦ãããã³ãã³ãã§ãã
$ id uid=1000(vagrant) gid=1000(vagrant) groups=1000(vagrant)
ãã®ã³ãã³ãã¯æããã«NSSã使ã£ã¦ãããã§ãããã©ããããã©ã°ã¤ã³ã使ã£ã¦ãããã¯ãä¾ãã°straceã§è¿½ãããããã¾ãã
$ strace id 9999 2>&1 | grep 'libnss' openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libnss_systemd.so.2", O_RDONLY|O_CLOEXEC) = 3
glibcãç¨æãã¦ããæ¨æºçãªãã©ã°ã¤ã³ã¯ã libnss_XXX.so
ã®ãããªååã«ãªãã¾ããnsswitch.confã確èªããã¨ã確ãã«passwdæ
å ±ã«ã¤ãã¦ã¯ files
㨠systemd
ããã®é çªã§åç
§ããããã«ãªã£ã¦ãã¾ãã
$ grep passwd /etc/nsswitch.conf passwd: files systemd
ãªãã id
ã³ãã³ãã¯ãã¤ããªã«ããæ
å ±ããã©ã¤ãã©ãªããªã³ã¯ãã¦ããããã§ã¯ãªããåå解決ãããã¿ã¤ãã³ã°ã§åçã«ãã©ã°ã¤ã³ããã¼ããã¦ãã¾ããåçãªã³ã¯ã¨ãã£ã¦ãããã¯ç¹æ®ãã¨æãã¾ãã
$ ldd `which id` linux-vdso.so.1 (0x00007fff4f1fe000) libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fcd546b5000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd544cb000) libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007fcd5443b000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcd54435000) /lib64/ld-linux-x86-64.so.2 (0x00007fcd546fb000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fcd54413000)
ãã¦ããããã®NSSãã©ã°ã¤ã³å
±æã©ã¤ãã©ãªã«ã¯ _nss_XXX_getpwuid_r
ã¨ããé¢æ°ãå®ç¾©ããã¦ãããNSS㯠getpwuid_r(3)
ãå¼ã¶ã¿ã¤ãã³ã°ã§ãé ç¹°ãã«ãããã®é¢æ°ãå¼ãã§ããã¾ãã
ç¶ãã¦ãbpftraceã使ã£ã¦è¿½ãããã¦ã¿ã¾ã*2ã
次ã®ãã㪠trace.bt
ã¨ãããã¡ã¤ã«ãä½æãã¾ãã
uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_getpwuid_r { printf("called: %s(%d)\n", probe, arg0); } uretprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_getpwuid_r { printf("returns: %d\n", retval); } uprobe:/lib/x86_64-linux-gnu/libnss_systemd.so.2:_nss_systemd_getpwuid_r { printf("called: %s(%d)\n", probe, arg0); } uretprobe:/lib/x86_64-linux-gnu/libnss_systemd.so.2:_nss_systemd_getpwuid_r { printf("returns: %d\n", retval); }
bpftraceãèµ·åãã¾ãã
$ sudo bpftrace trace.bt Attaching 4 probes...
å¥ã®ã¿ã¼ããã«ã§ id
ã³ãã³ããçºè¡ãã㨠_nss_*
ãªé¢æ°å¼ã³åºãã¨æ»ãå¤ãè¨é²ããã¦ãã¾ããnsswitch.confã®manã«ãã success
ã1ã«ã notfound
ã0ã«å¯¾å¿ãã¦ããæãã§ããã
$ id 1 uid=1(daemon) gid=1(daemon) groups=1(daemon) $ id 9999 id: â9999â: no such user .... $ sudo bpftrace trace.bt Attaching 4 probes... called: uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_getpwuid_r(1) returns: 1 called: uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_getpwuid_r(1) returns: 1 called: uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_getpwuid_r(9999) returns: 0 called: uprobe:/lib/x86_64-linux-gnu/libnss_systemd.so.2:_nss_systemd_getpwuid_r(9999) returns: 0
NSSã®ãã©ã°ã¤ã³å ¥é
ããã¾ã§èªãã§åããéããNSSã®ãã©ã°ã¤ã³ã¯ libnss_${ãã©ã°ã¤ã³å}.so
ã¨ããååã§ã _nss_${ãã©ã°ã¤ã³å}_${対å¿ããé¢æ°å}
ã¨ããã·ã³ãã«ãã¨ã¯ã¹ãã¼ããã¦ããå
±æã©ã¤ãã©ãªã£ã½ããã¨ãããã¨ããããã¾ãã
å®éã©ãããååã®ã©ã¤ãã©ãªã«ãã¦ãã©ãããé¢æ°ã®å®ç¾©ã«ãã¦ã·ã³ãã«ã¯ããã§ããã¨ããã®ã¯GNU libcã®ããã¥ã¢ã«ã«ããã¾ãã
ãããã£ããå®ä¾ãçºãã¦ã¿ã¾ãã
åå解決ã«mDNSã使ãããã®nss-mdnsã¨ãããã©ã°ã¤ã³ãããããã§ãã
ãã® ã½ã¼ã¹ã³ã¼ããè¦ã ã¨ãhostsãã©ã°ã¤ã³ãæ¸ãã«ã¯ã gethostbyname_r
gethostbyname[234]_r
gethostbyaddr_r
ãããã«å¯¾å¿ããé¢æ°èªä½ã¯ enum nss_status
ãè¿ãã¨ããã¿ããã ã¨ãããã¾ãã
ã¨ããã§ä¾ãã° ping -c1 udzura.jp
ã®ãããªã³ãã³ããæã£ã¦ã¿ãã¨ã gethostbyname4_r(3)
ãå¼ãã§ããããã§ãã®ã§ãããã ãå®è£
ãããã©ã°ã¤ã³ãä½ã£ã¦ã¿ã¾ãã
$ sudo bpftrace -e ' uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_gethostbyname*_r { printf("%s called probe %s\n", comm, probe); }' Attaching 4 probes... ping called probe uprobe:/lib/x86_64-linux-gnu/libnss_files.so.2:_nss_files_gethostbyname4_r
ã¨ããããè¦æ§è¦çä¼¼ã§1é¢æ°ã ãã
#include <nss.h> #include <syslog.h> enum nss_status _nss_logger_gethostbyname4_r(const char* name, struct gaih_addrtuple** pat, char* buffer, size_t buflen, int* errnop, int* h_errnop, int32_t* ttlp) { openlog("resolver.hello", 0, LOG_USER); syslog(LOG_NOTICE, "resolving: %s", name); return NSS_STATUS_NOTFOUND; }
ãã®è¾ºã®è¨è¿° ãåèã«ãã¦ãã«ããªãã·ã§ã³ã決ãã¾ãã
$ gcc -shared -o libnss_logger.so.2 -Wl,-soname,libnss_logger.so.2 nss_logger.c
ã¾ããNSSã¯å
±æã©ã¤ãã©ãªè§£æ±ºæã«ã¯ LD_LIBRARY_PATH
ç°å¢å¤æ°ãåç
§ãã¦ãããªããããªã®ã§ã /usr/lib/x86_64-linux-gnu
é
ä¸ã«ã¤ã³ã¹ãã¼ã«ãã¦ããã¾ãã
$ sudo install ./libnss_logger.so.2 /usr/lib/x86_64-linux-gnu/
æå¾ã«nsswitchã«ãhosts解決æã«ã¯ logger
ãã©ã°ã¤ã³ãæåªå
ãããããæå®ãã¾ãã
hosts: logger files dns
ããã§é©å½ã«åå解決ããããã°ã©ã ãèµ°ãããã¨ãsyslogã«åå解決ããæ¨ã¨è§£æ±ºãããã¨ãããã¡ã¤ã³åãè¨é²ããã¾ãã
$ sudo tail -f /var/log/syslog | grep resolver Dec 4 07:13:11 ubuntu-groovy resolver.hello: resolving: ubuntu-groovy Dec 4 07:13:15 ubuntu-groovy resolver.hello: resolving: udzura.jp Dec 4 07:13:20 ubuntu-groovy resolver.hello: resolving: ubuntu-groovy ...
ã¡ãªã¿ã« _nss_logger_gethostbyname4_r()
èªä½ã¯çµ¶å¯¾ã«notfoundã«ãªãããã«ãã¦ããã解決ã®å¦çèªä½ã¯æ¬¡ã®ãã©ã°ã¤ã³ã«ç§»è²ããã¾ãããããããã¨ã§è¨ã£ã¦ã¿ãã°ãåå解決ã®ç£æ»ãã®ãããªå®è£
ãç°¡åã«ä½ããããã«æããã¾ããã
ãªããæ¢åã®ãã©ã°ã¤ã³ã¯å¤§æµCã§æ¸ããã¦ãã¾ãããåçãç解ããã°åããéãä»ã®è¨èªã§ããå ±æã©ã¤ãã©ãªãä½æã§ããè¨èªãªãä½æå¯è½ã§ãã
Rust ã§æ¸ããããã©ã°ã¤ã³ã®ä¾ã§ãã
ã¡ãªã¿ã«NSSã¯æ¬æ¥ããã°ã©ã å´ã§ãªã³ã¯ãæ³å®ãã¦ããªãå ±æã©ã¤ãã©ãªãåçã«èªã¿è¾¼ãå½¢ã«ãªããããããã°ã©ã å´ã¨NSSãã©ã°ã¤ã³å´ã§ãªã³ã¯ããã©ã¤ãã©ãªãéã£ãããé¢æ°åãã³ã³ããªã¯ããã¦ããã¨æ·±é ãªãã°ã®åå ã«ãªãã¾ãã
ä¾ãã°è¤éãªå¦çãããããªNSSãã©ã°ã¤ã³ã¯ãå ±æã©ã¤ãã©ãªä¾åã§ã¯ãªããC++ãRustãªã©ã®ã©ã³ã¿ã¤ã ãcrateã®å®è£ ã§æ¸ãã¨ããæ¹æ³ã¯åé¿ã®ä¸ã¤ã®çã¨ãã¦æå¹ããããã¾ããã
NSSã§ã©ããããã©ãã«ãèµ·ãããããã«ã¤ãã¦ã¯ãç¶ã»ç©å¼èå âæ¯ãããã¨ãçã¾ãããâãã®2020å¹´8æã9æã®å·ãã¨ã¦ãåããããã詳細ãªã®ã§ããã¡ããæ¯éä½µãã¦ãèªã¿ãã ããã
ã¾ã¨ã
NSS ã«ã¤ãã¦æ¦è¦çãªå 容ã¨ãç°¡åãªãã©ã°ã¤ã³ã®ä½ãæ¹ãæ¸ãæ®ãã¾ãããæ®æ®µé ãã¦ããå²ã«ã¯ãLinuxã使ãä¸ã§ã»ã¼çµ¶å¯¾ã«é¿ããããªãä»æ§ã§ãããã®ã§ããã®ç¥èãéç¨ã®ä½ãã®å½¹ã«ç«ã¤ã¨å¬ãããªã¨æãã¾ãã
åä½ç°å¢
æ¬ç¨¿ã¯ä»¥ä¸ã®ç°å¢ã§ç¢ºèªãã¾ããã
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 20.10 Release: 20.10 Codename: groovy
$ uname -a Linux ubuntu-groovy 5.8.0-63-generic #71-Ubuntu SMP Tue Jul 13 15:59:12 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
è¬è¾
ãã®è¨äºã¯ @ten_forward ããã«ã¬ãã¥ã¼ãããã ãã¾ããããããã¨ããããã¾ããï¼*3
ten_forward ããã®Linuxã¢ããã³ãã«ã¬ã³ãã¼ã¯21æ¥ç®ã§ããã¾ããææ¥ã¯ @kaizen_nagoya ããã§ãã