SSD Nodes Learn
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-07-24

Restic 사용법: VPS 데이터를 외부로 안전하게 백업하기

Restic을 사용하여 VPS 데이터를 암호화 및 중복 제거된 상태로 외부 서버나 S3에 백업하는 방법을 설명합니다. Ubuntu 24.04 환경에서 SFTP 설정부터 systemd 타이머를 이용한 자동화, 복구 검증까지 단계별로 학습할 수 있습니다.

동일한 서버에 저장된 백업이 진정한 백업이 아닌 이유

Restic은 암호화 및 중복 제거가 적용된 파일 스냅샷을 다른 위치로 전송하는 무료 오픈 소스 백업 도구입니다. 저장소로는 두 번째 VPS, 홈 서버, 또는 S3 호환 오브젝트 스토리지를 사용할 수 있습니다. 이 가이드는 Ubuntu 24.04 환경에서 설치부터 SFTP를 통한 저장소 설정, 첫 백업 수행, 야간 systemd 타이머 설정, 보관 정책(retention policy), 그리고 전체 프로세스의 정상 작동을 검증하는 복구 실습까지 다룹니다. 백업 대상은 반드시 다른 기기여야 합니다. 동일한 서버에 저장된 복사본은 서버가 파괴되면 함께 사라지기 때문입니다.

백업 대상 기기 내의 backup/ 디렉토리는 실수로 파일을 삭제하는 상황만 방지할 수 있습니다. 디스크가 고장 나면 해당 디렉토리도 함께 손실됩니다. 루트 권한을 가진 공격자가 침입하면 공격자는 복사본을 가장 먼저 삭제합니다. VPS 자체를 삭제하는 계정 관리 실수 상황에서도 복사본은 보호받지 못합니다. The world's least efficient datacenter는 데이터와 동일한 어레이에 저장된 backup_final_v2_REAL라는 이름의 tarball을 농담 소재로 다루는데, 이는 많은 사용자가 실제로 겪는 문제이기 때문입니다. 백업은 반드시 외부 기기에 저장해야 하며, restic은 이를 수행하는 가장 효율적인 방법입니다.

Restic의 네 가지 핵심 개념

Repository. restic이 데이터를 기록하는 장소입니다. restic 전용 형식의 디렉토리이며, 암호화된 blob들로 구성됩니다. 오직 restic만 이 데이터를 읽을 수 있습니다. 사용자가 직접 파일을 수정해서는 안 됩니다. 반드시 restic 명령어나 -r 주소를 통해 접근해야 합니다.

Snapshot. 백업된 파일들의 특정 시점 상태를 나타냅니다. 백업을 실행할 때마다 snapshot이 생성됩니다. 각 snapshot은 개별적으로 복구할 수 있으며, 해당 시점의 전체 데이터 복사본처럼 동작합니다.

Deduplication. restic은 파일을 내용 기반의 chunk 단위로 분할합니다. 그 후 repository에 없는 chunk만 업로드합니다. 첫 번째 백업은 모든 데이터를 업로드하지만, 이후의 백업은 변경된 부분만 업로드합니다. 예를 들어 20 GB 크기의 snapshot에서 50 MB가 변경되었다면, 추가 비용은 약 50 MB입니다. 따라서 수십 개의 snapshot을 보관해도 비용 부담이 적습니다.

Encryption by default. restic repository는 항상 암호화(AES-256)되어 있으며, 모든 명령 실행 시 repository password가 필요합니다. 백업 호스트나 스토리지 제공업체는 암호화된 blob만 볼 수 있습니다. 이로 인해 발생하는 중요한 결과는 다음과 같습니다. password를 분실하면 데이터는 영구적으로 복구할 수 없습니다. 이는 설계 의도입니다. password 복사본을 해당 서버가 아닌 다른 안전한 곳에 보관하십시오. 이 사항은 매우 중요하므로 아래에서 두 번 더 언급됩니다.

Ubuntu 24.04에 restic 설치하기

sudo apt update && sudo apt install -y restic
restic version

Ubuntu 24.04에서는 restic 0.16.4 버전이 설치됩니다. 현재 최신 릴리스 버전은 0.19.1입니다. LTS(Long Term Support) 릴리스는 패키지 버전을 고정하기 때문에 이러한 차이가 발생합니다. 하지만 본 가이드의 내용을 수행하는 데는 0.16.4 버전으로도 충분합니다. 성능 향상이 포함된 최신 릴리스를 사용하려면 restic 프로젝트의 GitHub releases 페이지에서 공식 단일 바이너리 빌드를 다운로드하십시오. 다운로드한 파일은 bunzip2로 압축을 해제한 후 /usr/local/bin/restic 경로에 설치하십시오. restic 설치 과정은 이 작업이 전부입니다.

SFTP를 사용하여 다른 서버에 repository 생성하기

