손상된 initrd를 원격으로 디버깅하는 방법은 무엇입니까?

손상된 initrd를 원격으로 디버깅하는 방법은 무엇입니까?

배경

Linux를 실행하는 시스템이 있습니다. 모니터, 키보드, 직렬 포트가 없는 NAS입니다. 네트워크 포트가 있습니다. 실행 중인 소프트웨어가 마음에 들지 않아 다른 배포판을 실행하려고 합니다.

내가 소유한 것

기존 시스템에서는 웹 인터페이스를 사용하여 ROM을 업그레이드하여 새 커널을 얻고 initrd를 부팅할 수 있었지만 그 업그레이드는 커널, initrd의 압축을 풀고 kexec다음을 실행하는 kexec것에 지나지 않는 특수 제작된 이미지였습니다. 매개변수를 사용하여 새 커널을 부팅하려면 필요합니다.

initrd는 네트워크 연결을 설정하고 SSH 서버(dropbear)를 시작한 후 완료될 때까지 기다립니다. 그런 다음 다른 스크립트를 실행합니다. 이를 사용하여 몇 가지 테스트를 수행할 수 있습니다. 해당 커널/initrd로 부팅하고, SSH를 통해 로그인하고, stage-2 스크립트를 사용자 정의하고, dropbear를 종료하고, 최선을 다할 수 있습니다.

이 방법을 사용하여 하드 드라이브에 작동하는 운영 체제를 성공적으로 설치했습니다. (현재는 NixOS가 중요하지만 나중에 변경할 수도 있습니다. 하지만 제 질문은 특정 배포판에 관한 것이 아닙니다.) 저는 의도적으로아니요부팅 가능하게 만드세요. 플래시를 그대로 유지하여 하드 드라이브의 데이터를 제외하고 NAS가 여전히 "공식"임을 확인하고 싶습니다. 그러나 배포판 자체 커널과 initrd를 얻었고 이를 업그레이드 이미지에 넣으려고 합니다.

질문

이 커널과 initrd를 사용하면 시스템을 부팅할 수 없습니다.

내 시도

배포판 설정과 내 설정을 공유 initrd로 구성했는데 계속해서 dropbear로 부팅됩니다. 그런 다음 SSH 셸에서 배포판의 init 스크립트를 실행해 보았습니다. 그러나 이는 PID 1로 실행되기 때문에 실패합니다.

그런 다음 PID 1이 임의의 명령을 받아들이도록 시도했습니다. 파이프에서 스크립트를 실행하고 원격 셸에서 해당 파이프에 기록하여 명령이 원하는 효과를 얻었는지 수동으로 확인하려고 했습니다. 그러나 이는 작동하지 않습니다. init-shell(PID 1)은 첫 번째 명령 후에 EOF를 확인하고 즉시 종료됩니다. 안녕하세요, 커널패닉입니다.

또한 systemd --system옵션을 전달하여 PID 1로 실행되는지 상관하지 않게 만든 다음 내 쉘에서 배포판의 init 스크립트를 실행하면 어떤 일이 발생하는지 테스트해 보았습니다. 이 형식에서는 문제를 재현할 수 없습니다. 그냥 작동합니다.

내 질문: 지금은 무엇입니까?

이 시점에서는 실제로 여러 명령을 실행할 수 있는 다른 방법을 찾기 위해 파이프라인 방법을 검토하고 있습니다. 명령의 출력도 볼 수 있다면 가장 좋을 것입니다.

기본적으로: 실제로 모니터나 직렬 케이블을 연결하지 않고는 SSH 세션에서 실행할 수 없는 PID 1에서 실행되는 부트로더의 출력을 원격으로 보는 방법을 알고 싶습니다.

완전히 다른 접근 방식을 취하는 답변도 환영하지만 제가 다루고 있는 시스템 제한 사항을 염두에 두십시오. 모니터나 직렬 케이블이 없을 뿐만 아니라 VGA나 직렬 포트도 없습니다. 원할 경우 키보드를 연결할 수 있는 USB 포트가 있지만 당연히 내가 입력하는 내용은 아무것도 표시되지 않습니다.

답변1

이를 달성하기 위한 일반적인 아이디어는 init를 백그라운드에서 initrd 기반 부팅 스크립트를 생성하고 시스템 루트 디렉터리를 계속 마운트하고 [ -x /root/sbini/init ] && exec chroot /root를 실행하는 스크립트로 바꾸는 것입니다. /sbin /초기화. (존재하지 않는 경우를 처리하려면 아래에 일부 코드를 넣으십시오.)

답변2

SSH 세션이 시작되면 다른 세션도 여기에 쓸 수 있습니다 /dev/pts/<N>. 따라서 무슨 일이 일어나고 있는지 확인하려면 어떤 PID 1이 실행될지 제어할 수 있으므로 거기에 쓰기만 하면 됩니다. PID 1을 사용하여 exec 0<>/dev/pts/0 1<>/dev/pts/0 2<>/dev/pts/0다른 어떤 것도 읽거나 쓰지 않는지 확인하면 무슨 일이 일어나고 있는지 알 수 있습니다. 마침내 실패했을 때 배포판의 init 스크립트는 무엇을 해야 할지 묻는 메시지를 표시했고 심지어 R다시 시작하라는 입력에 올바르게 응답하기도 했습니다.

내가 겪고 있는 실제 문제는 필수 커널 모듈이 로드되지 않았기 때문에 발생한 것 같습니다. 모든 것을 수동으로 작동시킬 수 있었는데 이는 분명히 블록, RAID 및 파일 시스템 모듈을 사용할 수 있고 로드할 수 있다는 것을 의미했지만 배포판의 initscript는 udev에 의존했으며 특히 여기에는 몇 가지 추가 모듈이 필요하다는 것이 밝혀졌습니다 unix. 커널에 직접 빌드하지 않을 수 있는 옵션은 없습니다.)

관련 정보