JSch 정리

Ada·2025년 10월 20일

자유 공부

목록 보기
20/21

1. JSch란?

JSch jsch = new JSch();

JSch (Java Secure Channel)는 SSH2 프로토콜을 Java로 구현한 라이브러리.

SSH란?

  • Secure Shell: 원격 서버에 안전하게 접속하는 프로토콜
  • 암호화된 네트워크 통신
  • 비밀번호 또는 SSH Key로 인증

JSch가 제공하는 기능:

  • SSH 원격 접속
  • SFTP (SSH File Transfer Protocol) - 파일 전송
  • SCP (Secure Copy) - 파일 복사
  • 포트 포워딩

예시:

// JSch = SSH 연결을 위한 도구 상자
JSch jsch = new JSch();

// SSH Key 등록 (비밀번호 대신 사용)
jsch.addIdentity("/path/to/private_key");

2. Session이란?

Session session = jsch.getSession("username", "host", port);
session.connect();

Session은 원격 서버와의 SSH 연결을 나타냄.

비유:

  • Session = 전화 통화
  • 전화를 걸고(connect) → 통화하고 → 끊는(disconnect) 과정
// 1. 세션 생성 (전화번호 누르기)
Session session = jsch.getSession("weblogic", "10.188.10.61", 22);

// 2. 설정
session.setConfig("StrictHostKeyChecking", "no");  // 호스트 검증 안 함 (개발용)

// 3. 연결 (전화 걸기)
session.connect();

// 4. 사용 후...

// 5. 연결 해제 (전화 끊기)
session.disconnect();

3. Channel과 ChannelSftp란?

Channel channel = session.openChannel("sftp");
ChannelSftp channelSftp = (ChannelSftp) channel;

Channel은 SSH 세션 위에서 동작하는 특정 서비스이다.

비유:

  • Session = 전화 연결
  • Channel = 전화로 할 수 있는 서비스 (음성 통화, 화상 통화, 파일 전송 등)

Channel의 종류:

// 1. SFTP 채널 - 파일 업로드/다운로드
session.openChannel("sftp")

// 2. Shell 채널 - 명령어 실행
session.openChannel("shell")

// 3. Exec 채널 - 특정 명령어 한 번 실행
session.openChannel("exec")

ChannelSftp의 주요 메서드:

ChannelSftp channelSftp = (ChannelSftp) channel;

// 파일 작업
channelSftp.cd("/path");           // 디렉토리 이동
channelSftp.pwd();                 // 현재 디렉토리 확인
channelSftp.ls("*");               // 파일 목록 조회
channelSftp.mkdir("dirname");      // 디렉토리 생성
channelSftp.get("remote", "local"); // 다운로드
channelSftp.put("local", "remote"); // 업로드
channelSftp.rm("file");            // 파일 삭제
channelSftp.rename("old", "new");  // 파일 이동/이름 변경

// 파일 정보 조회
channelSftp.stat("path");          // 파일/디렉토리 정보
channelSftp.lstat("path");         // 심볼릭 링크 정보 (링크 자체)

4. stat vs lstat

stat()

SftpATTRS attrs = channelSftp.stat("/home/weblogic/backup");

역할: 파일이나 디렉토리의 실제 정보를 가져옴.

특징:

  • 심볼릭 링크(바로가기)가 있으면 → 링크가 가리키는 실제 파일 정보를 반환
  • 파일이 없으면 → SftpException 발생

lstat()

SftpATTRS attrs = channelSftp.lstat("/home/weblogic/backup");

역할: 파일이나 디렉토리의 정보를 가져오는데, 심볼릭 링크는 링크 자체 정보를 반환함.

특징:

  • 심볼릭 링크가 있으면 → 링크 자체 정보를 반환 (실제 파일 X)
  • 파일이 없으면 → SftpException 발생

차이점 예시:

# 리눅스 서버에 이런 구조가 있다고 가정
/home/weblogic/data/file.txt        # 실제 파일
/home/weblogic/link -> data/file.txt  # 심볼릭 링크
// stat(): 링크가 가리키는 실제 파일 정보
SftpATTRS attrs1 = channelSftp.stat("/home/weblogic/link");
System.out.println(attrs1.isLink());  // false (실제 파일 정보이므로)

// lstat(): 링크 자체 정보
SftpATTRS attrs2 = channelSftp.lstat("/home/weblogic/link");
System.out.println(attrs2.isLink());  // true (링크 자체 정보)

일반적인 사용:

/**
 * 디렉토리 존재 여부 확인
 */
private boolean isDirectoryExists(ChannelSftp channelSftp, String path) {
    try {
        SftpATTRS attrs = channelSftp.lstat(path);  // 또는 stat()
        return attrs.isDir();  // 디렉토리인지 확인
    } catch (SftpException e) {
        return false;  // 파일/디렉토리가 없음
    }
}

5. SftpATTRS란?

SftpATTRS attrs = channelSftp.stat("/path");

SftpATTRS는 파일이나 디렉토리의 속성 정보를 담고 있는 객체이다.

제공하는 정보:

SftpATTRS attrs = channelSftp.stat("/home/weblogic/file.txt");

// 파일 타입 확인
attrs.isDir();      // 디렉토리인가?
attrs.isReg();      // 일반 파일인가?
attrs.isLink();     // 심볼릭 링크인가?

