본문 바로가기
지난 블로그에서는 FTP를 이용한 파일 전송 자동화에 대해 다루었습니다. FTP 사용에는 세 가지 문제가 있습니다. 첫째, 비밀번호가 네트워크를 통해 평문으로 전송되어 프로토콜 분석기를 가진 누구에게나 노출될 수 있습니다. 둘째, 데이터 역시 평문으로 전송됩니다. 셋째, 모듈 내 어레이나 .netrc 파일에 비밀번호를 기록해야 합니다. 이러한 문제점들로 인해 많은 사이트에서 FTP 대신 SSH의 보안 FTP 하위 시스템인 SFTP 사용을 의무화하거나 의무화할 계획입니다. 그러나 명령어 어레이에서 ftp를 sftp로 단순히 대체한다고 해서(그림 1) 제대로 작동할 것이라고 기대할 수는 없습니다(그림 2).

 

&attach_input
sftp 172.16.1.116
nd
MYPASSWORD
put foo
&if (command_status) ^= 226 &then &goto ERROR1
get bar
&if (command_status) ^= 226 &then &goto ERROR2
quit
&
&label ERROR1
..display_line Could not put file
quit
&return
&
&label ERROR2
..display_line Could not get file
quit
&return

그림 1 – sftp1.cm – 명령어 매크로에서 ftp 명령어를 sftp로 대체

 

sftp1
Connecting to 172.16.1.116...
dup2: Bad file number.
Error on line 3 of sftp1.
command_processor: Object not found. nd. In command macro
%phx_vos#m15_mas>SysAdmin>Noah_Davids>sftp1.cm
ready  12:39:59

 

그림 2 – sftp1.cm 실행 중
문제는 네이티브 VOS 명령어와 POSIX 오픈소스가 입력을 처리하는 방식 간의 비호환성입니다. 그러나 SFTP는 FTP와 마찬가지로 요청 목록이 담긴 파일을 생성할 수 있게 해주며(그림 3), 이를 자동으로 실행합니다(그림 4).

 


put foo
get bar

 

그림 3 – sftp2.input – sftp가 실행할 요청을 포함하는 파일

 


sftp -b sftp2_input [email protected]
[email protected]'s password:
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:06:45

 

그림 4 – 요청 입력 파일과 비밀번호 프롬프트를 사용한 실행
그림 4에서 sftp가 비밀번호를 입력하라고 요청하는 것을 확인할 수 있습니다. 입력 파일에 비밀번호를 넣을 방법은 없습니다. 비밀번호 입력 요청을 우회할 수 있는 유일한 방법은 공개 키 인증을 사용하는 것입니다(그림 5).

 

sftp -b sftp2_input [email protected]
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/foo
sftp> get bar
Couldn't stat remote file: No such file or directory
File "/SysAdmin/Noah_Davids/bar" not found.
Ready  13:12:28

 

그림 5 – 요청 입력 파일을 사용한 실행, 비밀번호 프롬프트를 제거하기 위한 공개 키 인증 적용

 

공개 키 인증 설정 방법에 관한 글은 여기에서 확인할 수 있습니다 – http://members.cox.net/ndav1/self_published/publickey_authentication_setup.html

안타깝게도 sftp는 입력 파일에 있는 모든 요청을 단순히 차례로 실행할 뿐이며, 전송이 성공했는지 여부를 테스트할 수 있는 메커니즘이 없습니다.

명령어 매크로를 사용할 수 없다면 대안이 있을까요? gnu_tools 제품에는 expect라는 프로그램이 포함되어 있습니다. 이 프로그램은 명령어를 전송하고, 다양한 응답을 기다린 후 출력 스트림에서 확인한 내용에 따라 작업을 수행하는 데 사용할 수 있습니다. 저는 expect 전문가는 아니지만, 그림 6의 스크립트가 시작하는 데 도움이 될 것입니다. 웹에서 "expect 스크립트"를 검색하면 제 간단한 예제를 사용자 정의하는 데 도움이 될 많은 참고 자료를 찾을 수 있습니다.

 

