openssl s_client를 사용하여 명령줄에서 https 서버로부터 파일 가져오기

openssl s_client를 사용하여 명령줄에서 https 서버로부터 파일 가져오기

https 서버에서 호스팅되는 파일이 있고 다음을 openssl s_client사용하여 해당 파일을 내 클라이언트로 전송할 수 있기를 원합니다 openssl s_client -connect <my_ip:my_port>/my_file.

현재는 명령을 실행한 다음 를 입력하여 파일의 내용을 가져올 수 있지만 GET my_file대화형이 아니도록 자동화하고 싶습니다. -quiet스위치를 사용해 도 도움이 되지 않습니다.

참고: 제가 이 제품을 사용하려는 장치에는 다른 파일 전송 프로그램이 없으므로 계속 사용하겠습니다.openssl

답변1

실제로 HTTP/0.9를 사용할 수 있다면 이것이 효과가 있을 것입니다.

printf '%s\r\n\r\n' 'GET my_file' | openssl s_client -connect <my_ip:my_port>

답변2

openssl s_client특별히 좋은 도구는 아니지만 수행할 수 있습니다. 두 부분으로 나누어 보겠습니다. 먼저 HTTP 요청이 이루어진 다음 응답에서 콘텐츠가 추출됩니다.

HTTP 요청하기

여기서 가장 어려운 부분은 s_client표준 입력이 닫힐 때 연결을 닫는 것입니다. 따라서 연결이 닫힐 때까지 stdin을 열어 두어야 합니다. 기반으로이 서버 오류 답변, 다음과 같이 할 수 있습니다.

(printf "GET $PATH HTTP/1.0\r\nHost: $HOST\r\n\r\n"; sleep 10) | \
    openssl s_client -connect $HOST:443 -quiet) > /tmp/output.tmp

여기에는 몇 가지 큰 제한이 있습니다. 먼저 sleep전송이 완료될 때까지 충분히 길게 설정해야 합니다 . 하지만 영원히 기다릴 만큼 길지는 않을 것입니다. 둘째, 리디렉션 처리가 없으므로 302다른 곳으로 이동하지 않고 요청한 URL에서 직접 데이터를 제공하는 URL이 필요합니다.

데이터 추출

/tmp/output.tmp이제 데이터가 포함된 HTTP 응답이 포함된 파일이 생겼습니다 .그리고일부 제목. 헤더를 제거하는 것은 생각보다 어렵습니다. 새 줄 \r\n과 줄 바꿈을 혼합 \n하고 바이너리 데이터를 전송할 수 있기 때문입니다.

파일이 Unix 스타일 텍스트(예: 쉘 스크립트)인 경우 모든 \r문자를 제거하고 첫 번째 빈 줄을 포함하여 모든 것을 삭제할 수 있습니다.

tr -d '\r' < /tmp/output.tmp | sed '1,/^$/d' > /tmp/output

파일이 바이너리(예: 실행 파일)인 경우 문자만 제거할 수는 없습니다 \r. 파일의 처음 몇 바이트가 매우 고유하고( \xF7ELF이 예에서는 가정) GNU grep을 사용할 수 있다고 가정하면 다음을 수행할 수 있습니다.

SKIP=$(grep -aboF "$(printf "\xf7ELF")" output | head -1 | awk -F: '{print $1}')
dd ibs=1 if=/tmp/output.tmp of=/tmp/output skip=$SKIP

관련 정보