socat를 사용하여 localhost를 HTTPS로 프록시하면 처음으로 연결이 거부됩니다.

socat를 사용하여 localhost를 HTTPS로 프록시하면 처음으로 연결이 거부됩니다.

https://termbin.com/9hc2kBash 리디렉션을 사용하고 페이지를 가져오려고 합니다 socat. 특히 특수 파일을 사용하여 /dev/tcp/localhost/8080네트워크 연결을 열려고 합니다.

# fetch.sh
# fetch uploaded text from termbin.com

url=$1

# check if url is provided as argument
if [[ $# -lt 1 ]]; then
    echo "error: provide url" >&2
    echo >&2
    echo "Usage: fetch.sh [url]" >&2
    exit 1
fi

n1=$'\r\n'
request=$(cat <<END
GET /${url}/ HTTP/1.1
Host: termbin.com
Connection: close
$n1 
$n1
END
)
#echo "$request"

socat TCP-LISTEN:8080,fork,reuseaddr ssl:termbin.com:443,verify=0 &
socat_pid=$!
exec 3<>/dev/tcp/localhost/8080
echo "$request" >&3
cat <&3

exec 3>&-

내가 얻으려고하면 https://termbin.com/9hc2k:

$ ./fetch.sh 9hc2k
./fetch.sh: connect: Connection refused
./fetch.sh: line 26: /dev/tcp/localhost/8080: Connection refused
./fetch.sh: line 27: 3: Bad file descriptor
./fetch.sh: line 28: 3: Bad file descriptor

처음으로 연결 거부 오류가 발생했습니다.

하지만 다시 시도해 보면,

$ ./fetch.sh 9hc2k
2022/07/30 12:29:18 socat[497218] E bind(5, {AF=2 0.0.0.0:8080}, 16): Address already in use
HTTP/1.1 200 OK
Server: nginx
Date: Sat, 30 Jul 2022 02:29:20 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 6
Last-Modified: Sat, 30 Jul 2022 01:51:42 GMT
Connection: close
ETag: "62e48eae-6"
Accept-Ranges: bytes

hello

보시다시피 두 번째 시도에서는 작동합니다. hello링크에서 텍스트를 가져왔습니다 .

처음에는 실패하고 두 번째(및 후속)에는 작동하는 이유를 모르겠습니다. 왜 이런 일이 발생하는지, 그리고 가장 합리적인 해결책은 무엇인지 말해주실 수 있나요? 감사해요.

답변1

내 생각엔 exec 3<>/dev/tcp/localhost/8080그런 일이 있었던 것 같아너무 빨라그 이후에는 socat … &아직 socat준비가 되지 않았습니다.

귀하의 스크립트는 생성된 것을 죽이지 않습니다 socat. 다시 시도하면 이전 연결이 socat이미 존재하며 새 연결을 처리할 수 있습니다.

sleep 1당신이 가기 전에 빠르고 더러운 수정이 필요합니다 exec 3<>…. 더 나은 해결책은 exec 3<>…성공할 때까지 또는 시도 횟수가 합리적인 임계값에 도달할 때까지(그런 다음 실패했다고 가정할 때까지) 주기적으로 시도하고 다시 시도하는 것입니다.kill -s 0 "$socat_pid"socat실패합니다(그러면 어떤 이유로 종료되었음을 알 수 있습니다 ).

답변2

설명해 주신 Camille에게 감사드립니다. 결국 socat pid의 상태를 모니터링하여 "S"로 변경하여 문제를 해결했습니다.

이것은 내 고정 코드입니다.

# fetch uploaded text from termbin.com

url=$1

# check if url is provided as argument
if [[ $# -lt 1 ]]; then
    echo "error: provide url" >&2
    echo >&2
    echo "Usage: fetch.sh [url]" >&2
    exit 1
fi

n1=$'\r\n'
request=$(cat <<END
GET /${url}/ HTTP/1.1
Host: termbin.com
Connection: close
$n1 
$n1
END
)
#echo "$request"

socat TCP-LISTEN:8080,fork,reuseaddr ssl:termbin.com:443,verify=0 &
socat_pid=$!

# loop until socat's pid status becomes 'S'
while [[ -z $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; do
    :
done

exec 3<>/dev/tcp/localhost/8080
echo "$request" >&3
cat <&3

# if socat's pid status is 'S' then kill it
if [[ -n $(ps -p $socat_pid -o stat --no-headers | grep 'S') ]]; then
    kill -9 $socat_pid
fi

exec 3>&-

관련 정보