대상 머신이 필요합니다. 일반적으로 두 번째 소형 VPS를 사용하며, SSH server와 여유 디스크 공간이 있는 장비라면 무엇이든 가능합니다. Restic은 SFTP(SSH를 통한 파일 전송)를 지원하므로, backup host에 별도의 프로그램을 설치할 필요가 없습니다. 이 가이드에서 backup host는 10.0.0.12이며, 사용자 이름은 restic입니다. 사용자 이름을 backup으로 설정하지 마십시오. Ubuntu와 Debian은 모든 설치 시 backup(uid 34, 로그인 셸 없음)라는 예약된 시스템 계정을 포함하므로, adduser backup이 실패하고 ssh backup@...nologin에 저장됩니다.

야간 작업(nightly job)은 백업 대상 서버에서 root 권한으로 실행됩니다. 따라서 root 계정이 backup host에 키로 로그인할 수 있어야 합니다. 새벽 3시에 비밀번호를 입력할 사람이 없으므로, passphrase가 없는 전용 키를 생성하여 복사하십시오.

sudo ssh-keygen -t ed25519 -f /root/.ssh/id_ed25519 -N "" -C "web1-restic"
sudo ssh-copy-id -i /root/.ssh/id_ed25519.pub restic@10.0.0.12
sudo ssh restic@10.0.0.12 true && echo key login works

SSH 키가 처음이라면, SSH key management basics에서 모델, 권한 및 키 취소 방법을 확인할 수 있습니다.

다음은 repository password입니다. root만 읽을 수 있는 파일에 강력한 비밀번호를 생성하십시오.

openssl rand -base64 32 | sudo tee /root/.restic-password
sudo chmod 600 /root/.restic-password

더 진행하기 전에 해당 비밀번호를 password manager에 복사하십시오. VPS가 손실되어도 repository와 이 비밀번호가 있으면 모든 데이터를 복구할 수 있습니다. 비밀번호가 없는 repository로는 아무것도 복구할 수 없습니다.

repository를 초기화하십시오.

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password init
created restic repository 9f3c2a1b0d at sftp:restic@10.0.0.12:/srv/restic/web1

대안적인 대상은 S3-compatible object storage입니다. 두 번째 머신을 운영하고 싶지 않은 경우 적합한 선택입니다. 모든 S3-compatible bucket은 동일하게 작동하며, 주소와 두 개의 credential 변수만 변경됩니다.

export AWS_ACCESS_KEY_ID=your-key-id
export AWS_SECRET_ACCESS_KEY=your-secret-key
sudo -E restic -r s3:https://s3.example.com/web1-backups --password-file /root/.restic-password init

init 이후의 모든 과정은 두 대상에 대해 동일합니다. 이 가이드의 나머지 부분은 SFTP 주소를 기준으로 설명하므로, 사용자의 주소로 대체하여 적용하십시오.

제외 항목을 포함한 첫 번째 백업

전체 filesystem이 아닌 재설치가 불가능한 데이터만 백업하십시오. operating system은 재설치를 통해 복구할 수 있지만, configuration과 data는 그렇지 않습니다. 일반적인 VPS의 경우 /etc, /home, 그리고 /srv 또는 /var/www와 같이 application이 state를 저장하는 모든 경로를 의미합니다. cache는 용량이 크고 매일 변경되며 자동으로 재생성되므로 백업에서 제외하십시오:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password backup /etc /home /srv --exclude '/home/*/.cache'
Files:        4181 new,     0 changed,     0 unmodified
Added to the repository: 731.204 MiB (312.418 MiB stored)
snapshot 5b8a3f2c saved

첫 실행 시에는 모든 데이터를 업로드하므로 시간이 오래 걸립니다. 동일한 command를 다시 실행하면 몇 개의 파일 변경과 몇 MiB의 추가 데이터만 보고하며 몇 초 내에 완료됩니다. 이는 deduplication 기능이 새로운 chunk만 업로드하기 때문입니다. 백업 목록을 확인하십시오:

sudo restic -r sftp:restic@10.0.0.12:/srv/restic/web1 --password-file /root/.restic-password snapshots

각 snapshot에는 ID, 시간, 그리고 포함된 경로가 표시됩니다. 이 ID를 사용하여 데이터를 복구합니다.

systemd timer을 이용한 야간 실행

명령어를 입력할 때마다 repository 주소를 입력하는 것은 번거로운 작업이며, 수동으로 실행하는 백업은 한 달 이내에 중단될 가능성이 높습니다. 이 두 가지 문제는 하나의 script와 하나의 timer로 해결할 수 있습니다. script는 restic이 읽는 두 개의 environment variables인 RESTIC_REPOSITORYRESTIC_PASSWORD_FILE를 설정하므로, script 내부의 모든 명령어를 간결하게 유지할 수 있습니다.

