짧은 질문
분기된 프로세스에 대한 연결 시도가 실패하면 socat
상위 프로세스가 종료되는 것으로 보입니다. 이것은 버그입니까? 이에 대한 가장 좋은 해결책은 무엇입니까?
긴 질문
socat
OpenSSL 암호화(서버 인증용)를 사용하여 서버(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
그러나 이는 그다지 우아해 보이지는 않습니다. 더 나은 솔루션이 있어야 합니다.