由於在某些場景需要使用靜態鏈接的snmpwalk或者其他程序,為了方便執行文件的分發,適配多版本系統,所以需要自己編譯net-snmp
實驗操作系統Ubuntu22 amd64
獲取程序
git clone方式
$ git clone https://github.com/net-snmp/net-snmp.git
或者也可以依據tag下載源碼包
生成Makefile
net-snmp項目根路徑下面有一個configure文件,可以用於生成Makefile,命令執行過程中會彈出一些輸入確認,直接回車確認即可
$ ./configure --prefix=/tmp/snmp --disable-embedded-perl --without-perl-modules --disable-ucd-snmp-compatibility --disable-scripts
--prefix參數指定文件安裝目錄到/tmp/snmp
需要禁用perl相關模塊以及一些腳本,否則可能會遇到錯誤如下
relocation R_X86_64_PC32 against symbol `netsnmp_ds_handle_config' can not be used when making a shared object; recompile with -fPIC
生成執行程序
如果此時項目根目錄下面生成一個Makefile,則表示configure命令成功
執行程序的源碼和生成的二進制都在apps/目錄下
$ make LDFLAGS="-static"
校驗生成的二進制執行文件,發現不是靜態鏈接的
$ ldd apps/snmpwalk
linux-vdso.so.1 (0x00007ffed71c1000)
libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3 (0x00007ff639800000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff639400000)
/lib64/ld-linux-x86-64.so.2 (0x00007ff639d7e000)
靜態編譯snmpwalk
發現在make snmpwalk執行的時候會產生兩條執行命令,第一條是 gcc包含-static參數,但是第二條沒包含
$ cd apps
$ rm snmpwalk
$ make snmpwalk
/bin/bash ../libtool --mode=link gcc -static -g -O2 -DNETSNMP_ENABLE_IPV6 -fno-strict-aliasing -DNETSNMP_REMOVE_U64 -g -O2 -Ulinux -Dlinux=linux -Wall -Wextra -Wstrict-prototypes -Wwrite-strings -Wcast-qual -Wimplicit-fallthrough -Wlogical-op -Wundef -Wno-format-truncation -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter -o snmpwalk snmpwalk.lo ../snmplib/libnetsnmp.la
libtool: link: gcc -g -O2 -DNETSNMP_ENABLE_IPV6 -fno-strict-aliasing -DNETSNMP_REMOVE_U64 -g -O2 -Ulinux -Dlinux=linux -Wall -Wextra -Wstrict-prototypes -Wwrite-strings -Wcast-qual -Wimplicit-fallthrough -Wlogical-op -Wundef -Wno-format-truncation -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter -o snmpwalk .libs/snmpwalk.o ../snmplib/.libs/libnetsnmp.a -lm -lssl -lcrypto
所以需要執行命令如下,把make snmpwalk的輸出的第二條命令粘貼下來,手動在gcc後面加上-static參數
$ rm snmpwalk
$ gcc -static -g -O2 -DNETSNMP_ENABLE_IPV6 -fno-strict-aliasing -DNETSNMP_REMOVE_U64 -g -O2 -Ulinux -Dlinux=linux -Wall -Wextra -Wstrict-prototypes -Wwrite-strings -Wcast-qual -Wimplicit-fallthrough -Wlogical-op -Wundef -Wno-format-truncation -Wno-missing-field-initializers -Wno-sign-compare -Wno-unused-parameter -o snmpwalk .libs/snmpwalk.o ../snmplib/.libs/libnetsnmp.a -lm -lssl -lcrypto
# 執行的時候會產生告警信息如下,這是正常的
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/11/../../../x86_64-linux-gnu/libcrypto.a(libcrypto-lib-dso_dlfcn.o): in function `dlfcn_globallookup':
(.text+0x17): 警告: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ../snmplib/.libs/libnetsnmp.a(system.o): in function `netsnmp_str_to_gid':
/home/gong/rust-work/github/net-snmp/snmplib/system.c:1492: 警告: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the bc version used for linking
/usr/bin/ld: /home/gong/rust-work/github/net-snmp/snmplib/system.c:1494: 警告: Using 'endgrent' in statically linked applications requires at runtime the shared librar from the glibc version used for linking
/usr/bin/ld: ../snmplib/.libs/libnetsnmp.a(system.o): in function `netsnmp_str_to_uid':
/home/gong/rust-work/github/net-snmp/snmplib/system.c:1459: 警告: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the bc version used for linking
/usr/bin/ld: /home/gong/rust-work/github/net-snmp/snmplib/system.c:1461: 警告: Using 'endpwent' in statically linked applications requires at runtime the shared librar from the glibc version used for linking
/usr/bin/ld: ../snmplib/.libs/libnetsnmp.a(system.o): in function `netsnmp_getaddrinfo':
/home/gong/rust-work/github/net-snmp/snmplib/system.c:884: 警告: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/bin/ld: ../snmplib/.libs/libnetsnmp.a(system.o): in function `netsnmp_gethostbyaddr':
/home/gong/rust-work/github/net-snmp/snmplib/system.c:1050: 警告: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries frome glibc version used for linking
/usr/bin/ld: ../snmplib/.libs/libnetsnmp.a(system.o): in function `netsnmp_gethostbyname':
/home/gong/rust-work/github/net-snmp/snmplib/system.c:980: 警告: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from glibc version used for linking
檢查snmpwalk鏈接
$ ldd snmpwalk
不是動態可執行文件
之後也可以把生成的snmpwalk複製到另外一台古老的linux上運行校驗,如果機器上有docker, 可以執行命令docker run -it alpine sh,把snmpwalk複製到容器內部執行
靜態鏈接snmptrapd
如果出現報錯如下
/usr/bin/ld: 找不到 -lpci: 沒有那個文件或目錄
collect2: error: ld returned 1 exit status
這個是加入了-static參數導致的
嘗試了
$ sudo apt install libpci-dev
可以選擇把編譯選項中-lpci參數去掉