Java, SFTP, JSCh
Java에서 SFTP기능을 구현하기 위해 SFTP라이브러리를 찾아보면 JSCh 외에는 선택의 여지가 없습니다. 예제가 잘 돌아가서 실제 개발소스에서도 문제가 없다면 상관없지만 저는 아래와 같은 문제가 있었습니다.
구형 Sun장비의 경우 OpenSSH로 업데이트하지 않았다면 Sun에서 컴파일한 Sun_SSH가 설치되어 있으며 이것은 Jeus와 이해하기 힘든 오류를 발생합니다. 단순히 JSCh로 구현하면 잘되는데, Jeus에 올려진 웹애플리케이션에서는 sun.security.jgss.krb5.initiate라는 오류가 발생할 수 있습니다.
이 문제는 소스에서 gssapi-with-mic 인증을 빼거나 sshd설정에서 GSSAPIAuthentication no로 설정하면 Kerberos인증이 스킵되면서 해결됩니다.
Keyboard-interactive(PAM)은 사용자 암호를 저장하여 sftp를 불법으로 이용하는 것을 막는 기능이지만 여러 가지 방법으로 Keyboard입력을 에뮬레이션 할 수 있어 조금은 쓸모가 없는 기능입니다. 하지만 많은 서버 보안 가이드에서는 PAMAuthenticationViaKdbInt Yes를 권고하고 있습니다.
JSCh에서도 인증 시 Keyboard입력을 에뮬레이션 하고 있어 보통은 이 인증을 통과하지만 그렇치 않는 서버도 있습니다. 이것 역시 sshd설정에서 PAMAuthenticationViaKdbInt No로 하면 해결 가능하지만 보안팀이 별도로 있어 점검을 해주는 곳이라면 No로 설정하는 것에 반대를 할 수 있습니다.
인터넷에 널리 퍼져있는 JSch 예제는 id/pw인증 방식입니다. 이 예제만 너무 많이 있어 마치 이 방법이 가장 좋으며, 이 방법뿐인 것으로 착각이 될 정도입니다. (제가 그랬습니다. ) 그런데 한발짝 물러서 소스를 바라보면 보안을 위해 sftp를 사용했는데 평문으로 id/pw를 바로 쓴다는 것은 마치 철로 된 벽에 문은 부서지기 쉬운 나무로 만든 것 같지 않나요?
JSch jsch = new JSch();
session = jsch.getSession(username, host, port);
session.setPassword(password);
session.connect();
위 첫 번째, 두 번째 문제를 해결하며, 보안까지 강화한 소스는 아래와 같습니다.
JSch jsch = new JSch();
String secret-key = “.ssh/id_dsa”;
jsch.addIentity(secret-key);
Session session = jsch.getSession(id, ip, port);
session.connect();
바로 비밀키/공개키 방식을 사용하는 것입니다. 비록 ssh keygen으로 비밀키/공개키를 생성하고 sftp서버에 공개키를 등록해야하는 작업이 있지만 그정도 가치는 충분하다고 생각합니다.
버전에 따라 G-PIN과 같은 모듈과 충돌이 발생할 수 있습니다.
자바 1.4에서도 잘 돌아갑니다.
로그 클래스를 만들어 등록하면 JSCh가 동작하는 상세로그를 확인할 수 있어 문제 발생 시 해결의 실마리를 제공합니다.
모두 모두 덜 고생하세요!