SSD Nodes Learn Hosting plans →
가이드 Matt Connor작성자 Matt Connor · 업데이트됨 2026-09-07

Stalwart 메일 서버 설치 및 Postfix 비교 분석

Stalwart가 단일 Rust 바이너리로 Postfix와 Dovecot 스택을 어떻게 대체하는지 설명합니다. 포트 25 차단 문제와 엔터프라이즈 라이선스 제한 사항을 포함하여 직접 설치 전 반드시 확인해야 할 기술적 제약과 메일 도달률 최적화 전략을 상세히 다룹니다.

Stalwart가 하나의 바이너리로 통합하는 기능

Stalwart는 단일 Rust 바이너리로 구성되어 하나의 VPS에서 실행되는 메일 서버입니다. 이 프로세스 하나가 SMTP, IMAP, POP3, JMAP, CalDAV, CardDAV 및 WebDAV 요청을 모두 처리하며, 자체 스팸 필터, 메시지 저장소, ACME 클라이언트를 내장하고 있습니다. 기존의 메일 서버 스택은 Postfix, Dovecot, Rspamd, 계정용 데이터베이스, 별도의 인증서 도구를 조합하여 같은 작업을 수행합니다. Stalwart는 이 모든 것을 하나의 서비스 유닛과 /etc/stalwart/config.json에 위치한 하나의 설정 파일로 대체합니다.

아래의 모든 수치, 설정 이름, 명령어는 2026년 8월 28일 기준으로 v0.16.19 릴리스(2026년 8월 24일 배포)의 Stalwart 공식 문서, 릴리스 페이지, 설치 스크립트에서 인용했습니다. 이는 사용자가 자신의 서버에서 직접 실행할 명령어들입니다. 각 명령어 뒤에는 정상 작동 여부를 확인할 수 있는 검증 절차가 이어집니다.