sudo nano /usr/local/bin/restic-backup.sh
#!/usr/bin/env bash
set -euo pipefail
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password

restic backup /etc /home /srv --exclude '/home/*/.cache'
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
restic check
sudo chmod 700 /usr/local/bin/restic-backup.sh

forgetcheck 라인에 대한 설명은 다음 두 섹션에 있습니다. 이제 스케줄을 설정합니다. script를 실행하는 oneshot service와 매일 03:00에 실행되는 timer를 구성합니다. timer는 실행 로그가 journal에 기록되며, Persistent=true 기능 덕분에 서버가 다운타임 이후 다시 가동될 때 누락된 백업을 즉시 실행하므로 cron보다 유리합니다.

# /etc/systemd/system/restic-backup.service
[Unit]
Description=Nightly restic backup
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/restic-backup.sh
# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Run the nightly restic backup

[Timer]
OnCalendar=*-*-* 03:00:00
RandomizedDelaySec=15m
Persistent=true

[Install]
WantedBy=timers.target

timer를 활성화한 후, service를 수동으로 한 번 실행하여 정상 작동 여부를 확인하십시오.

sudo systemctl daemon-reload
sudo systemctl enable --now restic-backup.timer
sudo systemctl start restic-backup.service
sudo journalctl -u restic-backup.service -f

systemctl list-timers를 통해 다음 실행 시간을 확인할 수 있습니다. unit file를 직접 작성하는 대신 다음 명령어로 생성할 수도 있습니다.

ToolGenerate the backup service and timer

calendar syntax 및 service에 적용 가능한 hardening directives를 포함하여, 이 두 파일의 전체 패턴은 VPS에서 systemd service로 프로그램 실행하기에서 확인할 수 있습니다.

백업은 복구할 수 있을 때까지는 소문에 불과합니다

이 문장을 원칙으로 삼으십시오. 매일 밤 성공적으로 완료되는 백업 작업은 작업이 실행되었음을 증명할 뿐, 데이터가 복구됨을 증명하지는 않습니다. 다음 두 가지 검증을 통해 이 격차를 해소하십시오.

첫째, 스크립트가 이미 매일 밤 실행 중인 restic check입니다. 이 작업은 repository 구조와 index를 검증합니다. 따라서 backup host의 데이터 손상이 발생하더라도 복구 시점이 아닌 다음 날 밤에 즉시 발견할 수 있습니다. 한 달에 한 번은 더 심층적인 버전을 실행하십시오. 이 버전은 실제 데이터의 10%를 무작위로 다운로드하여 암호학적으로 검증합니다:

sudo -i
export RESTIC_REPOSITORY='sftp:restic@10.0.0.12:/srv/restic/web1'
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic check --read-data-subset=10%

매번 무작위 부분 집합을 선택하므로, 전체 데이터를 다운로드하지 않고도 매달 실행을 통해 repository 전체를 검증할 수 있습니다.

둘째, 복구 훈련입니다. 위에서 사용한 root shell 상태에서, 최신 snapshot의 실제 디렉토리 하나를 임시 위치로 복구한 뒤 실제 파일과 비교하십시오:

restic restore latest --target /srv/restore-drill --include /etc/ssh
diff -r /etc/ssh /srv/restore-drill/etc/ssh

diff 결과에 아무것도 출력되지 않으면 모든 byte가 동일하게 복구되었음을 의미하며, 이것만이 유효한 증거입니다. 작업 완료 후 /srv/restore-drill를 삭제하십시오. 이 훈련을 매달 수행하고, 1년에 한두 번은 전체 버전을 수행하십시오. 전체 최신 snapshot을 임시 VPS에 복구한 뒤 애플리케이션이 정상적으로 시작되는지 확인하십시오. 압박이 심한 상황에서 복구가 필요할 때, 이 과정이 이미 익숙한 루틴이어야 합니다.

Retention: forget plus prune

정책이 없으면 snapshot이 계속 쌓여서 repository 크기가 계속 커집니다. script의 forget 라인은 매일 밤 정책을 적용합니다. --keep-daily 7은 지난 7일 동안 매일 하나씩의 snapshot을 유지합니다. --keep-weekly 4은 4주 동안 매주 하나씩 유지합니다. --keep-monthly 6은 6개월 동안 매달 하나씩 유지합니다. 규칙으로 보호되지 않는 모든 데이터는 삭제됩니다.

forget만 사용하면 snapshot 레코드만 삭제됩니다. 데이터 chunk는 다른 요소가 삭제하기 전까지 repository에 남아 있습니다. --prune은 이 문제를 해결합니다. 더 이상 snapshot에서 참조되지 않는 chunk를 찾아 삭제하며, 이때 실제로 디스크 공간이 확보됩니다. Prune은 실제 repository 작업을 수행합니다. 따라서 규모가 큰 repository에서는 forget를 매일, --prune을 매주 실행하기도 합니다. 일반적인 VPS 크기에서는 매일 실행해도 무방합니다.

