Openrsync: Rsync 프로토콜의 현대적인 그리고 BSD 라이선스를 따르는 구현체
수십 년 동안 rsync는 네트워크를 통한 효율적인 파일 동기화의 표준으로 자리 잡아 왔습니다. 하지만 기존 구현체는 수년간 쌓인 레거시 코드의 무게와 GPL 라이선스의 제약이라는 문제를 안고 있습니다. 이에 등장한 openrsync는 OpenBSD 팀이 개발한 rsync 프로토콜의 클린룸(clean-room) 구현체입니다.
원래 NetNod 및 SUNET과 같은 조직의 지원을 받는 OpenBSD용 RPKI 검증기인 rpki-client(1) 프로젝트의 일부로 만들어졌던 openrsync는 이후 OpenBSD 기본 시스템에 통합되었습니다. 이는 현대적인 rsync(프로토콜 버전 27)와 호환되는 BSD 라이선스(ISC) 대안을 제공하며, 보안과 미니멀리즘을 강조한 간결한 파일 동기화 방식을 제안합니다.
핵심 알고리즘: openrsync의 작동 방식
openrsync의 핵심은 소스 파일과 대상 파일 간의 차이점만 전송하여 데이터 전송을 최소화하는 클래식 rsync 알고리즘을 구현한다는 점입니다. 이 프로세스는 sender(소스 파일 관리)와 receiver(대상 관리)로 나뉩니다.
블록 교환 프로세스
openrsync의 효율성은 정교한 "블록 교환" 메커니즘에 달려 있습니다.
- 파일 목록 생성: sender가 파일 이름과 메타데이터 목록을 생성합니다. 양측 모두 이 목록을 사전식으로 정렬하여 디렉토리가 포함된 파일보다 먼저 처리되도록 합니다.
- 해싱을 통한 효율성 확보: 일반 파일의 경우, receiver가 파일을 블록으로 나눕니다. 각 블록은 두 번 해싱됩니다. 먼저 빠른 Adler-32(4바이트) 해시를 수행하고, 그다음 더 느린 MD4(16바이트) 해시를 수행합니다.
- 매칭: receiver가 이 해시들을 sender에게 보냅니다. sender는 자신의 파일 버전을 스캔하며 실시간으로 빠른 해시를 계산합니다. 빠른 해시가 일치하면, 느린 MD4 해시로 일치 여부를 다시 확인합니다.
- 재구성: 일치하는 항목이 발견되면, sender는 receiver에게 로컬 복사본에서 어떤 블록을 재사용할지 알려줍니다. 일치하는 항목이 없으면, sender는 원시 바이트를 전송합니다. 이 과정은 파일이 완전히 재구성될 때까지 계속됩니다.
블록 크기 최적화
오버헤드와 정밀도 사이의 균형을 맞추기 위해, openrsync는 전체 파일 크기의 제곱근을 기준으로 블록 크기를 계산하며, 최소 크기는 700바이트입니다. 이를 통해 작은 설정 파일부터 거대한 데이터베이스 덤프까지 어떤 파일이든 효율적으로 동기화할 수 있습니다.
아키텍처 개선 사항
openrsync와 기존 Samba rsync의 주요 차이점 중 하나는 내부 아키텍처입니다. 기존 rsync가 파일 스캔을 처리하기 위해 (receiver에서 포크된) 별도의 "generator" 프로세스를 사용하는 반면, openrsync는 generator와 receiver를 하나의 프로세스로 통합합니다.
event loop를 활용함으로써, openrsync는 프로세스 간 통신(IPC)의 오버헤드 없이 읽기 및 쓰기 요청에 더 빠르게 응답할 수 있습니다. receiver는 uploader(블록 메타데이터 전송)와 downloader(sender로부터 받은 데이터 쓰기)로서의 멀티태스킹을 효과적으로 수행합니다.
설계에 의한 보안
OpenBSD 팀이 개발했기에, 보안은 사후 고려 사항이 아니라 근본적인 요구 사항입니다. openrsync는 공격 표면을 제한하기 위해 네이티브 OpenBSD 보안 프리미티브를 활용합니다.
pledge(2): 프로세스가 수행할 수 있는 시스템 호출을 제한합니다. 예를 들어, receiver는 "dry-run" 모드가 아닐 때만 디스크에 대한 쓰기 권한을 부여받습니다.unveil(2): 프로세스의 파일시스템 접근 범위를 제한합니다. receiver는 대상 디렉토리와 그 하위 디렉토리에서만 "unveiled" 상태가 되며, 이를 통해 프로세스가 대상 경로 외부의 파일에 실수로 또는 악의적으로 접근하는 것을 방지합니다.- 무작위 시딩(Randomized Seeding):
time(3)을 사용하는 일부 구현체와 달리, openrsync는 서버 모드에서arc4random(3)을 사용하여 MD4 해시의 시딩을 수행함으로써 견고성을 높입니다.
이식성 및 생태계
공식적으로는 OpenBSD에서 지원되지만, openrsync는 이식 가능한 설계로 만들어졌습니다. 현재 Linux (glibc 및 musl), FreeBSD, NetBSD, macOS, 그리고 OmniOS에서 컴파일 및 실행이 가능합니다.
하지만 개발자들은 pledge와 unveil의 보안 보증이 매우 중요하다고 경고합니다. 동일한 보안 태세를 유지하기 위해서는 이를 다른 시스템으로 이식하는 것(예: FreeBSD의 Capsicum 사용)이 필수적입니다. 저자가 언급했듯이, 기존 rsync는 네트워크로부터 임의의 데이터를 파일시스템에 들이붓는 방식입니다. 이러한 보호 조치 없이서는 어떤 구현체라도 잠재적으로 위험할 수 있습니다.
커뮤니티 관점 및 현재 상태
초기 도입자들과 커뮤니티 구성원들은 도입과 관련하여 몇 가지 핵심 사항을을 언급했습니다.
- 통합: 흥미롭게도, 일부 보고에 따르면 openrsync가 이미 macOS 15.0에서 활용되고 있다는 소식이 있습니다.
- 기능적 동등성: rsync의 명령줄 인자 중 일부를 지원하지만, 현재 격차를 줄여가는 중입니다. 예를 들어,
--exclude지원은 최근 OpenBSD 7.9에서 추가되었습니다. - 라이선스 매력도: BSD 라이선스로의 전환은 GPL을 제한적이라고 느끼는 사용자들에게 큰 이점이며, 이는 다른 독점적 또는 허용적인 OS 배포판으로의 통합을 용이하게 할 만큼의 잠재력이 있습니다.
"rsync의 이러한 파편화 문제는 Apple과 Android가 이를 선호하게 만들겠지만, Linux와 더 넓은 GPL 세계는 관성성 때문에 기존 구현체를 고수할 것입니다." — HN User @chasil
깨끗하고 안전하며 허용적인 라이선스를 가진 구현체를 제공함으로써, openrsync는 단순히 파일을 동기화하는 도구만을 제공하는 것이 아닙니다. 이는 현재의 보안 환경에서 필수적인 시스템 유틸리티가 어떻게 구축되어야 하는지에 대한 현대적인 청사진을을 제공합니다.