
sftp 전송은 약 1/5번 정도 실패하고 client_loop: send disconnect: Broken pipe
제 경우에는 보고됩니다. sshd 로그에 다음이 표시됩니다. forced close
대신 closed
파일이 예상보다 작을 수 있습니다. 약 1/5번(위 메시지와 함께 sftp가 실패하는 경우)에 파일은 정상입니다. 이는 아마도 파일 전송 직후 연결이 끊어졌음을 의미할 것입니다.
server1: OpenSSH_8.0p1, OpenSSL 1.1.1c FIPS 2019년 5월 28일(CentOS 8.2.2004)
server2: OpenSSH_8.3p1, OpenSSL 1.1.1g FIPS 2020년 4월 21일(Fedora 32)
client1: OpenSSH_8.3p1, OpenSSL 1.1.1g FIPS 21 2020년 4월(Fedora 32)
client2: OpenSSH_6.6.1p1, OpenSSL 1.0.1e-fips 2013년 2월 11일(RHEL/CentOS 7.2)
명령(sthg like): (아래 긴 버전)f=file.pdf echo -e "-ls -l $f\nput $f\nls -l $f" | sftp -b- [email protected]:/upload
다음은 관련성이 없어 보입니다(다른 곳에서 보고되고 때로는 "해결책"으로 제공되기는 하지만).
ChrootDirectory
서버 측 옵션 (sshd)- 서버 측의 홈 디렉토리 퍼미션
-oIPQoS=throughput
서버 및/또는 클라이언트의 옵션- 서버 네트워크 인터페이스의 MTU 크기(1200과 1500을 시도했습니다)
- 서버 측 방화벽/게이트웨이의 트래픽 조절/QoS 설정
- iptables/firewalld를 통한 TCP MSS 설정
하지만 두 가지 옵션이 모두 있는 경우
-B1500
-oCiphers=aes128-cbc
사용하면 오류율이 훨씬 낮아집니다. a -B1000 OR -oCiphers=aes256-cbc OR -oCiphers=aes128-ctr은 오류 수준을 높입니다.
내가 사용하는 최상의 결과는 다음과 -oCiphers=aes128-cbc -oBatchMode=yes -oCompression=no -oIPQoS=throughput -oRequestTTY=no -B1500
같습니다.
- 109kbyte 파일의 1216개 전송에서 4개의 오류(0.33% 불량)
- 6.81mbyte 파일의 2695개 전송에서 10개 오류(0.37% 불량)
vmware 호스트에 sftp/scp sthg를 시도할 때도 동일한(또는 유사한?) 일이 발생합니다. "깨진 파이프"는 "put" 명령 직후에 보고됩니다. -B 옵션만 도움이 되는 것으로 나타났습니다. 제 경우에는 -B265가 안정적인 결과를 주었습니다. -B266은 한 번 작동했지만 항상(자주 시도하지는 않았습니다) "깨진 파이프"였습니다. 실제로 OS 이미지를 로컬 데이터 저장소로 전송하고 있었습니다.
서버: OpenSSH_7.9p1, OpenSSL 1.0.2r-fips 2019년 2월 26일(ESXi 6.7?)
클라이언트: OpenSSH_7.4p1, OpenSSL 1.0.2k-fips 2017년 1월 26일(Fedora 25)
어쩌면 누군가 여기서 무슨 일이 일어나고 있는지 알아낼 수 있을 것입니다. openssl과 관련하여 문제가 있는 것처럼 느껴집니다. 아마도 openssh와 결합되어 있을 수 있습니다. 반드시 sftp 자체와 관련이 있는 것은 아닙니다.
나는 실제로 사용하고 있습니다
dd if=/dev/urandom of=x.rand bs=1021 count=6999
n=1; f=x.rand; while true; do
echo "=== $n ==="
date
echo -e "-ls -l $f\nput $f\nls -l $f" \
| sftp -b- -oPort=22 -B1500 -oCiphers=aes128-cbc -oBatchMode=yes -oCompression=no -oIPQoS=throughput -oRequestTTY=no [email protected]:/upload
n=`expr $n + 1`
sleep 0.1
done 2>&1 | tee output_x_rand.log
이것을 테스트하기 위해.
sshd_config:
Match User user
ForceCommand internal-sftp -m 640 -e -P remove,mkdir,rmdir,symlink,posix-rename,hardlink,readlink,setstat,fsetstat,lsetstat,statvfs,fstatvfs -l INFO
PasswordAuthentication no
GSSAPIAuthentication no
HostbasedAuthentication no
KbdInteractiveAuthentication no
KerberosAuthentication no
PubkeyAuthentication yes
ChrootDirectory /var/transfer/incoming
PermitTunnel no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
이것이 (strace) 일어나는 일입니다섬기는 사람, 연결이 끊어진 경우:
168224 read(5, 0x7fff0f71e350, 16384) = -1 ECONNRESET (Connection reset by peer)
168224 getpid() = 168224
168224 getuid() = 1000
168224 write(9, "\0\0\0{|", 5) = 5
168211 <... poll resumed>) = 1 ([{fd=12, revents=POLLIN}])
168224 write(9, "\0\0\0fSHA256:fc:5f:4c:91:1a:75:eb:"..., 122 <unfinished ...>
168211 read(12, <unfinished ...>
168224 <... write resumed>) = 122
168211 <... read resumed>"\0\0\0{", 4) = 4
168224 getuid( <unfinished ...>
168211 read(12, <unfinished ...>
168224 <... getuid resumed>) = 1000
168211 <... read resumed>"|\0\0\0fSHA256:fc:5f:4c:91:1a:75:eb"..., 123) = 123
168224 getpid( <unfinished ...>
168211 socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT <unfinished ...>
168224 <... getpid resumed>) = 168224
168211 <... socket resumed>) = 9
168224 write(9, "\0\0\0\25z", 5 <unfinished ...>
168211 fcntl(9, F_SETFD, FD_CLOEXEC <unfinished ...>
168224 <... write resumed>) = 5
168211 <... fcntl resumed>) = 0
168224 write(9, "\0\0\0\2\0\0\0\0\0\2\221 \0\0\0\0\0\0\3\350", 20 <unfinished ...>
168211 ioctl(0, TCGETS <unfinished ...>
168224 <... write resumed>) = 20
168211 <... ioctl resumed>, 0x7fff0f71fbe0) = -1 ENOTTY (Inappropriate ioctl for device)
168224 read(9, <unfinished ...>
168211 ioctl(1, TCGETS, 0x7fff0f71fbe0) = -1 ENOTTY (Inappropriate ioctl for device)
168211 ioctl(2, TCGETS, 0x7fff0f71fbe0) = -1 ENOTTY (Inappropriate ioctl for device)
168211 sendto(9, {{len=244, type=0x964 /* NLMSG_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=15, pid=0}, "\x6f\x70\x3d\x64\x65\x73\x74\x72\x6f\x79\x20\x6b\x69\x6e\x64\x3d\x73\x65\x72\x76\x65\x72\x20\x66\x70\x3d\x53\x48\x41\x32\x35\x36"...}, 244, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 244
168211 poll([{fd=9, events=POLLIN}], 1, 500) = 1 ([{fd=9, revents=POLLIN}])
168211 recvfrom(9, {{len=36, type=NLMSG_ERROR, flags=NLM_F_CAPPED, seq=15, pid=168211}, {error=0, msg={len=244, type=0x964 /* AUDIT_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=15, pid=0}}}, 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, [12]) = 36
168211 recvfrom(9, {{len=36, type=NLMSG_ERROR, flags=NLM_F_CAPPED, seq=15, pid=168211}, {error=0, msg={len=244, type=0x964 /* AUDIT_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=15, pid=0}}}, 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, [12]) = 36
168211 close(9) = 0
168211 poll([{fd=12, events=POLLIN}], 1, -1) = 1 ([{fd=12, revents=POLLIN}])
168211 read(12, "\0\0\0\25", 4) = 4
168211 read(12, "z\0\0\0\2\0\0\0\0\0\2\221 \0\0\0\0\0\0\3\350", 21) = 21
168211 getsockname(5, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("172.17.17.2")}, [128->16]) = 0
168211 socket(AF_NETLINK, SOCK_RAW, NETLINK_AUDIT) = 9
168211 fcntl(9, F_SETFD, FD_CLOEXEC) = 0
168211 ioctl(0, TCGETS, 0x7fff0f71fbb0) = -1 ENOTTY (Inappropriate ioctl for device)
168211 ioctl(1, TCGETS, 0x7fff0f71fbb0) = -1 ENOTTY (Inappropriate ioctl for device)
168211 ioctl(2, TCGETS, 0x7fff0f71fbb0) = -1 ENOTTY (Inappropriate ioctl for device)
168211 sendto(9, {{len=196, type=0x964 /* NLMSG_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=16, pid=0}, "\x6f\x70\x3d\x64\x65\x73\x74\x72\x6f\x79\x20\x6b\x69\x6e\x64\x3d\x73\x65\x73\x73\x69\x6f\x6e\x20\x66\x70\x3d\x3f\x20\x64\x69\x72"...}, 196, 0, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 196
168211 poll([{fd=9, events=POLLIN}], 1, 500) = 1 ([{fd=9, revents=POLLIN}])
168211 recvfrom(9, {{len=36, type=NLMSG_ERROR, flags=NLM_F_CAPPED, seq=16, pid=168211}, {error=0, msg={len=196, type=0x964 /* AUDIT_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=16, pid=0}}}, 8988, MSG_PEEK|MSG_DONTWAIT, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, [12]) = 36
168211 recvfrom(9, {{len=36, type=NLMSG_ERROR, flags=NLM_F_CAPPED, seq=16, pid=168211}, {error=0, msg={len=196, type=0x964 /* AUDIT_??? */, flags=NLM_F_REQUEST|NLM_F_ACK, seq=16, pid=0}}}, 8988, MSG_DONTWAIT, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, [12]) = 36
168211 close(9) = 0
168211 write(12, "\0\0\0\1{", 5 <unfinished ...>
168224 <... read resumed>"\0\0\0\1", 4) = 4
168211 <... write resumed>) = 5
168224 read(9, <unfinished ...>
168211 poll([{fd=12, events=POLLIN}], 1, -1 <unfinished ...>
168224 <... read resumed>"{", 1) = 1
168224 exit_group(255) = ?
168225 <... select resumed>) = 1 (in [0])
168224 +++ exited with 255 +++
168225 read(0, <unfinished ...>
168211 <... poll resumed>) = ? ERESTART_RESTARTBLOCK (Interrupted by signal)
168225 <... read resumed>"", 16384) = 0
168211 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=168224, si_uid=1000, si_status=255, si_utime=0, si_stime=1} ---
168225 write(2, "forced close \"/upload/xx.rand\" b"..., 60 <unfinished ...>
168211 restart_syscall(<... resuming interrupted poll ...> <unfinished ...>
168225 <... write resumed>) = -1 EPIPE (Broken pipe)
168225 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=168225, si_uid=1000} ---
168225 +++ killed by SIGPIPE +++
이것이 (strace) 일어나는 일입니다고객, 연결이 끊어진 경우:
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48403 mmap(NULL, 2019328, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00c3731000
48403 munmap(0x7f00c391e000, 2002944) = 0
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48402 <... writev resumed>) = 32797
48403 mmap(NULL, 2035712, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 <unfinished ...>
48402 read(3, <unfinished ...>
48403 <... mmap resumed>) = 0x7f00c3afb000
48402 <... read resumed>"\0\0\0\30", 4) = 4
48402 read(3, "e\0\0\0\f\0\0\0\0\0\0\0\7Success\0\0\0\0", 24) = 24
48402 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 32768) = 32768
48402 writev(3, [{iov_base="\0\0\200\31", iov_len=4}, {iov_base="\6\0\0\0M\0\0\0\4\0\0\0\0\0\0\0\0\0#\0\0\0\0\200\0\0\0\0\0\0\0\0"..., iov_len=32793}], 2) = 32797
48402 read(3, <unfinished ...>
48403 munmap(0x7f00c3731000, 2019328) = 0
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48403 mmap(NULL, 2052096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00c3906000
48403 munmap(0x7f00c3afb000, 2035712) = 0
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48403 mmap(NULL, 2068480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00c370d000
48403 munmap(0x7f00c3906000, 2052096) = 0
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48403 mmap(NULL, 2084864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00c3aef000
48403 munmap(0x7f00c370d000, 2068480) = 0
48403 select(7, [3 4], [3], NULL, {tv_sec=59, tv_usec=0}) = 1 (in [4], left {tv_sec=58, tv_usec=999997})
48403 read(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 16384) = 16384
48403 mmap(NULL, 2101248, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f00c38ee000
48403 munmap(0x7f00c3aef000, 2084864) = 0
48403 select(7, [3], [3], NULL, {tv_sec=59, tv_usec=0}) = 2 (in [3], out [3], left {tv_sec=58, tv_usec=981048})
48403 read(3, 0x7ffc9bb9c500, 8192) = -1 ECONNRESET (Connection reset by peer)
48403 rt_sigaction(SIGWINCH, {sa_handler=SIG_DFL, sa_mask=~[RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f00c3f83ab0}, {sa_handler=0x55ff7bcc73f0, sa_mask=~[KILL STOP RTMIN RT_1], sa_flags=SA_RESTORER|SA_RESTART, sa_restorer=0x7f00c3f83ab0}, 8) = 0
48403 getpid() = 48403
48403 write(3, "\364\3301X\302Y\34\361\310:\323\275\315!Hy\334;\312\201\231\273\217\17h\363)&\207bD7"..., 154924) = -1 EPIPE (Broken pipe)
48403 --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=48403, si_uid=1000} ---
48403 write(2, "client_loop: send disconnect: Br"..., 43) = 43
48403 exit_group(255) = ?
48402 <... read resumed>0x5611a3af2810, 4) = -1 ECONNRESET (Connection reset by peer)
48403 +++ exited with 255 +++
48402 --- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=48403, si_uid=1000, si_status=255, si_utime=15, si_stime=24} ---
48402 wait4(48403, NULL, WNOHANG, NULL) = 48403
48402 write(2, "\rConnection closed. \n", 22) = 22
48402 rt_sigreturn({mask=[]}) = -1 ECONNRESET (Connection reset by peer)
48402 write(2, "Connection closed\r\n", 19) = 19
48402 exit_group(255) = ?
48402 +++ exited with 255 +++
답변1
좋아요. 메라키 위협 방지, 침입 방지까지 추적했습니다.
- https://community.cisco.com/t5/network-security/can-sftp-packets-trigger-ssh-event-respoverflow-events-in-ips/td-p/2933423
- https://bst.cloudapps.cisco.com/bugsearch/bug/CSCze89434/?rfs=iqvred
- https://community.meraki.com/t5/Security-SD-WAN/SFTP-session-disconnecting/td-p/49244
IPS 규칙 SSH_EVENT_RESPOVERFLOW가 화이트리스트에 있는 경우 오류가 사라집니다.
그럼에도 불구하고 IPS 규칙을 허용하는 것은 적절한 해결책이 아니라고 생각합니다. IPS 규칙은 오탐을 방지하기 위해 더 나은 방법으로 침입을 감지해야 합니다.