// 파일 정보
attrs.getSize();         // 파일 크기 (bytes)
attrs.getMTime();        // 수정 시간
attrs.getPermissions();  // 권한 (755, 644 등)
attrs.getUId();          // 소유자 ID
attrs.getGId();          // 그룹 ID

예시:

try {
    SftpATTRS attrs = channelSftp.stat("/home/weblogic/backup");
    
    if (attrs.isDir()) {
        System.out.println("디렉토리입니다");
        System.out.println("권한: " + attrs.getPermissionsString());
    } else {
        System.out.println("파일입니다");
        System.out.println("크기: " + attrs.getSize() + " bytes");
    }
    
} catch (SftpException e) {
    System.out.println("파일/디렉토리가 없습니다");
}

6. 전체 흐름 이해하기
시나리오: 원격 서버에 파일 업로드
java// 1. JSch 초기화 (도구 준비)
JSch jsch = new JSch();

// 2. SSH Key 등록 (신분증 등록)
jsch.addIdentity("/path/to/private_key");

// 3. Session 생성 (전화 걸기)
Session session = jsch.getSession("weblogic", "10.188.10.61", 22);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
System.out.println("서버 접속 완료!");

// 4. SFTP Channel 열기 (파일 전송 서비스 시작)
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftp = (ChannelSftp) channel;
System.out.println("SFTP 채널 오픈!");

// 5. 디렉토리 존재 확인
try {
    SftpATTRS attrs = sftp.stat("/home/weblogic/backup");
    if (attrs.isDir()) {
        System.out.println("백업 디렉토리 있음");
    }
} catch (SftpException e) {
    // 디렉토리가 없으면 생성
    sftp.mkdir("/home/weblogic/backup");
    System.out.println("백업 디렉토리 생성!");
}

// 6. 디렉토리 이동
sftp.cd("/home/weblogic/backup");
System.out.println("현재 위치: " + sftp.pwd());

// 7. 파일 업로드
sftp.put("/local/file.txt", "file.txt");
System.out.println("파일 업로드 완료!");

// 8. 파일 목록 확인
Vector<ChannelSftp.LsEntry> list = sftp.ls("*");
for (ChannelSftp.LsEntry entry : list) {
    System.out.println("파일: " + entry.getFilename());
}

// 9. 정리 (연결 해제)
sftp.disconnect();
session.disconnect();
System.out.println("연결 종료!");

7. 비유로 이해하기

전체 구조:

JSch          = 택배 회사
Session       = 배송 트럭 (출발지 → 목적지)
Channel       = 트럭 안의 서비스 (일반 배송, 냉장 배송, 특급 배송)
ChannelSftp   = 파일 전송 서비스
stat/lstat    = 목적지에 뭐가 있는지 확인
SftpATTRS     = 물건 정보 (크기, 종류, 상태)

과정:

1. JSch jsch = new JSch()
   → 택배 회사 선택

2. jsch.addIdentity(key)
   → 신분증 등록

3. Session session = jsch.getSession(...)
   → 트럭 준비 (출발지 → 목적지)

4. session.connect()
   → 트럭 출발

5. Channel channel = session.openChannel("sftp")
   → 트럭 안의 파일 전송 서비스 시작

6. ChannelSftp sftp = (ChannelSftp) channel
   → 파일 전송 도구 사용

7. sftp.stat("/path")
   → 목적지에 뭐가 있는지 확인

8. sftp.mkdir("/path")
   → 목적지에 폴더 만들기

9. sftp.put(local, remote)
   → 파일 보내기

10. sftp.disconnect() / session.disconnect()
    → 서비스 종료, 트럭 복귀

8. 예시 코드

private Map<String, File> downloadFromFep(String rcvYm, boolean moveToBackup) {
    
    // 1. 도구 준비
    JSch jsch = new JSch();
    Session session = null;
    ChannelSftp channelSftp = null;
    
    try {
        // 2. 신분증 등록 + 서버 접속
        jsch.addIdentity(rcvPrivateKey);
        session = jsch.getSession(rcvUserKey, rcvServerHost, devPort);
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();  // ← 이제 서버에 접속됨
        
        // 3. SFTP 서비스 시작
        Channel channel = session.openChannel("sftp");
        channel.connect();
        channelSftp = (ChannelSftp) channel;  // ← 이제 파일 전송 가능
        
        // 4. 원격 디렉토리 이동
        channelSftp.cd("/home/weblogic/files");
        
        // 5. 백업 디렉토리 존재 확인
        try {
            SftpATTRS attrs = channelSftp.stat("/home/weblogic/backup");
            // stat이 성공하면 디렉토리 있음
        } catch (SftpException e) {
            // stat이 실패하면 디렉토리 없음 → 생성
            channelSftp.mkdir("/home/weblogic/backup");
        }
        
        // 6. 파일 다운로드
        channelSftp.get("remote.txt", "/local/remote.txt");
        
        // 7. 파일 이동
        channelSftp.rename("/old/path/file.txt", "/new/path/file.txt");
        
    } finally {
        // 8. 정리
        if (channelSftp != null) channelSftp.disconnect();
        if (session != null) session.disconnect();
    }
}
profile
백엔드 프로그래머

0개의 댓글