Stalwart는 GNU Affero General Public License v3.0(AGPL-3.0)과 Stalwart Enterprise License v2의 이중 라이선스를 따릅니다. 일부 기능은 엔터프라이즈 버전에서만 제공됩니다. 문서화된 HTTP 엔드포인트 목록 중 /scim/v2/*로 표시된 항목이 이에 해당합니다. 직접 실행해보지 않은 기능을 기반으로 배포 계획을 세우기 전에 반드시 라이선스 약관을 확인하십시오.

바이너리 하나로 통합하면 움직이는 부품(moving parts)이 확실히 줄어듭니다. 하지만 메일 도달 여부를 결정짓는 두 가지 핵심 요소까지 줄어드는 것은 아닙니다.

포트 25와 DNS 평판은 어떤 소프트웨어를 실행하는지 고려하지 않습니다

아웃바운드 TCP 포트 25는 첫 번째 관문입니다. 많은 VPS 제공업체는 새 계정에서 이 포트를 기본적으로 차단하며, 포트 25가 차단되면 서버는 자기 자신과만 통신할 수 있고 외부와는 통신할 수 없습니다. 무엇을 설치하기 전에 이 포트를 먼저 테스트하십시오.

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 alt1.aspmx.l.google.com 25

정상적인 결과는 약 1초 안에 Connection to alt1.aspmx.l.google.com ... 25 port [tcp/smtp] succeeded!를 출력합니다. 차단된 포트는 패킷이 업스트림에서 드롭되고 리셋 신호가 돌아오지 않기 때문에 5초 동안 응답이 없다가 nc: connect to alt1.aspmx.l.google.com port 25 (tcp) failed: Connection timed out을 출력합니다. 만약 이런 결과가 나온다면 제공업체에 문의 티켓을 제출하십시오. 드롭된 패킷을 우회하여 메일을 전송할 수 있는 메일 서버는 없습니다.

두 번째 관문은 수신 측 네트워크가 귀하의 IP 주소와 도메인을 어떻게 평가하느냐입니다. 이는 IP에 대한 역방향 DNS(reverse DNS), SPF, DKIM, DMARC, 그리고 귀하가 할당받은 IP 대역의 발송 이력을 의미합니다. Stalwart의 DNS 설정 페이지는 이러한 작업이 어디에서 이루어지는지 명확히 밝히고 있습니다. 역방향 DNS 레코드는 "Stalwart 자체가 아닌 호스팅 제공업체에서 설정하는 것이 일반적"입니다. 나머지 항목들도 마찬가지입니다. 이 설정들은 메일 서버 내부가 아니라 귀하의 DNS 영역과 제공업체의 제어판에서 관리됩니다.

따라서 이 페이지에서는 해당 레코드들을 다시 설명하지 않습니다. 관련 내용을 다루는 별도의 가이드가 있습니다: 메일을 발송하는 모든 서비스를 위한 SPF, DKIM, DMARC 설정. 메일 서버를 직접 운영할지 아직 결정하지 못했다면, 메일 서버 직접 운영의 가치에 대한 솔직한 분석을 먼저 읽어보시기 바랍니다. Stalwart를 선택한다고 해서 이러한 운영상의 고려 사항이 달라지지는 않습니다.

소규모 VPS에서 Stalwart 메일 서버를 운영하기 위한 요구 사항

2026년 8월 28일에 확인한 Stalwart 시스템 요구 사항 페이지에 따르면, 유휴 상태의 메모리 사용량은 약 100 MB입니다. 5명에서 10명 정도의 사용자를 위한 소규모 배포는 1 GB RAM으로 충분합니다. 약 5명의 사용자가 이용하는 저트래픽 환경은 단일 CPU 코어에서 동작하며, 해당 페이지는 "동시 접속과 활동이 증가함에 따라 낮은 지연 시간과 높은 처리량을 유지하려면 더 많은 CPU 코어가 필요하다"고 덧붙이고 있습니다. 기본 연결 제한은 모든 서비스를 통틀어 8,192개의 동시 연결이며, 이는 설정으로 변경할 수 있습니다.

해당 페이지에는 최소 디스크 크기에 대한 명시가 없으므로, 보관할 메일 용량과 저장소 압축을 위한 여유 공간을 고려하여 디스크 크기를 산정하십시오.

세 가지 아웃바운드 경로가 정상적으로 작동해야 합니다. 그렇지 않으면 메일 기능과는 무관한 문제로 서버가 고장 난 것처럼 보일 수 있습니다. 서버는 https://github.com/stalwartlabs/webui/releases/latest/에서 웹 인터페이스 번들을 가져옵니다. 인증서를 위해 https://acme-v02.api.letsencrypt.org/directory에 접근합니다. 또한 MX 및 인증 레코드 조회를 위해 UDP 및 TCP 포트 53번을 통한 DNS 통신이 필요합니다. 첫 번째 경로를 차단하는 엄격한 이그레스 방화벽을 설정하면 관리 인터페이스가 없는 메일 서버가 실행되는 상태가 됩니다.

"latest" 대신 특정 릴리스 버전 설치하기

공식 설치 프로그램은 셸 스크립트입니다. 실행하기 전에 내용을 읽어보십시오.

curl --proto '=https' --tlsv1.2 -sSf https://get.stalw.art/install.sh -o install.sh
less install.sh
sudo sh install.sh

2026년 8월 28일 기준으로 해당 스크립트를 읽어보면 수행하는 작업이 명확히 드러납니다. 스크립트는 stalwart 서비스 계정을 생성하고 필요한 디렉터리를 만듭니다. 그 후 https://github.com/stalwartlabs/stalwart/releases/latest/download에서 바이너리를 다운로드합니다. 바이너리는 /usr/local/bin/stalwart에 0755 모드로 저장됩니다. 설정 파일은 /etc/stalwart/config.json, 데이터는 /var/lib/stalwart, 로그는 /var/log/stalwart에 저장되며, 이 세 디렉터리는 모두 stalwart 소유의 0750 모드로 설정됩니다. 환경 파일은 /etc/stalwart/stalwart.env에 0640 모드로 작성되며 소유자는 root:stalwart입니다. 스크립트는 선택적인 설치 접두사와 FoundationDB 빌드를 위한 --fdb 플래그를 인자로 받습니다. 버전 인자는 받지 않습니다.

마지막 사항이 중요합니다. 스크립트는 항상 최신 릴리스를 가져오므로, 일주일 간격으로 구축한 두 서버가 동일한 코드를 실행하지 않을 수 있습니다. 설치 직후 직접 바이너리를 고정하십시오. 이는 v0.16.19 릴리스 노트에서 제시하는 업그레이드 방식이기도 합니다: "v0.16.x에서 업그레이드하는 경우 바이너리를 교체하십시오(또는 docker pull을 실행하십시오)."

STALWART_TAG=v0.16.19
curl -fsSLO "https://github.com/stalwartlabs/stalwart/releases/download/${STALWART_TAG}/stalwart-x86_64-unknown-linux-gnu.tar.gz"
tar zxf stalwart-x86_64-unknown-linux-gnu.tar.gz
sudo systemctl stop stalwart
sudo install -m 0755 -o root -g root stalwart /usr/local/bin/stalwart
sudo systemctl start stalwart
systemctl is-active stalwart

systemctl is-active stalwartactive을 출력해야 합니다. 다른 결과가 나온다면 journalctl -u stalwart -n 50를 읽어보십시오. 모든 릴리스 에셋은 일치하는 .sigstore.json 번들과 함께 제공되므로, 설치 전에 다운로드한 파일의 서명을 검증할 수 있습니다.

스크립트가 작성하는 유닛은 User=stalwart 계정으로 실행되며 AmbientCapabilities=CAP_NET_BIND_SERVICE를 설정합니다. 이 권한 덕분에 권한이 없는 계정도 25, 443, 465, 993 포트를 바인딩할 수 있습니다. 나중에 직접 유닛 파일을 작성할 때 해당 줄을 생략하면, 일반 사용자는 1024 미만의 포트를 바인딩할 수 없으므로 서비스 시작 시 실패합니다.

최초 관리자 비밀번호가 출력되는 위치

Stalwart는 부트스트랩 모드로 시작하며 16자리의 임시 비밀번호를 서비스 로그에 단 한 번 기록합니다.

sudo journalctl -u stalwart -n 200 | grep -A8 'bootstrap mode'

설정 마법사는 8080 포트에서 일반 HTTP로 대기하므로, 해당 포트를 외부로 노출하지 마십시오. 대신 노트북에서 SSH를 통해 터널링하십시오:

ssh -N -L 8080:127.0.0.1:8080 you@your-vps

그다음 http://127.0.0.1:8080/admin을 열고 로그에 있는 비밀번호를 사용하여 admin 계정으로 로그인하십시오. 마법사는 서버 호스트 이름, 기본 메일 도메인, TLS, 스토리지, 계정 디렉터리, 로깅 및 DNS 처리 방식을 묻습니다. 설정이 완료되면 서비스를 재시작하고, 이후부터는 https://<your-host>/admin를 사용하십시오.

비밀번호가 로그에서 밀려나 확인이 불가능하다면 고정 비밀번호를 설정하십시오. /etc/stalwart/stalwart.env에는 이를 위한 주석 처리된 항목이 포함되어 있으며, 여기에는 STALWART_RECOVERY_ADMIN=admin:changeme, STALWART_RECOVERY_MODE=trueSTALWART_RECOVERY_MODE_PORT(기본값 8080)가 포함됩니다. 주석을 해제하고 재시작한 뒤 로그인하고, 다시 주석 처리하십시오. Stalwart의 보안 강화(hardening) 페이지에서는 해당 자격 증명을 비상시에만 사용하고, 관리자 계정으로 IMAP, JMAP 또는 WebDAV에 로그인하지 말 것을 권고합니다.

같은 페이지에는 유지해야 할 리스너 목록이 나열되어 있습니다. 인바운드 SMTP용 25번 포트, 암시적 TLS를 사용하는 제출(submission)용 465번 포트, IMAPS용 993번 포트, 그리고 모든 HTTP 트래픽을 위한 443번 포트입니다. 587, 143, 4190, 110, 995 및 8080 포트는 필수적이지 않은 것으로 간주하며, 설정이 완료되면 8080 포트를 비활성화할 것을 권장합니다.

Docker에서 고정 태그로 실행하기

문서화된 이미지는 stalwartlabs/stalwart입니다. 2026년 8월 28일 기준으로 Docker Hub에는 v0.16.19 태그가 존재하며, -alpine 변형도 함께 제공됩니다. 위에서 언급한 바이너리와 같은 이유로 v0.16 플로팅 태그가 아닌 패치 버전을 고정하십시오.

services:
  stalwart:
    image: stalwartlabs/stalwart:v0.16.19
    container_name: stalwart
    restart: unless-stopped
    ports:
      - "25:25"
      - "465:465"
      - "993:993"
      - "443:443"
      - "127.0.0.1:8080:8080"
    volumes:
      - stalwart-etc:/etc/stalwart
      - stalwart-data:/var/lib/stalwart
volumes:
  stalwart-etc:
  stalwart-data:

해당 파일은 문서화된 docker run 명령어를 Compose 형식으로 작성한 것이며, 필수적이지 않은 리스너는 제외하고 설정 포트를 localhost에 바인딩했습니다. 서비스를 시작하고 동일한 부트스트랩 줄을 확인하십시오:

docker compose up -d
docker compose logs stalwart 2>&1 | grep -A8 'bootstrap mode'

Docker 페이지에서는 시작 시 고정 자격 증명을 설정하는 방법으로 -e STALWART_RECOVERY_ADMIN=admin:mySecretPass를 안내하고 있으며, 로그를 읽는 것보다 Compose의 environment: 키를 사용하는 것을 선호한다면 이를 활용하십시오.

문서화된 전체 포트 목록 및 이 파일이 더 짧은 이유

Stalwart의 Docker 페이지는 443, 8080, 25, 587, 465, 143, 993, 110, 995, 4190 포트를 공개합니다. 보안 강화 페이지에서는 587, 143, 110, 995, 4190 포트를 필수적이지 않은 것으로 분류하며, 설정 후 8080 포트를 비활성화할 것을 권장합니다. 클라이언트가 실제로 요구하는 포트만 다시 추가하십시오. 휴대폰에서 STARTTLS 제출을 요구한다면 587 포트를 공개하고, 사용자가 데스크톱 클라이언트에서 Sieve 규칙을 작성한다면 4190 포트를 공개하십시오.

Compose가 생소하다면 VPS를 위한 Docker Compose 가이드에서 파일 레이아웃과 이 설정에서 사용하는 명명된 볼륨 모델을 확인하십시오. 메일 서버 운영 시 특히 주의할 점이 있습니다. Docker는 자체 방화벽 규칙을 작성하여 포트를 공개하는데, 이 규칙은 ufw보다 우선 적용되므로 ufw deny 8080 명령으로는 Compose가 공개한 포트를 닫을 수 없습니다. 포트 매핑에서 127.0.0.1에 바인딩해야 실제로 포트가 닫히며, 위 파일이 그렇게 작성된 이유이자 SSH 터널이 여전히 유효한 이유입니다.

Certbot 없이 TLS 사용하기와 그에 따른 제약 사항

Stalwart는 ACME(automatic certificate management environment)를 직접 구현하므로 certbot이나 갱신용 훅(renewal hook)이 필요하지 않습니다. 문서에는 4가지 검증 방식이 명시되어 있습니다. HTTP-01은 포트 80에서 챌린지 요청에 응답합니다. TLS-ALPN-01은 ACME 전용 ALPN 프로토콜을 사용하여 포트 443에서 전용 인증서를 제시합니다. DNS-01은 임시 TXT 레코드를 게시하며, 와일드카드 인증서를 발급할 수 있는 두 가지 방식 중 하나입니다. DNS-PERSIST-01은 매번 갱신할 때마다 새로운 레코드를 작성하는 대신 장기 유지되는 인증용 TXT 레코드를 사용합니다.

이 방식의 제약 사항은 Stalwart가 해당 포트를 직접 점유해야 한다는 점입니다. TLS-ALPN-01은 자체적으로 TLS 핸드셰이크를 완료하는 방식으로 동작하므로, TLS를 대신 종료해 주는 리버스 프록시 뒤에서는 성공할 수 없습니다. 만약 해당 서버에서 nginx나 Caddy가 이미 포트 443을 사용 중이라면, Stalwart의 방식을 DNS-01로 변경하거나 Stalwart에 별도의 IP 주소를 할당해야 합니다.

DANE 및 MTA-STS와 알아두어야 할 기본값

두 설정 모두 웹 인터페이스의 Settings, MTA, Outbound, TLS Strategies 경로에 있는 MtaTlsStrategy 객체에서 TLS 전략별로 구성합니다. dane 필드의 기본값은 optional이며, 수신자가 TLSA 레코드를 게시한 경우 DANE 검증을 시도하고 그렇지 않으면 일반 STARTTLS로 대체합니다. require로 설정하면 검증 가능한 TLSA 레코드가 있을 때만 전송이 진행됩니다. mtaSts 필드도 동일하게 동작하며 기본값은 optional입니다. 관련 타임아웃 설정은 tlsTimeout(기본값 3분)와 mtaStsTimeout(기본값 5분)입니다.

인바운드 측면에서 Stalwart는 https://mta-sts.<domain>/.well-known/mta-sts.txt 경로에 자체 MTA-STS 정책을 게시할 수 있으며, 이를 위해서는 443번 포트가 열려 있어야 합니다. MtaSts 싱글톤에는 mode(기본값 testing), maxAge(기본값 7일), 그리고 mxHosts가 포함되어 있으며, mxHosts가 비어 있으면 TLS 인증서의 호스트 이름을 사용합니다. 두 개의 DNS 레코드를 제공해야 합니다. 메일 호스트를 가리키는 mta-sts CNAME 레코드와 정책 식별자를 포함하는 _mta-sts TXT 레코드입니다.

dig +short TXT _mta-sts.example.org
curl -s https://mta-sts.example.org/.well-known/mta-sts.txt

TXT 조회 시 v=STSv1; id=... 문자열이 반환되어야 하며, curl 명령은 정책 본문을 반환해야 합니다. curl이 아무것도 반환하지 않는다면 443번 포트가 닫혀 있거나 mta-sts.example.org에 대한 인증서가 발급되지 않은 상태입니다.

두 확인 절차를 모두 통과할 때까지 modetesting로 유지하십시오. 인증서가 잘못된 상태에서 enforce 모드로 정책을 운영하면 다른 서버가 메일을 전달할 수 없게 되며, 로그가 아닌 사용자로부터 문제를 전해 듣게 될 것입니다. DANE에도 주의할 점이 있습니다. DANE은 DNSSEC으로 서명된 영역을 요구하며, 리프 인증서를 고정(pinning)하는 TLSA 레코드는 ACME가 갱신될 때마다 다시 게시해야 합니다. 발급 CA를 고정하거나, 갱신 작업을 감수하십시오.

저장 데이터 암호화는 종단간 암호화가 아닙니다

이 기능은 가장 자주 오해받는 부분이므로, 문서에 명시된 내용을 정확히 설명합니다. 사용자의 일반 텍스트 메시지는 디스크에 기록되기 전 OpenPGP 또는 S/MIME 인증서를 사용하여 자동으로 암호화됩니다. encryptAtRest은 기본적으로 활성화되어 있으며, 수신자가 암호화 키를 등록한 경우 SMTP 또는 LMTP를 통해 도착하는 메시지에 적용됩니다. encryptOnAppend은 기본값이 false이며, "클라이언트가 저장된 콘텐츠에 대한 완전한 제어권을 유지할 수 있도록 추가된 메시지는 그대로 둡니다". OpenPGP는 구형 PGP/Inline 대신 PGP/MIME을 사용하며, AES-256 또는 AES-128을 지원합니다. Stalwart는 키를 생성하지 않습니다. 사용자는 ASCII-armored 형식의 공개 키를 내보낸 뒤, Account의 Public Keys 아래에 PublicKey 객체로 등록해야 합니다.

따라서 이 기능은 디스크 이미지 도난, 백업 도난, 그리고 배달 후 저장소를 읽으려는 운영자로부터 데이터를 보호합니다. 개인 키가 없으면 저장된 바이트는 읽을 수 없으며, 관리자도 이를 복호화할 수 없습니다.

이 기능은 전송 중인 메시지를 보호하지 않습니다. 메시지는 두 서버가 합의한 TLS를 통해 인터넷을 가로질러 일반 텍스트로 도착하며, Stalwart는 그 시점에 메시지를 암호화합니다. 발신자, 발신자의 서비스 제공자, 그리고 TLS를 제거한 모든 경유지는 이미 일반 텍스트를 확인한 상태입니다.

추가로 세 가지 제한 사항을 명확히 밝힙니다. Sent 및 Drafts 폴더는 클라이언트가 기록하며 이는 추가(append) 작업에 해당합니다. encryptOnAppend은 기본값이 false이므로, 설정을 변경하지 않으면 해당 폴더의 내용은 암호화되지 않은 상태로 남습니다. 2026년 8월 28일에 확인한 문서에는 메시지 본문에 대해서만 설명되어 있으며, 봉투 데이터(envelope data), 헤더, 인덱스 항목이 암호화된다는 언급은 없으므로 암호화된다고 가정하지 마십시오. 또한 키를 업로드하기 전에 이미 저장된 메시지가 재암호화된다는 내용도 없으므로, 그렇지 않다고 가정하고 확인하십시오. 암호화된 본문에 대해 전체 텍스트 검색이 작동하는지 여부도 명시되어 있지 않습니다. 누구에게도 약속하기 전에 테스트 계정에서 직접 확인하십시오.

사용자가 개인 키를 분실하면 메일은 영구적으로 손실됩니다. 설계상 복구 경로는 존재하지 않습니다.

WKD는 메일 서버 작업이 아니라 웹 서버 작업입니다

WKD(Web Key Directory)는 OpenPGP의 나머지 절반을 담당하며, 다른 문제를 해결합니다. WKD는 사용자의 공개 키를 도메인 하위의 고정된 HTTPS URL에 게시하여, 발신자의 메일 클라이언트가 이를 찾아 메시지가 발신자의 기기를 떠나기 전에 암호화할 수 있도록 합니다. 이것이 종단간 암호화(end-to-end encryption)입니다. Stalwart의 저장 데이터 암호화(at-rest encryption)는 디스크에 저장된 사본에 대한 것입니다. 하나를 설정한다고 해서 다른 하나가 제공되지는 않습니다.

Stalwart는 WKD를 제공하지 않습니다. 2026년 8월 28일에 확인한 Stalwart의 문서화된 HTTP 엔드포인트는 jmap, caldav, carddav, oauth-authorization-server, openid-configuration, acme-challenge, mta-sts.txt, mail-v1.xml 및 자동 설정(autoconfig)을 위한 잘 알려진 경로들을 나열하고 있습니다. openpgpkey 경로는 존재하지 않습니다. 일반적인 정적 웹 서버를 통해 서비스하십시오.

사양은 두 가지 레이아웃을 정의합니다. 고급 방식은 https://openpgpkey.example.org/.well-known/openpgpkey/example.org/hu/iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=Joe.Doe을 사용합니다. 직접 방식은 https://example.org/.well-known/openpgpkey/hu/iy9q119eutrkn8s1mk4r39qejnbu3n5q?l=Joe.Doe를 사용합니다. 해당 32자 문자열은 소문자로 변환된 로컬 파트를 z-base-32로 인코딩한 SHA-1 해시값이므로, 이러한 파일 이름을 직접 생성해서는 안 됩니다. GnuPG가 이를 대신 생성해 줍니다.

gpg --export --armor you@example.org > you.asc
gpg-wks-client --print-wkd-url you@example.org
gpg-wks-client --install-key you.asc you@example.org

--print-wkd-url는 서브도메인 형식을 사용하여 클라이언트가 가져올 URL을 출력합니다. --install-key은 WKD 레이아웃을 반영하는 로컬 디렉터리 트리 내에 키를 기록하며, 기본적으로 openpgpkey이라는 최상위 디렉터리 아래에 생성되고 -C dir을 통해 변경할 수 있습니다. 해당 트리를 웹 루트로 복사하고, hu 디렉터리 옆에 필수적인 policy 파일을 추가한 뒤(빈 파일도 유효합니다), curl을 사용하여 자신의 URL을 가져와 404 오류가 아닌 키 바이트가 반환되는지 확인하십시오.

단일 VPS에서의 스토리지

Stalwart는 스토리지를 네 가지 역할로 나눕니다. 메일함 상태와 같은 구조화된 레코드를 위한 데이터 저장소, 원시 메시지 바이트와 첨부 파일을 위한 블롭(blob) 저장소, 전문 검색 인덱싱을 위한 검색 저장소, 그리고 속도 제한, 인증 토큰, 세션 데이터를 위한 인메모리 저장소가 그것입니다. 각 역할은 서로 다른 백엔드를 가리킬 수 있습니다. 지원되는 목록에는 RocksDB, FoundationDB, PostgreSQL, MySQL, SQLite, S3 호환 객체 스토리지, Azure Blob Storage, Redis, ElasticSearch, Meilisearch가 포함됩니다.

단일 VPS 환경에서의 답은 간단합니다. 문서에서는 RocksDB를 "속도와 신뢰성 때문에 Stalwart의 단일 노드 설치에 권장되는 백엔드"라고 설명합니다. Redis는 인메모리 저장소로만 지원되며 데이터 저장소나 블롭 저장소로 사용할 수 없으므로, 시작하기 위해 별도의 Redis 컨테이너가 필요하지 않습니다. 메일함이 디스크 용량을 초과하면 나중에 블롭 저장소를 S3로 옮기면 됩니다.

백업은 백엔드에 따라 다릅니다. 외부 데이터베이스의 경우 해당 데이터베이스의 자체 절차를 사용하십시오. 내장 데이터베이스의 경우 FAQ에서는 /var/lib/stalwart 디렉터리를 복사하라고 안내합니다. 이 작업은 서비스를 중지한 상태에서 수행하거나, 파일 시스템 또는 볼륨 스냅샷을 통해 수행해야 합니다. 실행 중인 키-값 저장소를 파일 수준에서 복사하면 쓰기 도중의 상태가 캡처될 수 있으며, 복원을 시도하기 전까지는 데이터 손상 여부를 알 수 없습니다.

Rspamd를 대체하는 스팸 필터

필터링은 동일한 프로세스 내부에서 실행되므로, 별도로 유지해야 할 두 번째 데몬은 없습니다. 분류기는 Settings, Spam Filter, Classifier 아래의 SpamClassifier 싱글톤에서 설정합니다. 이 분류기는 특성 해싱(feature hashing)과 함께 FTRL-Proximal 알고리즘을 사용합니다. 대부분의 배포 환경에서는 FtrlFh을 기본값으로 권장합니다. FtrlCcfh는 해시 충돌을 줄이기 위해 쿠쿠(cuckoo) 특성 해싱으로 교체하며, 대규모 배포 환경을 대상으로 합니다. 학습은 지속적으로 이루어집니다. 사용자가 메시지를 스팸이나 정상 메일(ham)로 표시하면, 해당 레이블이 즉시 반영되어 향후 결정에 사용됩니다.

분류기 주변에는 DNS 차단 목록, 그레이리스팅(greylisting), 피싱 탐지, 스팸 트랩, Pyzor가 배치되어 있으며, 포기할 수 없는 규칙이 있는 경우 milter를 통해 SpamAssassin을 호출하는 옵션도 제공합니다.

mailcow가 여전히 올바른 선택인 경우

Stalwart에는 웹메일이 없습니다. 이는 가장 큰 결점이며, 다른 요소와 비교할 수준이 아닙니다. 2026년 8월 28일에 확인한 mailcow 문서에는 SOGo를 포함한 16개의 구성 요소가 나열되어 있으며, 이를 통해 사용자에게 브라우저 기반의 받은 편지함과 CalDAV 및 CardDAV 인터페이스를 즉시 제공할 수 있습니다. Stalwart의 2025년 6월 20일 로드맵 게시물에 따르면 내장 웹메일은 "계획에는 있으나 현재 당면한 우선순위는 아니며", 버전 1.0 이후 Rust와 Dioxus로 구축될 예정이고 "2026년 중 언젠가"가 될 가능성이 높다고 합니다. 2026년 8월 28일 기준으로 프로젝트 블로그에는 관련 발표가 없습니다. 따라서 Stalwart를 사용하려면 Roundcube를 직접 배포하거나 모든 사용자에게 메일 클라이언트를 설정하도록 안내해야 합니다.

Stalwart에는 웹 관리자 인터페이스가 있으므로, 사람들이 예상하는 것만큼 큰 공백은 아닙니다. 두 번째 공백은 버전의 성숙도입니다. FAQ에 따르면 Stalwart는 0.x 버전이며 데이터 레이아웃과 설정이 v1.0 이전에 변경될 수 있어 마이그레이션이 필요할 수 있습니다. 프로젝트의 2026년 6월 게시물 제목은 "열린 버그 리포트 0건: Stalwart 1.0으로 가는 길"로, 현재 상태가 1.0에 근접했지만 아직 도달하지 않았음을 보여줍니다.

세 번째 공백은 기능 목록에 아무도 적지 않는 부분입니다. Postfix, Dovecot, Rspamd는 10년간 축적된 해결책을 보유하고 있습니다. 새벽 2시에 메일이 큐에 쌓이고 사용자들이 기다리는 상황에서, 일치하는 에러 문자열을 찾아주는 검색 결과는 우아한 아키텍처보다 훨씬 가치가 있습니다. 이러한 상황이라면 mailcow 설치 가이드가 전체 스택을 처음부터 끝까지 안내하므로 밤을 더 짧게 보낼 수 있습니다.

단일 바이너리, 단일 설정 파일, JMAP을 원하고 초기 도입 단계의 불편함을 감수할 수 있다면 Stalwart를 선택하십시오. 당장 웹메일이 필요하고 기존에 축적된 방대한 해결책을 활용하고 싶다면 mailcow를 선택하십시오.

기존 메일 이전

일반적인 경로는 imapsync를 사용하는 IMAP 간 이전이며, 양쪽 끝에서 어떤 소프트웨어를 실행하는지는 중요하지 않습니다. 먼저 드라이 런(dry run)을 수행하십시오.

imapsync --dry \
  --host1 old.example.org --user1 you@example.org --passfile1 /root/.old.pw \
  --host2 mail.example.org --user2 you@example.org --passfile2 /root/.new.pw

--dry 플래그를 사용하면 imapsync는 "실제 작업을 수행하지 않고 수행될 작업만 출력"하므로, 플래그를 제거하기 전에 해당 출력을 확인하십시오. 각 암호 파일은 첫 번째 줄에 암호를 포함하므로, chmod 600 두 파일을 모두 사용한 뒤 나중에 삭제하십시오.

Stalwart는 대부분의 타사 가이드가 아직 다루지 못한 최신 도구도 함께 제공합니다. Stalwart 블로그에는 JMAP 가져오기 및 내보내기 도구인 Vandelay(2026년 5월 29일)와 무중단 업그레이드를 위한 마이그레이션 프록시(2026년 6월 10일)에 대한 문서가 있습니다. 다른 곳에서 찾을 수 있는 거의 모든 자료보다 최신 정보이므로 대규모 이전을 계획하기 전에 두 문서를 모두 읽어보시기 바랍니다.

실패 유형과 표시되는 문자열

관리자 인터페이스가 로드되지 않습니다. FAQ에서 이 문제를 직접 다룹니다. 웹 인터페이스 번들은 최초 실행 시 GitHub에서 다운로드되므로, github.com로의 아웃바운드 HTTPS 연결이 불가능한 서버에서는 서비스는 실행되지만 빈 페이지만 표시됩니다. 서버에서 curl -sI https://github.com/stalwartlabs/webui/releases/latest/ 명령으로 확인하십시오. FAQ에 나열된 다른 일반적인 원인으로는 HTTP 또는 HTTPS 스킴 불일치, 클라이언트 IP를 전달하지 않는 리버스 프록시 설정 등이 있습니다.

로그에 부트스트랩 비밀번호가 없습니다. 비밀번호는 부트스트랩 모드에서 시작할 때 단 한 번만 출력됩니다. 서비스가 그 이후에 재시작되었다면 sudo journalctl -u stalwart --since today | grep -A8 'bootstrap mode' 명령으로 로그 범위를 넓혀 확인하십시오. 비밀번호를 완전히 찾을 수 없다면 /etc/stalwart/stalwart.env 파일에 STALWART_RECOVERY_ADMIN 설정을 추가하고 재시작하십시오.

로컬 프록시를 통한 릴레이가 거부됩니다. v0.16.19 릴리스 노트에는 host resolves loopback address 오류로 릴레이 경로가 거부되던 문제에 대한 수정 사항이 기록되어 있습니다. 정확히 해당 문자열이 나타난다면 이전 빌드를 사용 중인 것입니다. 우회하지 말고 최신 버전으로 업데이트하십시오.

직접 작성한 유닛 파일로 서비스가 시작되지 않습니다. AmbientCapabilities=CAP_NET_BIND_SERVICE 설정이 없으면 stalwart 사용자는 25, 443, 465, 993 포트에 바인딩할 수 없으며, 첫 번째 리스너에서 시작이 실패합니다. 설치 프로그램이 생성한 유닛 파일에서 capability 라인을 복사하십시오.

인증서가 발급되지 않습니다. HTTP-01 방식을 사용하려면 80 포트가 열려 있고 사용 가능해야 합니다. TLS-ALPN-01 방식을 사용하려면 Stalwart가 직접 443 포트에서 TLS 핸드셰이크에 응답해야 합니다. 서버의 다른 프로세스가 해당 포트를 점유하고 있다면, 다른 모든 상태가 정상으로 보여도 ACME 인증은 계속해서 조용히 실패할 것입니다.

FAQ

Stalwart가 하나의 VPS에서 Postfix, Dovecot, Rspamd를 대체할 수 있습니까?

네, 가능합니다. 하나의 Rust 바이너리가 SMTP, IMAP, POP3, JMAP, CalDAV, CardDAV, WebDAV를 모두 처리하며, 스팸 필터, 메시지 저장소, ACME 클라이언트까지 포함하고 있습니다. 4개의 데몬과 그 사이를 연결하는 복잡한 설정 대신 /etc/stalwart/config.json에 위치한 하나의 systemd 유닛과 하나의 설정 파일만 관리하면 됩니다. 다만 DNS 영역 설정이나 서비스 제공업체의 포트 25 정책은 대체하지 않으며, 자가 호스팅 메일의 성공 여부는 이 부분에서 결정됩니다.

Stalwart 메일 서버는 어느 정도의 RAM이 필요합니까?

2026년 8월 28일 기준 Stalwart 시스템 요구사항 페이지에 따르면, 유휴 상태에서 약 100 MB를 사용하며 5~10명 규모의 소규모 배포에는 1 GB의 RAM이 적당합니다. 5명 정도의 저트래픽 환경은 단일 CPU 코어에서도 동작합니다. 기본 동시 연결 제한은 모든 서비스를 통틀어 8,192개이며 설정 가능하므로, 사용자가 아닌 연결 수와 메일 처리량에 따라 필요한 자원이 증가합니다. 최소 디스크 크기에 대한 명시적 기준은 없으므로 보관할 메일 용량에 맞춰 디스크를 할당하십시오.

Stalwart로 전환하면 이메일 도달률이 향상됩니까?

아니요. 도달률은 VPS의 아웃바운드 TCP 포트 25가 열려 있는지, IP에 대한 역방향 DNS(reverse DNS)가 설정되어 있는지, 그리고 도메인의 SPF, DKIM, DMARC 설정에 의해 결정됩니다. Stalwart는 DANE, MTA-STS, SMTP TLS 리포팅을 지원하며 MTA-STS 정책을 대신 게시해 줄 수 있지만, 이는 전송 보안을 위한 것이지 수신 측 네트워크가 귀하의 주소를 신뢰할지 여부를 결정하는 것은 아닙니다. 설치 전에 nc -vz -w 5 alt1.aspmx.l.google.com 25을 사용하여 포트 25를 먼저 테스트하십시오.

Stalwart에 웹메일이 포함되어 있습니까?

2026년 8월 28일 기준으로 포함되어 있지 않습니다. 웹 관리자 인터페이스는 제공되지만 이는 웹메일과는 다른 기능입니다. 2025년 6월 20일 자 프로젝트 로드맵 게시물에 따르면, Rust와 Dioxus로 구축된 웹메일 클라이언트가 버전 1.0 이후인 "2026년 중 언젠가"에 계획되어 있으나, 프로젝트 블로그에 아직 관련 공지는 없습니다. 사용자가 당장 브라우저 기반의 메일함을 필요로 한다면 Roundcube를 함께 배포하거나 SOGo가 포함된 스택을 사용하십시오.

Stalwart의 저장 데이터 암호화(encryption at rest)는 무엇을 보호합니까?

사용자의 메시지를 디스크에 쓰기 전에 각 사용자의 OpenPGP 또는 S/MIME 공개 키로 암호화하므로, 디스크나 백업이 탈취되거나 관리자가 저장소를 읽더라도 내용을 복구할 수 없습니다. 이는 종단 간 암호화(end to end encryption)가 아닙니다. 메시지는 평문으로 도착하여 전달 시점에 암호화되므로, 그 이전의 모든 전송 경로에서는 메시지를 볼 수 있습니다. encryptOnAppend은 기본적으로 false로 설정되어 있으므로, 설정을 변경하지 않으면 클라이언트가 작성한 보낸 편지함과 임시 보관함의 메시지는 암호화되지 않습니다. 문서는 메시지 내용에 대해서만 다루고 있으며 메타데이터, 인덱스 항목, 키 업로드 이전에 저장된 메일의 재암호화에 대해서는 언급하지 않으므로, 가정하지 말고 직접 확인하십시오.

#stalwart#email#self-hosting#mail-server#smtp