# If we get an end-of-file (eof) it means that the sftp process
# terminated. Report the last command that was sent.
#
proc goteof {cmd} {
puts "sftp connection unexpectedly closed n"
puts "last text received wasn"
puts "<<"
puts $cmd
puts ">>nnn"
exit
}
# 이 절차는 키 문자열을 찾는 정규 표현식 일치를 수행합니다
# 실행된 명령어로부터 수집된 출력에서. 이 경우
# 저는 단지 오류 유형을 보고할 뿐이지만 다른 조치도 가능합니다
# 또한. 나도 오직 2개의 오류를 확인합니다. 다른 오류들도 있습니다. 당신은
# 발견하는 대로 추가하세요.
#
proc checkforerrors {buf cmd} {
if [정규 표현식 {.*not found} $buf] {
puts "명령어 실패: 찾을 수 없음"
1을 반환합니다
}
if [정규 표현식 {.*Permission denied} $buf] {
“$cmd 실패 : 접근 문제”를 출력합니다.
1을 반환합니다
}
0을 반환합니다
}# 타임아웃을 -1로 설정하여 타임아웃이 없도록 합니다. 기본값은 10초입니다.
# 그리고 대부분의 파일 전송은 그보다 더 오래 걸립니다. 저는 설정하지 않기로 결정했습니다.
# 타임아웃, 변경할 수 있습니다.
타임아웃 설정 -1

# sftp 시작
spawn sftp [email protected]

# sftp 프롬프트를 기다리되, 인증 프롬프트(
로 끝나는)가 나타나면 # yes/no 보안 문제를 보고하고 종료합니다.
expect {
“yes/no?” { puts
“nnn잘못된 서버에 연결되었거나 서버가 재시작되었습니다.”
puts
“이 스크립트를 다시 실행하기 전에 서버 키를 검증해야 합니다.nnn”
exit}
sftp>
}

# 테스트를 위한 편리한 디렉토리로 변경
send “cd sftp_testr”
expect {
eof { goteof “cd sftp_test” }
sftp>
}

# 모든 수집된 문자를
프롬프트로 전달하여 오류 확인 # 또한 sftp로 전송된 명령어 확인.
# checkforerrors 프로시저가 1을 반환하면 스크립트 종료. 다른 작업도 수행 가능

if {[checkforerrors $expect_out(buffer) “cd sftp_test”] == 1} { exit }

send "put foo"
expect {
eof { goteof "put foo" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "put foo"] == 1} { exit }

send "get bar"
expect {
eof { goteof "get bar" }
sftp>
}
if {[checkforerrors $expect_out(buffer) "get bar"] == 1} { exit }

"quitr"을
로 전송 eof를
에서 기대 "스크립트 완료"를 출력

 

그림 6 – sftp3.exp – SFTP 자동화를 위한 expect 스크립트

 

expect sftp3.exp
spawn sftp [email protected]
Connecting to 172.16.1.116...
The authenticity of host 172.16.1.116(172.16.1.116)' can't be established
+.
RSA key fingerprint is 37:f4:1a:56:64:af:ab:8a:7c:0b:36:47:c5:6c:1d:1a.
Are you sure you want to continue connecting (yes/no)?
잘못된 서버에 연결되었거나 서버가 재시작되었습니다.
이 스크립트를 다시 실행하기 전에 서버 키를 검증해야 합니다. 준비 완료 10:41:10

 

그림 7 – 보안 경고와 함께 sftp3.exp expect 스크립트 실행

 

expect sftp3.exp
spawn sftp [email protected]
Connecting to 172.16.1.116...
sftp> cd sftp_test
sftp> put foo
Uploading foo to /SysAdmin/Noah_Davids/sftp_test/foo
sftp> get bar
원격 파일을 찾을 수 없습니다: 해당 파일 또는 디렉터리가 없습니다
파일 "/SysAdmin/Noah_Davids/sftp_test/bar"을 찾을 수 없습니다.
sftp> get bar FAILED : not found ready 10:42:11

 

그림 8 – 경고 없이 sftp3.exp expect 스크립트 실행, 그러나 전송 실패

마지막으로, 제 FTP 블로그에서 FTP가 아직 열려 있는 파일을 읽을 수 있어 때때로 불완전한 파일이 전송되는 경우가 있다고 언급한 바 있습니다. FTP 매크로가 특정 위치에 파일이 나타날 때까지 기다린 후 전송하는 경우, 해당 파일이 더 이상 잠겨 있지 않은지 반드시 확인해야 한다고 제안했습니다. 동일한 문제가 SFTP에서도 발생할 수 있으며 해결 방법도 동일합니다. 파일 잠금 확인을 명령 매크로(그림 9)에 배치한 후, 파일이 더 이상 잠겨 있지 않을 때 적절한 스크립트와 함께 expect를 호출할 수 있습니다.

&label AGAIN
&if (exists new_file) = 1 & (locked new_file) = 0 &then &goto EXPECT
display_line new_file not ready for transfer as of (time)
sleep -seconds 15
&goto AGAIN
&
&
&label EXPECT
expect sftp3.exp

 

그림 9 – expect 호출 전 파일 잠금에 대한 명령 매크로 테스트

© 2024 Stratus Technologies.