연결 실패로 인해 socat 상위 프로세스가 종료되었습니다.

연결 실패로 인해 socat 상위 프로세스가 종료되었습니다.

짧은 질문

분기된 프로세스에 대한 연결 시도가 실패하면 socat상위 프로세스가 종료되는 것으로 보입니다. 이것은 버그입니까? 이에 대한 가장 좋은 해결책은 무엇입니까?

긴 질문

socatOpenSSL 암호화(서버 인증용)를 사용하여 서버(socat 버전 1.7.3.1 및 1.7.3.2)를 실행하고 있습니다 . 다음 명령을 사용하여 서버를 시작합니다.

socat -d -d -d -d -U \
-lf /var/log/socat.log \
openssl-listen:8888,fork,reuseaddr,cert=server.pem,dhparam=dhparam.pem,verify=0 \
gopen:"file.txt" &

저는 fork서버에 대한 각 연결이 별도의 하위 프로세스에서 실행되도록 이 옵션을 사용하고 있습니다. 다음 클라이언트 명령을 사용하여 서버에 성공적으로 연결할 수 있습니다.

socat - openssl-connect:hostname:8888,cafile=server.crt

또한 서버 인증서를 제공하지 않고 연결을 시도했습니다. 예:

socat - openssl-connect:hostname:8888

이 작업을 수행하면 예상대로 다음 오류가 발생합니다.

YYYY/mm/dd HH:MM:SS socat[3464] E SSL_connect(): error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed

그러나 서버 프로세스도 종료됩니다. 이것은 예상치 못한 일입니다. netcat 연결 시도와 같이 실패한 다른 연결 시도에서도 비슷한 결과를 얻었습니다.

nc hostname 8888

이 경우 연결을 종료할 때까지 연결이 중단됩니다. 그러나 이전과 마찬가지로 현재 연결 시도(자식 프로세스)뿐만 아니라 서버(상위 프로세스)도 종료됩니다.

로그 파일을 확인해 보았습니다. 연결을 시도하는 동안 다음 메시지가 로그 파일에 기록됩니다.

 1  YYYY/mm/dd HH:MM:SS socat[PPID] D select -> (, 0x40, 0x0, 0x0, NULL/0.000000), 1
 2  YYYY/mm/dd HH:MM:SS socat[PPID] D accept(6, 0xbedc0224, 0xbedc020c)
 3  YYYY/mm/dd HH:MM:SS socat[PPID] I accept(6, {2, AF=2 127.0.0.1:54862}, 16) -> 7
 4  YYYY/mm/dd HH:MM:SS socat[PPID] D fcntl(7, 2, 1)
 5  YYYY/mm/dd HH:MM:SS socat[PPID] D fcntl() -> 0
 6  YYYY/mm/dd HH:MM:SS socat[PPID] D getpeername(7, 0xbedc0234, 0xbedc021c{16})
 7  YYYY/mm/dd HH:MM:SS socat[PPID] D getpeername(, {AF=2 127.0.0.1:54862}, {16}) -> 0
 8  YYYY/mm/dd HH:MM:SS socat[PPID] D getsockname(7, 0xbedc02a4, 0xbedc0220{16})
 9  YYYY/mm/dd HH:MM:SS socat[PPID] D getsockname(, {AF=2 127.0.1.1:8888}, {16}) -> 0
