개발일기/이슈 로그

[이슈로그] Alpine Linux에서 Nessus 다운로드 2 - 트러블 슈팅

ignuy 2024. 9. 9.

.deb 파일을 디패키징

나는 Alpine Linux 환경에 설치할 파일로 .deb 파일을 골랐다. .rpm을 골라도 상관없다. 우회가 목적이므로 정확한 원리와 함께 Linux 환경에서 .deb 파일을 디패키징하는 방법을 설명하겠다.

Linux- Ubuntu-amd64 설치 파일 다운로드

curl --request GET \\
  --url '<https://www.tenable.com/downloads/api/v2/pages/nessus/files/Nessus-10.8.2-ubuntu1604_amd64.deb>' \\
  --output 'Nessus-10.8.2-ubuntu1604_amd64.deb'

아카이브 추출

.deb파일도 ar (Unix 아카이브) 형식을 사용하여 여러 파일을 하나로 묶는 방식으로 구성된다. 따라서 binutils 라이브러리를 이용하여 .deb라는 아카이브 파일에서 내용을 추출하는 방법을 활용한다.

ar x Nessus-10.8.2-ubuntu1604_amd64.deb

위 명령어의 결과는 크게 세 개의 파일로 나온다.

  • debian-binary: 패키지 포맷 버전을 포함하는 텍스트 파일.
  • control.tar.gz: 패키지의 메타데이터 (설치 스크립트 및 패키지 정보 등).
  • data.tar.gz: 실제 프로그램 파일들이 들어있는 아카이브.

우리가 필요한 것은 data.tar.gz이다.

.tar 파일 디패키징

tar -xvf data.tar.gz

따라서 패키징을 위 명령어로 풀면 설치가 완료된다.

정리

  1. ar 명령어: ar은 UNIX 및 UNIX-like 시스템에서 사용하는 아카이브 파일을 생성, 수정, 추출하는 명령어이다. ar은 일반적으로 .a 확장자를 가진 정적 라이브러리 파일을 처리할 때 사용되지만, Debian 패키지 파일(.deb)도 ar 형식으로 패키징 되어 있기 때문에 활용 가능하다.
  2. x 옵션: x 옵션은 ar 명령어의 추출(extract) 모드로, 아카이브 파일에서 파일을 추출할 때 사용된다. 이 옵션을 지정하면, ar은 아카이브 파일에서 모든 파일을 현재 작업 디렉토리로 추출한다.

musl vs glibc

이 부분에서 시간을 많이 썩혔다. 앞서 설명했듯 Alpine Linux는 musl(머슬)을 표준 C 라이브러리로 사용하고 있다. 기존 리눅스 운영체제에 대중적으로 사용되던 glibc와 다르다.

위 .tar 파일을 디패키징하여 나오는 결과물을 직접 실행해 보면 다음과 같은 일이 벌어진다.

not found?!

필요한 C 라이브러리들이 존재하지 않아서 발생하는 문제이다. 따라서 Alpine Linux에서 glibc를 가져와야 한다.

1. gcompat 설치

결과적으로 이 방법은 실패했다.

Alpine Linux에서도 musl과 glibc사이의 호환을 위한 방법들을 공식적으로 소개하고 있다(https://wiki.alpinelinux.org/wiki/Running_glibc_programs). 그중 하나가 gcompat이다.

gcompat을 설치하고 다시 직접 실행해보면 역시 실행되지 않는다. gcompat으로도 실행되지 않는다면 결국 필요한 라이브러리를 전부 만족하지 못하지 않았을까 하는 의심으로 ldd 명령을 통해 nessusd가 의존하는 모든 라이브러리와 그 라이브러리들이 올바른 경로에 있는지 확인했다.

$ ldd /opt/nessus/sbin/nessusd

------------------------------------------------------------------
 /lib64/ld-linux-x86-64.so.2 (0x7fcf4e85c000)
 libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7fcf4e85c000)
Error loading shared library libanl.so.1: No such file or directory (needed by /opt/nessus/sbin/nessusd)
 libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7fcf4e85c000)
 libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fcf4e85c000)
 libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x7fcf4d87f000)
 libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fcf4e85c000)
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /opt/nessus/sbin/nessusd)
Error relocating /opt/nessus/sbin/nessusd: __printf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __longjmp_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __stpcpy_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __cmsg_nxthdr: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __vfprintf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: getnetbyname_r: symbol not found
Error relocating /opt/nessus/sbin/nessusd: makecontext: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __open_2: symbol not found
Error relocating /opt/nessus/sbin/nessusd: setcontext: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __strncpy_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __sprintf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: gai_cancel: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __snprintf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: getcontext: symbol not found
Error relocating /opt/nessus/sbin/nessusd: fcvt_r: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __fread_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: getaddrinfo_a: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __strftime_l: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __vsnprintf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __memmove_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __strcpy_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __strcat_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __memset_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: backtrace: symbol not found
Error relocating /opt/nessus/sbin/nessusd: gai_error: symbol not found
Error relocating /opt/nessus/sbin/nessusd: getprotobyname_r: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __fdelt_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __realpath_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __fprintf_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __memcpy_chk: symbol not found
Error relocating /opt/nessus/sbin/nessusd: ecvt_r: symbol not found
Error relocating /opt/nessus/sbin/nessusd: __read_chk: symbol not found

아무래도 nessusd 실행 파일이 의존하는 모든 라이브러리를 충족시키지 못한 모양이다.

오픈소스 활용(https://github.com/sgerrand/alpine-pkg-glibc)

이 방법도 결과적으론 실패다. Github에서 오픈소스로 공개된 alpine linux 환경에서 glibc 라이브러리를 실행하기 위한 패키징을 발견했다.

Readme.md가 시키는 대로 설치를 해보자.

wget -q -O /etc/apk/keys/sgerrand.rsa.pub <https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub>
wget <https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r1/glibc-2.35-r1.apk>
apk add glibc-2.35-r1.apk

그 후 다시 파일을 직접적으로 실행해보면 아래와 같은 에러를 확인할 수 있다.

$ ldd /opt/nessus/sbin/nessusd
Segmentation fault

대체 이 깔끔하고 담백한 한줄의 에러는 무엇이란 말인가…(더 줘...)

gdb를 사용하여 nessusd를 실행해 보아도 아무런 단서를 잡지 못했다.

 

glibc 버전업(https://github.com/sgerrand/alpine-pkg-glibc/issues/204, https://github.com/sgerrand/alpine-pkg-glibc/issues/209, https://github.com/sgerrand/alpine-pkg-glibc/issues/210)

드디어 성공한 사례이다. 두 번째 시도에서 생겼던 Segmentation Error와 같은 사례를 찾았다. glibc 2.35 버전이 문제였다.

해당 이슈(Issue #210)에서 다른 활동자가 올려준 버전을 활용하여 glibc 버전을 2.38로 올려 실행해 보았다.

echo '<https://storage.sev.monster/alpine/edge/testing>' | sudo tee -a /etc/apk/repositories
wget <https://storage.sev.monster/alpine/edge/testing/x86_64/sevmonster-keys-1-r0.apk>
sudo sh -c '
  apk add --allow-untrusted ./sevmonster-keys-1-r0.apk
  apk update \\
    && apk add gcompat \\
    && rm /lib/ld-linux-x86-64.so.2 \\
    && apk add --force-overwrite glibc \\
    && apk add glibc-bin'

성공이다.

댓글