Vaultwarden VPS 설치 및 Docker 구축 가이드
Docker를 사용하여 VPS에 Vaultwarden을 구축하는 방법을 설명합니다. Bitwarden 클라이언트의 HTTPS 필수 요구사항과 Admin Token 설정, 데이터 백업 및 Fail2ban 적용법을 상세히 다룹니다.
구축 목표
사용자가 완전히 제어할 수 있는 비밀번호 관리자를 구축합니다. HTTPS를 종료하는 reverse proxy 뒤에서 Vaultwarden을 단일 컨테이너로 실행합니다. 스마트폰, 노트북, 브라우저의 공식 Bitwarden 앱을 이 서버로 연결합니다. Vaultwarden은 Bitwarden 서버 API를 Rust로 재구현했습니다. bitwarden.com과 동일한 프로토콜을 사용하므로 모든 공식 클라이언트가 수정 없이 작동합니다. 또한 여러 컨테이너로 구성된 공식 스택과 달리 RAM 사용량이 약 100 MB에 불과합니다.
설치 과정은 Compose 파일 몇 줄이면 충분합니다. 실제 중요하며 오류가 발생하기 쉬운 요소는 다음 세 가지입니다. 첫째, web vault를 로드하기 전에 반드시 TLS가 설정되어 있어야 합니다. 둘째, 본인의 계정이 생성된 즉시 public signups를 차단해야 합니다. 셋째, 데이터 volume을 백업하고 복구 테스트를 수행해야 합니다. 해당 디렉토리에 모든 비밀번호가 저장되기 때문입니다.
Prerequisites and the honest gotchas
- Docker Engine 및 Compose plugin이 설치된 VPS가 필요합니다. root 또는 sudo 권한이 있는 신규 Ubuntu 24.04 KVM 환경을 권장합니다. 512 MB RAM으로도 충분하며, 1 GB면 여유롭습니다. 이 서비스는 매우 가볍습니다. 자체 호스팅할 가치가 있는 서비스 목록 상단에 위치합니다.
- VPS의
vault.example.com를 가리키는 A 레코드(IPv6 사용 시 AAAA 레코드 포함)를 가진 도메인이 필요합니다. TLS 인증서는 이 도메인 이름으로 발급됩니다. 따라서 시작 전 DNS 설정이 완료되어야 합니다. - 80 및 443 포트가 인터넷에 개방되어 있어야 하며, reverse proxy가 이를 처리해야 합니다. 절대로 Vaultwarden이 직접 처리하게 하지 마십시오. 80 포트는 ACME 인증서 챌린지 및 HTTP-to-HTTPS 리다이렉트 용도로만 사용됩니다.
- 주의사항: Bitwarden 클라이언트는 HTTPS가 아닌 서버와의 통신을 거부합니다. "먼저 http로 테스트하기"는 불가능합니다. 다음 섹션에서 설명할 구체적인 이유로 인해 해당 방식은 작동하지 않습니다.
왜 Bitwarden 공식 스택 대신 Vaultwarden인가
동일한 클라이언트를 사용하면서 리소스 사용량은 훨씬 적습니다. 공식 self-hosted Bitwarden은 여러 컨테이너(MSSQL, Nginx, Identity, Api, Admin 등)의 번들 형태로 제공되며 약 2 GB의 RAM을 요구합니다. Vaultwarden은 단일 binary 파일이며 기본적으로 SQLite 데이터베이스에 모든 데이터를 저장하므로 유휴 상태에서 수십 MB의 메모리만 사용합니다. 개인, 가족 또는 소규모 팀에게는 Vaultwarden이 최적의 선택입니다. 또한 Bitwarden API를 충실히 구현하므로 데이터는 Vaultwarden과 bitwarden.com 사이에서 호환됩니다.
대신 엔터프라이즈 기능의 대부분을 사용할 수 없습니다. SCIM provisioning을 지원하지 않습니다(단, 1.35.0 버전에서 실험적인 OpenID Connect SSO가 추가되었습니다). 또한 사용자가 직접 운영자이므로 패치, HTTPS 설정, 백업을 직접 수행해야 합니다. 이 가이드는 이 세 가지 작업에 대해 다룹니다.
HTTPS가 필수인 이유
Bitwarden web vault와 browser extensions는 Web Crypto API (window.crypto.subtle)를 사용하여 browser에서 encryption keys를 생성합니다. Browser는 secure context인 HTTPS 또는 http://localhost의 경우에만 crypto.subtle를 허용합니다. 일반 http://vault.example.com 환경에서는 undefined이므로, app이 key를 생성하는 즉시 오류가 발생하며 console에 다음 내용이 표시됩니다:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'importKey')페이지가 멈추거나 일반적인 crypto error가 발생하며 로그인이 되지 않습니다. desktop, mobile, browser client는 self-hosted URL에 대해 자체 검증을 수행합니다. http(또는 접속 불가능한) endpoint를 사용하면 다음과 같은 오류와 함께 접속을 거부합니다:
This is not a recognized Bitwarden server. You may need to check with your provider or update your server.두 경우 모두 원인은 동일합니다. 유효한 HTTPS가 없기 때문입니다. 따라서 반드시 TLS를 먼저 구축해야 하며, 단순 확인을 위해서라도 http를 통해 vault를 여는 일은 절대 없어야 합니다.
Step 1 — DNS and the reverse proxy (TLS first)
레코드를 VPS로 지정하고 올바른 주소로 해석되는지 확인하십시오:
dig +short vault.example.com출력된 라인은 반드시 VPS IP여야 합니다. 값이 비어 있거나 잘못되었다면 DNS를 수정하고 TTL이 만료될 때까지 기다리십시오. 이름이 올바르게 해석되지 않으면 인증서 발급이 실패합니다.
이 가이드의 HTTPS 프런트 엔드에는 Traefik을 사용합니다. Traefik은 Let's Encrypt 인증서를 자동으로 발급 및 갱신하며 Compose와 직접 연동됩니다. 아직 Traefik을 사용 중이 아니라면 Traefik reverse proxy and automatic TLS setup를 먼저 수행하십시오. 이 과정은 외부 Docker network (아래의 proxy)와 Vaultwarden 서비스가 연결될 ACME resolver (letsencrypt)를 생성합니다. 수동으로 발급한 인증서를 사용하는 일반 nginx도 Vaultwarden 측면에서는 동일하게 작동합니다.
Traefik 대신 nginx와 Certbot을 선호합니까? Vaultwarden을 127.0.0.1:8080에 배치하십시오 (서비스에 ports: ["127.0.0.1:8080:80"]를 추가하고 Traefik labels를 제거하십시오). 그 다음 인증서를 발급하고 해당 서비스로 프록시를 설정하십시오. 인증서 관련 내용은 issuing Let's Encrypt certificates with Certbot and nginx에서 다룹니다. 중요한 추가 사항은 notifications 경로에 대한 WebSocket upgrade 설정입니다:
server {
listen 443 ssl;
server_name vault.example.com;
client_max_body_size 525M;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}X-Real-IP 라인에 주의하십시오. 이 설정이 있어야 나중에 Fail2ban이 127.0.0.1 대신 실제 공격자를 식별할 수 있습니다. Traefik 또는 nginx 중 무엇을 프런트 엔드로 사용하든 이 가이드의 나머지 내용은 동일합니다.
Step 2 — the Compose file
먼저 프로젝트 디렉토리를 생성하십시오. 이 가이드는 /opt/vaultwarden를 사용합니다. 이를 통해 Compose 프로젝트 이름과 데이터 볼륨인 vaultwarden_vw-data을 예측 가능한 상태로 유지합니다. 아래의 Fail2ban 및 백업 단계는 이 정확한 이름을 기준으로 작동합니다.
sudo mkdir -p /opt/vaultwarden
cd /opt/vaultwardenadmin secret을 위한 .env을 생성하고 해당 디렉토리에 Compose 파일을 만드십시오.
# .env
ADMIN_TOKEN=paste-a-strong-token-hereopenssl rand -base64 48를 사용하여 토큰을 생성한 뒤 붙여넣으십시오. (더 강력한 해시 형태는 다음 단계에서 다룹니다. 처음에는 긴 무작위 문자열을 사용해도 무방합니다.)
# docker-compose.yml
services:
vaultwarden:
image: vaultwarden/server:latest
container_name: vaultwarden
restart: unless-stopped
environment:
DOMAIN: "https://vault.example.com"
SIGNUPS_ALLOWED: "true" # closed in Step 4, keep true just to register
ADMIN_TOKEN: "${ADMIN_TOKEN}"
IP_HEADER: "X-Forwarded-For" # X-Real-IP if your proxy sends that instead
LOG_FILE: "/data/vaultwarden.log"
LOG_LEVEL: "warn"
volumes:
- vw-data:/data
networks:
- proxy
labels:
- "traefik.enable=true"
- "traefik.http.routers.vw.rule=Host(`vault.example.com`)"
- "traefik.http.routers.vw.entrypoints=websecure"
- "traefik.http.routers.vw.tls.certresolver=letsencrypt"
- "traefik.http.services.vw.loadbalancer.server.port=80"
volumes:
vw-data:
networks:
proxy:
external: true이 파일에는 전체 설계의 핵심인 두 가지 사항이 있습니다. 첫째, ports: 매핑이 없습니다. 따라서 Vaultwarden은 Traefik과 TLS를 통해서만 접속할 수 있습니다. 호스트에 포트를 공개하면 사용자가 실수로 http를 통해 볼트를 서비스하게 됩니다. 둘째, DOMAIN는 반드시 전체 공개 HTTPS URL이어야 합니다. 이 값은 첨부 파일 링크, WebAuthn 2FA, 알림 엔드포인트에 포함됩니다. 값이 틀리거나 http로 설정되면 사이트가 로드되더라도 해당 기능들이 작동하지 않습니다. latest 태그는 일반적인 never-latest 규칙에 대한 의도적인 예외입니다. Vaultwarden은 안정적인 릴리스를 단일 롤링 이미지로 제공하며, :testing을 별도의 프리릴리스 채널로 제공합니다. 따라서 의도적으로 업데이트를 진행하되, 이미지를 pull 하기 전에 릴리스 노트를 확인하십시오.
서비스를 실행하고 로그를 확인하십시오:
docker compose up -d
docker compose logs -f vaultwarden정상적으로 시작되면 Rocket has launched from http://0.0.0.0:80과 같은 라인이 출력됩니다. Traefik이 인증서를 가져올 때까지 몇 초간 대기한 후 https://vault.example.com을 로드하십시오. 유효한 자물쇠 아이콘이 표시되고 인증서 경고가 없는 Bitwarden 웹 볼트가 나타나야 합니다.
Step 3 — 강력한 ADMIN_TOKEN 및 $$ 트랩
ADMIN_TOKEN은 인스턴스의 모든 사용자 및 설정을 읽을 수 있는 패널인 /admin을 보호합니다. 따라서 root 비밀번호와 동일하게 취급해야 합니다. 두 가지 방식이 있습니다.
단순한 방식은 이미 openssl rand -base64 48를 통해 생성한 무작위 문자열을 사용하는 것입니다. base64에는 $이 포함되지 않으므로, 별도의 escaping 없이 .env에 바로 입력할 수 있습니다.
강력한 방식은 Argon2 PHC 해시를 사용하는 것입니다. 이 방식을 사용하면 평문 토큰이 디스크에 저장되지 않습니다. 동일한 이미지를 사용하여 다음을 생성하십시오:
docker run --rm -it vaultwarden/server /vaultwarden hash --preset owasp두 번의 프롬프트가 나타나며 $argon2id$v=19$...으로 시작하는 문자열이 출력됩니다. 사용자들이 흔히 겪는 1시간짜리 트랩이 있습니다. Docker Compose는 $을 변수 보간(variable interpolation)으로 처리합니다. 따라서 해시를 Compose 파일에 붙여넣을 때 모든 $을 $$으로 변경해야 합니다. 해시는 .env을 통하지 않고 environment: 바로 아래에 입력하며, 따옴표로 감싸지 마십시오:
environment:
ADMIN_TOKEN: $$argon2id$$v=19$$m=19456,t=2,p=1$$c29tZXNhbHQ$$RdescudvJCsgt3ub+b+dWRWJTmaaJObG단일 $ 기호를 그대로 두면 Compose가 The "argon2id" variable is not set 경고를 발생시키고 토큰을 빈 값으로 만듭니다. 이 경우 /admin에서 올바른 비밀번호를 거부합니다. docker compose up -d를 실행한 후, 프롬프트에 입력한 평문 토큰을 별도의 비밀번호 관리자에 저장하십시오.
Step 4 — 계정을 등록한 후 보안 설정을 완료하십시오
SIGNUPS_ALLOWED: "true"를 사용하여 https://vault.example.com을(를) 엽니다. Create account를 클릭하고 이메일과 강력한 master password를 입력하여 등록을 진행하십시오. 이 master password는 분실 시 복구할 수 없으며 재설정 기능도 제공되지 않습니다. 따라서 반드시 안전한 곳에 따로 저장해 두어야 합니다.
이제 보안 설정을 적용하십시오. Compose file을 수정하여 회원가입 기능을 비활성화합니다.
SIGNUPS_ALLOWED: "false"docker compose up -d를 사용하여 설정을 다시 적용하십시오. 이 작업은 필수적인 보안 강화 단계이므로 미룰 수 없습니다. 회원가입을 열어두면 URL을 발견한 누구나(크롤러 포함) 서버에 계정을 생성할 수 있습니다. 이들이 사용자의 vault를 읽을 수는 없지만, 시스템 자원을 소모하며 개인용 인스턴스를 공개 서비스로 만듭니다. 설정이 활성화되어 있는지 확인하려면 /admin에서 직접 생성하지 않은 계정 목록을 확인하십시오.
나중에 가족이나 팀원을 추가할 때는 공개 회원가입을 다시 열 필요 없이 /admin의 Invite User 버튼을 사용하십시오. 이 기능을 사용하려면 초대받은 사용자가 링크를 받을 수 있도록 SMTP 설정이 완료되어 있어야 합니다.
Step 5 — /admin 접속
https://vault.example.com/admin로 이동하여 plaintext admin token을 입력하십시오. (해시값이 아닌, 무작위 문자열 또는 해싱하기 전의 비밀번호를 입력해야 합니다.) 해당 페이지에서 사용자 목록 확인, 설정 조정, 테스트 이메일 발송, 데이터베이스 스냅샷 생성이 가능합니다.
페이지에서 404 Not Found 오류가 발생하면 ADMIN_TOKEN가 비어 있거나 설정되지 않은 상태입니다. 이 경우 패널 기능이 완전히 비활성화됩니다. 패널이 필요 없다면 이 상태를 유지해도 무방합니다. 페이지는 로드되지만 토큰이 거부된다면, 아래 실패 목록에 있는 $$ escaping trap 항목을 확인하십시오. 토큰을 분실했습니까? 별도의 복구 프롬프트는 제공되지 않습니다. .env 또는 Compose 파일을 수정하여 새로운 토큰을 설정한 후 docker compose up -d를 수행하십시오.
Step 6 — Bitwarden 클라이언트 연결
모든 공식 클라이언트는 self-hosted 서버를 가리키도록 설정할 수 있습니다. 일반 스토어에서 Bitwarden desktop, mobile 또는 browser 클라이언트를 설치하십시오. 별도의 Vaultwarden 빌드가 필요하지 않습니다.
로그인하기 전에 로그인 화면에서 설정 아이콘(Self-hosted 또는 Region → Self-hosted로 표시됨)을 엽니다. Server URL을 https://vault.example.com으로 설정하고 저장하십시오. 그 다음 등록한 이메일과 master password로 로그인하십시오. 클라이언트가 즉시 연결되며 자격 증명을 채우고 저장할 것인지 묻는 메시지가 나타납니다.
클라이언트에 This is not a recognized Bitwarden server. You may need to check with your provider or update your server. 오류가 표시되면 URL이 잘못되었거나, http를 사용 중이거나, 인증서를 신뢰할 수 없는 상태입니다. 먼저 https://vault.example.com이 브라우저에서 정상적으로 로드되는지 다시 확인하십시오. 다른 기기에서의 느린 업데이트는 WebSocket push 문제이며, 아래에서 다룹니다.
Step 7 — 로그인 엔드포인트를 위한 Fail2ban jail 설정
Vaultwarden은 모든 로그인 실패 기록을 LOG_FILE에 설정된 파일에 기록합니다. 이는 brute-force 공격을 방어하는 데 필수적인 데이터입니다. Fail2ban을 아직 설치하지 않았다면 Fail2ban SSH hardening guide를 참조하십시오. 여기에서는 Vault를 위한 jail을 하나 추가합니다.
먼저 Fail2ban이 로그를 읽을 수 있도록 호스트에 있는 named volume의 위치를 확인하십시오:
docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}'결과로 /var/lib/docker/volumes/vaultwarden_vw-data/_data과 같은 경로가 출력됩니다. 해당 경로 내부의 로그 파일은 vaultwarden.log입니다. 필터를 생성하십시오:
# /etc/fail2ban/filter.d/vaultwarden.conf
[Definition]
failregex = ^.*Username or password is incorrect\. Try again\. IP: <ADDR>\. Username:.*$
ignoreregex =그 다음 jail을 생성하십시오:
# /etc/fail2ban/jail.d/vaultwarden.local
[vaultwarden]
enabled = true
filter = vaultwarden
logpath = /var/lib/docker/volumes/vaultwarden_vw-data/_data/vaultwarden.log
banaction = iptables-allports
chain = DOCKER-USER
maxretry = 5
findtime = 600
bantime = 3600sudo systemctl restart fail2ban를 사용하여 설정을 다시 로드하고 sudo fail2ban-client status vaultwarden으로 확인하십시오.
다음 세 가지 Docker 관련 설정에 따라 보호 여부가 결정됩니다. 첫째, 로그에 실패할 때마다 IP: 127.0.0.1 또는 프록시 주소가 기록된다면 Vaultwarden이 프록시 자체를 차단하게 됩니다. 이 경우 IP_HEADER을 프록시가 실제로 전송하는 헤더로 설정하십시오 (Traefik은 X-Forwarded-For, 위에서 설명한 nginx 블록은 X-Real-IP, Cloudflare 뒤에 있는 경우 CF-Connecting-IP). 둘째, 올바른 iptables chain은 프록시 설정에 따라 다릅니다. 포트가 공개된 컨테이너 형태의 Traefik을 사용하는 경우, 트래픽은 Docker의 FORWARD 경로를 통과하므로 차단 규칙은 위와 같이 DOCKER-USER에 있어야 합니다. 하지만 Step 1에서 host-nginx 옵션을 선택했다면, 연결은 호스트의 INPUT chain에 있는 nginx에서 종료됩니다. 이 경우 DOCKER-USER 차단은 트래픽을 감지할 수 없습니다. 이럴 때는 chain = DOCKER-USER 줄을 삭제하여 Fail2ban이 기본 INPUT chain을 사용하도록 설정하십시오. 셋째, 포트 기반의 기본값 대신 banaction = iptables-allports를 사용하십시오. 이 jail은 특정 포트를 지정하지 않습니다. DOCKER-USER에서 모든 포트를 차단하면 해당 공격자가 호스트의 모든 공개 서비스에 접속하는 것을 효과적으로 차단할 수 있습니다.
Step 8 — vault를 백업한 후 실제로 복구합니다
vw-data volume이 password manager입니다. 이 볼륨에는 db.sqlite3 (모든 entry), attachments/ 및 sends/ 디렉토리, 로그인 세션 서명용 rsa_key.* 파일, 그리고 admin panel의 config.json가 포함됩니다. 이 중 하나라도 누락된 백업은 실제 복구 시 실패합니다.
Vaultwarden이 데이터를 쓰는 동안 db.sqlite3를 복사하면 파일이 손상될 수 있습니다. 따라서 잠시 서비스를 중단하고 snapshot을 생성하십시오. 중단 시간은 몇 초 내외입니다:
#!/usr/bin/env bash
set -euo pipefail
STAMP=$(date +%F)
DEST=/root/vw-backups
VOL=$(docker volume inspect vaultwarden_vw-data --format '{{ .Mountpoint }}')
mkdir -p "$DEST"
docker compose -f /opt/vaultwarden/docker-compose.yml stop vaultwarden
tar czf "$DEST/vw-$STAMP.tgz" -C "$VOL" .
docker compose -f /opt/vaultwarden/docker-compose.yml start vaultwarden매일 밤 cron을 통해 실행하고 .tgz를 서버 외부로 복사하십시오. 보호하려는 서버에만 존재하는 백업은 진정한 의미의 백업이 아닙니다. 가장 권장되는 방법은 다른 서버나 object storage로 nightly restic backup을 수행하는 것입니다. 이 방식은 아카이브를 암호화하고 중복된 snapshot을 제거합니다. admin panel의 Backup Database 버튼은 SQLite 파일만 빠르게 snapshot으로 저장하지만, attachment와 key는 포함하지 않습니다.
이제 단순한 희망 사항이 아닌 실제 백업임을 증명하기 위해 복구 작업을 수행합니다:
mkdir -p /tmp/vw-restore
tar xzf /root/vw-backups/vw-2026-07-15.tgz -C /tmp/vw-restore
docker run --rm -p 127.0.0.1:8888:80 -v /tmp/vw-restore:/data vaultwarden/server노트북에서 ssh -L 8888:127.0.0.1:8888 you@your-vps를 사용하여 터널링을 생성한 후 http://localhost:8888를 엽니다. localhost는 secure context이므로 crypto.subtle를 사용할 수 있으며, 이 환경에서만 http를 통한 vault 복호화가 허용됩니다. 마스터 비밀번호로 로그인하여 entry가 모두 있는지 확인하십시오. 데이터가 정상적으로 보인다면 database, RSA keys, master password가 모두 정상적으로 복구된 것이며, 새로운 VPS에서도 몇 분 안에 재구축할 수 있습니다. Ctrl-C를 눌러 container를 중지하고 /tmp/vw-restore를 삭제하십시오.
Failure modes, with the strings you will see
브라우저 콘솔의 Cannot read properties of undefined (reading 'importKey'). Vault가 http를 통해 로드되어 crypto.subtle이(가) undefined 상태입니다. https://를 통해서만 접속해야 하며, proxy에서 HTTP-to-HTTPS 리다이렉트를 설정하십시오.
클라이언트의 This is not a recognized Bitwarden server.... Server URL이 http이거나, 오타가 있거나, 인증서를 신뢰할 수 없는 상태입니다. https://vault.example.com에 유효한 자물쇠 아이콘이 표시되는지 확인한 후, 클라이언트의 self-hosted 설정에 다시 입력하십시오.
/admin에서 올바른 비밀번호를 거부함. Argon2 해시의 이스케이프 문자가 유실되었습니다. 모든 $은 Compose에서 $$ 상태여야 합니다. 또는 평문 대신 해시 값을 입력했을 수 있습니다.
기기 간 동기화 지연; 콘솔에 WebSocket connection to 'wss://vault.example.com/notifications/hub' failed 표시. proxy가 Upgrade/Connection 헤더를 전달하지 않고 있습니다. Traefik은 이를 자동으로 처리하지만, nginx는 Step 1의 upgrade 라인 두 개가 필요합니다. Vault는 정상 작동하지만, 앱을 열 때만 동기화가 진행됩니다. v1.31.0부터 기존의 전용 포트 3012가 제거되었으므로, 별도의 WebSocket 경로는 필요하지 않습니다.
Fail2ban이 차단(ban)을 보고하지만 공격자가 계속 연결을 시도함. IP_HEADER가 잘못되어 127.0.0.1을(를) 차단하고 있거나, 차단 규칙이 잘못된 iptables chain에 있습니다. chain = DOCKER-USER 및 banaction = iptables-allports를 설정하십시오.
Upgrades
새 이미지를 pull한 뒤 recreate하십시오. named volume과 모든 데이터는 유지됩니다:
docker compose pull
docker compose up -dVaultwarden은 빈번하게 릴리스를 배포합니다. 일부 릴리스에는 마이그레이션 관련 사항이 포함될 수 있으므로, 특정 패치 버전을 고정하기보다 프로젝트 릴리스 노트를 확인하십시오. 주요 버전 업데이트 전에는 반드시 백업을 생성하십시오. tarball을 새 volume에 복원하여 롤백할 수 있습니다.
FAQ
Vaultwarden은 Bitwarden과 동일한 제품입니까?
Vaultwarden은 공식 서버가 아닌, 호환 가능한 독립형 서버입니다. Vaultwarden은 Bitwarden 서버 API를 Rust 언어로 재구현했습니다. 따라서 공식 desktop, mobile, browser 및 CLI 클라이언트를 모두 사용할 수 있으며, 공식 스택보다 훨씬 적은 리소스를 사용합니다. Vault 형식은 동일하므로, 내보내기(export)와 가져오기(import)를 통해 양방향으로 마이그레이션할 수 있습니다.
HTTPS가 반드시 필요합니까? 아니면 LAN에서 http로 실행해도 됩니까?
localhost 테스트 목적이 아니라면 HTTPS가 반드시 필요합니다. Bitwarden web vault와 확장 프로그램은 브라우저의 Web Crypto API를 사용합니다. 이 API는 보안 컨텍스트(secure context)에서만 사용할 수 있습니다. 따라서 일반 http를 사용하면 클라이언트에서 Cannot read properties of undefined 오류가 발생하며 로그인이 불가능합니다. 작동하는 유일한 http 주소는 http://localhost뿐입니다. Step 8의 복구 테스트에서 SSH 터널을 사용하는 이유가 이것입니다.
외부인이 서버에 등록하는 것을 어떻게 막습니까?
계정을 생성한 직후 Compose 파일에 SIGNUPS_ALLOWED: "false"을 설정하고 docker compose up -d를 실행하십시오. 그 이후부터는 /admin의 Invite User 버튼을 통해 새로운 사용자를 추가해야 합니다. 사용자가 초대 링크를 받으려면 SMTP 설정이 완료되어 있어야 합니다. 예상치 못한 계정이 생성되지 않았는지 관리자 사용자 목록을 주기적으로 확인하십시오.
Vaultwarden vault를 어떻게 백업합니까?
컨테이너를 잠시 중지한 후 vw-data 볼륨 전체를 아카이브하십시오. 대상은 db.sqlite3, attachments/, sends/, config.json 및 rsa_key.* 파일입니다. 그 다음 아카이브를 서버 외부로 복사하십시오. 야간 cron 작업을 사용하는 것이 가장 좋습니다. 서버가 실행 중인 상태에서 SQLite 파일을 복사하면 데이터가 손상될 위험이 있으므로, 반드시 중지된 상태에서 백업하십시오. 가장 중요한 점은, 백업이 유효한지 확인하기 위해 테스트용 컨테이너에 한 번 복구하여 로그인을 시도해 보는 것입니다.
비밀번호를 직접 호스팅하는 것이 실제로 안전합니까?
본 가이드에서 다루는 세 가지 사항을 준수한다면 안전합니다. 즉, 실제 HTTPS 적용, 회원가입 차단 및 강력한 admin token 설정, 그리고 검증된 백업입니다. Vault는 마스터 비밀번호를 통해 클라이언트 측에서 암호화됩니다. 따라서 서버는 비밀번호를 평문으로 볼 수 없습니다. db.sqlite3이 탈취되어도 마스터 비밀번호 없이는 무용지물입니다. 다만, 패치와 백업에 대한 책임이 사용자에게 있다는 점을 유의하십시오. 이것이 Fail2ban과 복구 테스트가 필수적인 이유입니다.