10  YYYY/mm/dd HH:MM:SS socat[PPID] N accepting connection from AF=2 127.0.0.1:54862 on AF=2 127.0.1.1:8888
11  YYYY/mm/dd HH:MM:SS socat[PPID] I permitting connection from AF=2 127.0.0.1:54862
12  YYYY/mm/dd HH:MM:SS socat[PPID] D sigprocmask(0, 0xbedc0314, 0x0)
13  YYYY/mm/dd HH:MM:SS socat[PPID] D sigprocmask() -> 0
14  YYYY/mm/dd HH:MM:SS socat[PPID] D fork()
15  YYYY/mm/dd HH:MM:SS socat[PPID] D fork() -> PID
16  YYYY/mm/dd HH:MM:SS socat[PPID] N forked off child process PID
17  YYYY/mm/dd HH:MM:SS socat[PPID] I close(7)
18  YYYY/mm/dd HH:MM:SS socat[PPID] D close()  -> 0
19  YYYY/mm/dd HH:MM:SS socat[PPID] D sigprocmask(1, 0xbedc0314, 0x0)
20  YYYY/mm/dd HH:MM:SS socat[PPID] D sigprocmask() -> 0
21  YYYY/mm/dd HH:MM:SS socat[PPID] I still listening
22  YYYY/mm/dd HH:MM:SS socat[PPID] N listening on AF=2 0.0.0.0:8888
23  YYYY/mm/dd HH:MM:SS socat[PPID] D select(7, &0x48, &0x0, &0x0, NULL/0.000000)
24  YYYY/mm/dd HH:MM:SS socat[PID] D fork() -> 0
25  YYYY/mm/dd HH:MM:SS socat[PID] D getpid()
26  YYYY/mm/dd HH:MM:SS socat[PID] D getpid() -> PID
27  YYYY/mm/dd HH:MM:SS socat[PID] I just born: child process PID
28  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_PID", "0", 1)
29  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
30  YYYY/mm/dd HH:MM:SS socat[PID] D getpid()
31  YYYY/mm/dd HH:MM:SS socat[PID] D getpid() -> PID
32  YYYY/mm/dd HH:MM:SS socat[PID] D sigprocmask(1, 0xbedc0314, 0x0)
33  YYYY/mm/dd HH:MM:SS socat[PID] D sigprocmask() -> 0
34  YYYY/mm/dd HH:MM:SS socat[PID] I just born: child process PID
35  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_PID", "PID", 1)
36  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
37  YYYY/mm/dd HH:MM:SS socat[PID] I close(6)
38  YYYY/mm/dd HH:MM:SS socat[PID] D close()  -> 0
39  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_SOCKADDR", "127.0.1.1", 1)
40  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
41  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_SOCKPORT", "8888", 1)
42  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
43  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_PEERADDR", "127.0.0.1", 1)
44  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
45  YYYY/mm/dd HH:MM:SS socat[PID] D setenv("SOCAT_PEERPORT", "54862", 1)
46  YYYY/mm/dd HH:MM:SS socat[PID] D setenv() -> 0
47  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_new(0x231f868)
48  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_new() -> 0x2320f00
49  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_set_fd(0x2320f00, 7)
50  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_set_fd() -> 1
51  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_accept(0x2320f00)
52  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_accept() -> -1
53  YYYY/mm/dd HH:MM:SS socat[PID] E SSL_accept(): Success
54  YYYY/mm/dd HH:MM:SS socat[PID] N exit(1)
55  YYYY/mm/dd HH:MM:SS socat[PID] D starting xioexit()
56  YYYY/mm/dd HH:MM:SS socat[PID] D SSL_shutdown(0x2320f00)
57  YYYY/mm/dd HH:MM:SS socat[PPID] N socat_signal(): handling signal 11
58  YYYY/mm/dd HH:MM:SS socat[PPID] D select -> (, 0x8, 0x0, 0x0, NULL/0.000000), 1
59  YYYY/mm/dd HH:MM:SS socat[PPID] D select(7, &0x48, &0x0, &0x0, NULL/0.000000)
60  YYYY/mm/dd HH:MM:SS socat[PPID] E exiting on signal 11
61  YYYY/mm/dd HH:MM:SS socat[PPID] N exit(139)
62  YYYY/mm/dd HH:MM:SS socat[PPID] D starting xioexit()
63  YYYY/mm/dd HH:MM:SS socat[PPID] I close(6)
64  YYYY/mm/dd HH:MM:SS socat[PPID] D close()  -> 0
65  YYYY/mm/dd HH:MM:SS socat[PPID] D finished xioexit()

따라서 하위 프로세스에 분할 오류(신호 11)가 있어 상위 프로세스가 종료되는 것처럼 보입니다. 현재 해결 방법은 다음과 같이 루프에서 socat 명령을 실행하는 것입니다.

while true; do
socat -d -d -d -d -U \
-lf /var/log/socat.log \
openssl-listen:8888,fork,reuseaddr,cert=server.pem,dhparam=dhparam.pem,verify=0 \
gopen:"file.txt" &
done

그러나 이는 그다지 우아해 보이지는 않습니다. 더 나은 솔루션이 있어야 합니다.

관련 정보