Databases: dump first, then back up the dump

Restic은 파일을 읽는 동시에 복사하며, 데이터베이스는 파일에 지속적으로 데이터를 기록합니다. 쓰기 작업 중에 캡처된 라이브 데이터베이스 파일은 손상된 상태로 복구됩니다. 이는 복사 과정에서 쓰기 전후의 페이지가 혼합되기 때문입니다. 해결 방법은 표준적입니다. 데이터베이스 엔진이 일관된 상태의 파일을 생성하도록 하고, restic이 해당 파일을 백업하도록 합니다.

PostgreSQL의 경우, restic-backup.sh 상단에 restic backup 명령 이전에 dump 명령을 추가하십시오. 그리고 백업 경로에 dump 디렉토리를 포함하십시오.

mkdir -p /var/backups/db
sudo -u postgres pg_dump myapp | gzip > /var/backups/db/myapp.sql.gz

mysqldump은 MariaDB 및 MySQL에서도 동일한 역할을 수행합니다. 전체 패턴의 실행 예시는 Nextcloud 백업 섹션을 참조하십시오. 해당 섹션에서는 유지 관리 모드를 활성화하고, Postgres를 dump한 뒤, 파일을 일관된 세트로 복사합니다. 이것이 restic이 매일 밤 서버에서 가져가야 할 정확한 세트입니다. SQLite도 동일한 원리를 사용하지만 방식이 더 간단합니다. Vaultwarden 가이드db.sqlite3의 콜드 카피(cold copy)를 생성하기 위해 컨테이너를 몇 초간 중지하며, restic은 해당 아카이브를 서버에서 전송합니다.

FAQ

restic 백업은 암호화됩니까?

예, 항상 암호화됩니다. 모든 restic repository는 AES-256으로 암호화됩니다. 암호화되지 않은 모드는 존재하지 않으며, 모든 명령에는 repository password가 필요합니다. repository를 저장하는 머신이나 제공업체는 암호화된 blob만 보유하므로, 백업 호스트가 침해되어도 파일이 노출되지 않습니다. 보안과 편의성 사이의 규칙은 명확합니다. password 없이는 누구도 데이터를 복구할 수 없으므로, 서버와 분리된 곳에 password 복사본을 보관하십시오.

restic은 증분 백업을 수행합니까?

모든 restic snapshot은 전체 백업처럼 동작하며, 저장 공간은 증분 방식으로 사용합니다. restic은 파일을 chunk 단위로 분할하고 repository에 저장되지 않은 chunk만 업로드합니다. 따라서 야간 실행 시 해당 날짜에 변경된 데이터량만큼만 전송됩니다. 기존의 증분 방식과 달리 재현해야 할 체인(chain)이 없습니다. 모든 snapshot은 직접 복구가 가능하며, 오래된 snapshot을 삭제해도 최신 snapshot에 영향을 주지 않습니다.

restic 백업에서 파일을 어떻게 복구합니까?

restic snapshots를 실행하여 snapshot ID를 확인한 후, restic restore <id> --target /some/empty/dir를 사용하여 복구하십시오. 일부만 복구하려면 --include /path을 추가하십시오. ID 대신 latest을 사용할 수 있습니다. restic은 대상 디렉토리 아래에 원래의 디렉토리 구조를 재구성합니다. 예를 들어 /etc/ssh를 복구하면 /some/empty/dir/etc/ssh에 저장됩니다. 백업이 검증되지 않으면 신뢰할 수 없으므로, 실제 필요할 때를 대비하여 미리 연습하십시오.

restic backup을 얼마나 자주 실행해야 합니까?

서버의 경우 매일 밤 실행하는 것이 적절하며, deduplication 덕분에 비용이 저렴합니다. 각 실행 시 마지막 실행 이후 변경된 chunk만 업로드합니다. 변경이 빈번하거나 하루라도 데이터 손실이 치명적인 경우에는 동일한 타이머 패턴으로 몇 시간마다 실행할 수 있습니다. 실행 빈도보다 중요한 것은 검증입니다. restic check를 정기적으로 실행하고 매달 복구 연습을 수행하십시오. 검증 없는 일정은 잘못된 안도감을 줍니다.

restic repository password를 분실하면 어떻게 됩니까?

백업을 복구할 수 없습니다. restic의 암호화에는 백도어나 비밀번호 재설정 기능이 없으므로, password는 백업 데이터만큼 중요합니다. password 복사본을 password manager나 백업 대상 서버가 아닌 안전한 곳에 보관하십시오. 접근 권한이 있는 동안 restic key add를 사용하여 동일한 repository에 대한 두 번째 password를 등록하여 예비용으로 사용할 수 있습니다.