리눅스 바이너리 파일들이 참조하는 주요 라이브러리 손상에 따른 시스템 이상 동작 확인 및 해결 방법
RHEL(CentOS) 7.x 기준으로 설명된 내용임
목차
이슈
CentOS 7.3 서버에서 아래 메시지와 함께 서버가 컨트롤 되지 않는 현상이 발생됨
ls: error while loading shared libraries: /lib64/libpcre.so. 1 : file too short |
- 문의 내용:
서버 사용 중에 아래와 같이 오류가 발생하며, 뭔가 이상해져서 서버 종료를 했지만
ls: error while loading shared libraries: /lib64/libpcre.so.1: file too short
서버 종료가 되지 않음
원인
원인은 libpcre 라이브러리 파일을 변형(혹은 손상)되어서 그렇다.
해당 라이브러리는 pcre rpm(RHEL / CentOS 기준)을 통해서 설치되는 라이브러리 파일로 정규표현식과 관련된 라이브러리를 제공해 준다.
이 라이브러리는 수 많은 리눅스 명령어와 연관되어 있다. 따라서 yum remove를 통해서 삭제를 시도하면 다른 패키지들과 의존성이 너무 커서 삭제할 수 없다는 메시지가 뜨고 삭제가 되지 않는다.
이슈재현
우선 ls 명령이 참조하는 라이브러리를 확인해 본다.
# ldd /bin/ls linux-vdso.so. 1 => ( 0x00007ffc701a9000 ) libselinux.so. 1 => /lib64/libselinux.so. 1 ( 0x00007f67568de000 ) libcap.so. 2 => /lib64/libcap.so. 2 ( 0x00007f67566d9000 ) libacl.so. 1 => /lib64/libacl.so. 1 ( 0x00007f67564d0000 ) libc.so. 6 => /lib64/libc.so. 6 ( 0x00007f6756102000 ) libpcre.so. 1 => /lib64/libpcre.so. 1 ( 0x00007f6755ea0000 ) libdl.so. 2 => /lib64/libdl.so. 2 ( 0x00007f6755c9c000 ) /lib64/ld-linux-x86- 64 .so. 2 ( 0x00007f6756b05000 ) libattr.so. 1 => /lib64/libattr.so. 1 ( 0x00007f6755a97000 ) libpthread.so. 0 => /lib64/libpthread.so. 0 ( 0x00007f675587b000 ) |
- libpcre.so.1 이 /lib64/libpcre.so.1 을 참조하고 있다.
- /lib64 디렉토리는 /usr/lib64 디텍토리로 싱볼릭링크 되어있고, libpcre.so.1 파일은 libpcre.so.1.2.0 파일로 싱볼릭링크 되어있다.
- 참조하는 라이브러리의 종류나 경로는 서버 배포판에 따라 다르게 출력될 수 있음.
리눅스의 여러 바이너리들이 libpcre 를 참조하는 것을 볼 수 있다.
# find /bin/ -type f | wc -l 1652 # find /bin/ -type f -exec ldd {} \; | grep libpcre | wc -l 488 |
- /bin 디렉토리 외에 /sbin, /usr/bin 등에 포함된 다른 많은 리눅스 실행 바이너리들도 libpcre를 참조한다.
- 따라서 ls, cp, mv, yum, rpm, shutdown 등의 수많은 바이너리 파일들이 실행이 안되며, sshd(새로운 ssh 세션 접속 불가), 콘솔 등 서버 접속이 불가하게 된다.
libpcre 파일을 삭제해 보기
# mv /usr/lib64/libpcre.so. 1.2 . 0 /tmp # ls: error while loading shared libraries: libpcre.so. 1 : cannot open shared object file: No such file or directory |
실제 원본 파일인 위 파일을 삭제한 후 ls 를 해보면 바로 에러메시지가 출력되면서 ls가 되지 않게된다.
그런데 고객 문의와는 다르게 'cannot open shared object file: No such file or directory' 메시지가 발생을 한다.
ldd 명령을 통해 참조된 라이브러리를 확인
# ldd /bin/ls linux-vdso.so. 1 => ( 0x00007fff1d58c000 ) libselinux.so. 1 => /lib64/libselinux.so. 1 ( 0x00007f23e0b41000 ) libcap.so. 2 => /lib64/libcap.so. 2 ( 0x00007f23e093c000 ) libacl.so. 1 => /lib64/libacl.so. 1 ( 0x00007f23e0733000 ) libc.so. 6 => /lib64/libc.so. 6 ( 0x00007f23e0366000 ) libpcre.so. 1 => not found -----> ** not found 메시지 ** libdl.so. 2 => /lib64/libdl.so. 2 ( 0x00007f23e0162000 ) /lib64/ld-linux-x86- 64 .so. 2 ( 0x00007f23e0d68000 ) libattr.so. 1 => /lib64/libattr.so. 1 ( 0x00007f23dff5d000 ) |
- ldd 명령 수행 가능하다.
- ln, cat, tail, head 등 일부 명령어 들은 libpcre 라이브러리를 참조하지 않기 때문에 실행이 가능하다.
- libpcre.so.1.2.0 파일을 지웠기 때문에 not found 메시지가 발생을 한다. 그렇기 때문에 ls 를 실행해도 No such file… 메시지가 출려되는 것이다.
그렇기 때문에 이슈 상황에선 파일은 존재하지만 파일이 손상되어서 'file too short' 메시지가 발생한 것이다.
이슈 상황처럼 재현하기
(먼저 libpcre.so.1.2.0 파일을 복구 한다.)
# cat /tmp/libpcre.so. 1.2 . 0 > /usr/lib64/libpcre.so. 1.2 . 0 # ls / bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var |
mv 명령은 실행이 안되지만 cat은 가능하다. cat으로 출력 및 원래 위치로 리다이렉션하여 libpcre를 복구한다.
libpcre 파일 손상 시키기
# md5sum /usr/lib64/libpcre.so. 1.2 . 0 63febf15c53f3e2df7508cee4623cc50 /usr/lib64/libpcre.so. 1.2 . 0 # ls -la /usr/lib64/libpcre.so. 1.2 . 0 -rw-r--r-- 1 root root 402384 Nov 16 20 : 24 /usr/lib64/libpcre.so. 1.2 . 0 # echo "test" > /usr/lib64/libpcre.so. 1.2 . 0 # md5sum /usr/lib64/libpcre.so. 1.2 . 0 d8e8fca2dc0f896fd7cb4cb0031ba249 /usr/lib64/libpcre.so. 1.2 . 0 # ls -la /usr/lib64/libpcre.so. 1.2 . 0 ls: error while loading shared libraries: /lib64/libpcre.so. 1 : file too short # ldd /bin/ls /bin/ls: error while loading shared libraries: /lib64/libpcre.so. 1 : file too short |
- 이슈상황과 동일한 에러가 발생된다.
- 파일 내용이 변경되었으므로 md5 check sum과 파일 사이즈가 변경되었다.
- ls 등의 명령을 실행하면 file too short 메시지가 발생을 한다.
해결하기
만약 아래 2가지 사항에 부합된다면 온라인으로 복구 가능하지만, 두 가지를 모두 만족하기 어려우므로 이 에러를 온라인으로 해결하기는 매우 어렵다.
- 현재 운영자가 터미널을 통해 shell 접속이 되어 있는 상태
- NFS 마운트가 되어있고, 외부의 다른 서브를 통해 NFS 볼륨에 libpcre.so.1.2.0 파일을 업로드 해줄 수 있음
이런 경우 아래와 같이 복구를 시도해 볼 수 있다.
온라인 복구
# cat /nfs-vols/libpcre.so. 1.2 . 0 > /usr/lib64/libpcre.so. 1.2 . 0 # ls / bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var |
- 이슈가 발생되면 콘솔 접속도 불가하기 때문에 온라인 상태에서 복구는 어렵다.
- 따라서 오프라인 복구를 시도해야 한다.
오프라인 복구
CentOS 7 설치 DVD로 trouble shooting 모드로 부팅으로 하고 아래와 같이 libpcre.so.1.2.0 파일을 복구한다.
DVD로 부팅 (해당 OS 버전의 DVD로 부팅)
- root 파일시스템의 디바이스명 (/dev/centos/root) 는 서버별로 상이할 수 있다.
- DVD를 통해 부팅된 임시 Live OS의 libpcre.so.1.2.0 파일을 Disk의 root 파일시스템에 복사하여 복원하는 것이다.
- 복사 후 exit 를 입력하여 서버를 재부팅한다.
- 2020.12.22 내용추가: mount 없이, # cp /usr/lib64/libpcre.so.1.2.0 /mnt/sysimage/usr/lib64 만 해도 된다.
libpcre 뿐만 아니라 libc와 같은 주요 라이브러리에 문제가 발생을 하더라도 시스템 운용에 치명적인 문제점이 발생된다.
위 내용을 참조하여 라이브러리 문제를 복구해 볼 수 있다.
안녕하세요. 주인장님.
본문내용 중
# mount -o rw /dev/centos/root /mnt
# cp /usr/lib64/libpcre.so.1.2.0 /mnt/usr/lib64
위 방법 외에
/dev/centos/root를 /mnt로 마운트 시키지 말고
# cp /usr/lib64/libpcre.so.1.2.0 /mnt/sysimage/usr/lib64
이렇게 해도 괜찮을지요?
안녕하세요, 상훈님.
rescure 모드 진입 시 이미 root 영역이 /mnt/sysimage에 마운트 되어 있으므로,
mount -o rw /dev/centos/root /mnt 와 같이 다시 마운트 할 필요가 없겠네요.
따라서 말씀하신대로 바로 cp 해도 되겠습니다.