インフラ・DevOps
メールサーバーをセルフホストする
Self-host your mail server (blog.haschek.at)
要約
この記事では、2026年現在でもメールサーバーを自宅やVPSでセルフホストすることが可能であることを示しています。メールは本来オープンなシステムであり、少数の大企業に依存しないために、セルフホスティングは有効な選択肢です。LLM(大規模言語モデル)をローカルで実行し、スパム対策に活用することで、従来の課題を克服できます。
全文翻訳
もしあなたがセルフホスティングやデータ主権のコミュニティに数日費やしたことがあるなら、必ず一つのアドバイスが飛び交うでしょう。「何でもセルフホストできるが、メールサーバーは別だ!」彼らがどこから来ているのかは理解できます。なぜなら、ブロックリストや配信問題に関する恐ろしい話があるからです。しかし今日、私は2026年現在でもそれが実際に可能であり、自宅からでもホストできるかもしれないことを示したいと思います!設計上、メールはオープンなシステムであり、少数の大企業が私たちのメールをすべて持ち、インターネットがその過程で分散性を失うことを受け入れるべきではありません。私の小さなMSP企業は、毎日人々や企業がGmailやMicrosoftからクラウド代替またはセルフホストソリューションに移行するのを支援しているので、私は自分の言葉に責任を持つべきだと考え、Google Workspaceから離れることにしました。
自宅かVPSか?メールサーバーをセルフホストすることをいとわないセルフホスターの小さなサブセットは、自宅でメールサーバーをホストすることを敢えてする人々と、VPSのみを使用する人々の間で再び分かれています。通常、私はVPSの使用を提案しますが、あなたの自宅のインターネットがこれらの条件を満たしているなら、自宅で独自のメールサーバーを100%ホストできます。
* 静的なIPv4アドレス(ブラックリストに載っていないことを確認してください)
* CGNATの背後にない
* IPのPTRレコードを変更できること(通常はISPのサポートを通じて)
* 一般的なメールサーバーポート(25、143、465、587、993)を開けること
これらすべてをチェックしたなら、自宅でホストする準備はできています!しかし、インターネットの停止についてはどうでしょうか?私のモデムがダウンしたら、受信メールを失うのではないか、右?それはあなたの停止期間によりますが、通常は違います!メールは非常に堅牢です。メールサーバーがダウンした場合、送信者はメールを再配信しようとします。なぜなら、初期のインターネットでは、停止は豊富にあったからです。1日のうち40%未満インターネットがダウンしている場合でも、問題なく動作します。
どのメールサーバーソフトウェアを使用すべきか?これは本当にあなたのニーズによります。ホストする方法が異なる、複数のメールサーバーソリューションがあります。良い出発点は、docker-mailserverでしょう。これは、妥当なデフォルトでDocker経由でデプロイできる完全なメールサーバースイートです。しかし、他にも次のようなソリューションがあります。
* Stalwart
* Mailcow
あるいは、あなたが純粋主義者なら、サーバー全体を自分でセットアップすることもできます。個人的には、私のメールはISPConfigサーバーにあり、レガシーな理由で長年維持してきました。もし今日メールサーバーを一からセットアップするなら、docker-mailserverを選びます。
私のドメインについてはどうでしょうか?IPアドレスと同様に、ドメインがどのスパムリストにも載っていないか確認する必要がありますが、配信トラブルを避けるためにいくつかのDNSレコードも必要です。メールサーバーソフトウェアがおそらくそれらのすべてを案内してくれるでしょうが、完全を期すために、これらのレコードが必要になります。
* SPF - Sender Policy Frameworkは、どのサーバーがあなたのドメインから送信できるかを定義します。通常、v=spf1 mx a ~all のようなもので十分です。
* DKIM - これは、メールサーバーが送信されるすべてのメールのヘッダーに追加する暗号化署名です。あなたのドメインには特定のレコードが必要ですが、名前と値はメールサーバーから伝えられます。通常は次のような見た目です:v=DKIM1; t=s; h=sha256; p=MIGf[..]B;
* DMARC - このレコードは、基本的にSPFとDKIMの拡張であり、あなたのドメインのメールなりすましを防ぐはずです。ここに何を入れるべきか不明な場合は、DMARCジェネレーターを使用してください。
* MX - MXレコードは、他のメールサーバーにあなたのドメインのどこにメールを配信するかを伝えます。通常、IPアドレスを指すmail.yourdomain.comのAレコードを作成し、MXレコードには優先度10、そして値としてmail.yourdomain.comを入れます。
また、前述のように、メールサーバーに使用するIPアドレスには、ISPまたはVPSプロバイダーのみが設定できるPTRレコードが必要です。これにより、サーバーのIPがドメインに解決できるようになります(通常は逆ですが)、そしてそれはメールサーバーに使用するホスト名を示す必要があります。例:mail.yourdomain.com。
一部のメールサーバーは、自動サービス検出のためにいくつかの追加レコードを追加することを推奨していますが、これらが開始に必要なコア設定です。ドメインとサーバーをセットアップしたら、https://www.mail-tester.com/ でメール配信をテストすることを強くお勧めします。これは、すべてのレコードが正しいか、サーバーが期待どおりに動作しているかを確認します。そのツールは何度も私を助けてくれました。
スパムについてはどうでしょうか?ここに楽しい部分があります!スパムはかつてセルフホスト型メールサーバーの最大の課題でした。それはひどかったので、セルフホスト型、あるいは(外部で)ホストされたウェブメールから離れる最大の理由だったと言えます。オープンソースのアンチスパムソリューションは、IPブラックリスト、ドメインリスト、spamhausのような外部アンチスパムサービス、またはキーワード検索に依存していましたが、これらはすべて非常に効果が低く、毎日あなたの受信トレイがこのようになっている原因でした。
噂では、スパムを避けたいなら、Gmailや、毎日何百万ものクライアントのメールを処理してスパムメールを検出できる他の大手クラウドプロバイダーを使用する必要があると言われていました。しかし、過去2年間で、セルフホスターのスパム問題を解決し、毎日スパムに氾濫することなく、再び独自のメールサーバーをホストできるようにした何かが変わりました。
ローカルLLMを使用してスパムと戦う
私が選んだセルフホスト型アンチスパムサービスはrspamdです。ブラックリスト、IPチェック、DNSチェック、キーワード検索など、他のアンチスパムシステムと同様に開始しますが、私のスパム問題を完全に解決した特定のプラグインがあります:GPTプラグイン。
この小さなプラグインは、大規模言語モデルを使用してメールを分類し、メールがスパムかどうかを判断できます。LLMがスパムメールを分類するのを一日中見ていられました。私たちはセルフホスターであり、プライバシーのためにもこれを行っているので、私たちのプライベートメールすべてを分析するために外部LLM APIを使用するのは意味がありません。ここでローカルモデルが登場します。
私がメール分類に選んだモデルはGemma 4 12B QATです。これはGPUまたはCPUで、わずか7GBのRAMまたはVRAMで実行でき、このプロジェクトに完全に適合する非常に有能な多言語モデルです。ローカルLLMをセットアップしたことがない場合は、Windows、Linux、Macで動作するunslothのこのガイドをお勧めします。しかし、要するに、LinuxまたはMacOSではcurl -LsSf https://llama.app/install.sh | shを実行するか、Windowsではwinget install llama.cppを実行するだけです。インストールしたら、llama serve -hf unsloth/gemma-4-12B-it-qat-GGUF:UD-Q4_K_XL --reasoning off -fa on -c 16000 --temp 0.7 を使用してLLMを世界に公開し、ブラウザを開いてhttp://localhost:8080にアクセスすると、チャットインターフェースが表示されます。あなた自身のローカルAIです!ここでチャットすることもできますが、すべての受信メールを判断するためにrspamdインスタンスに接続します。
それが機能したら、すべての受信メールを判断するためにローカルLLMを使用するようにrspamdに指示するだけです。例えば、これは私のメールサーバー上の/etc/rspamd/local.d/gpt.confです。
allow_ham = true;
allow_passthrough = true;
enabled = true;
type = "openai";
url = "http://192.168.1.5/v1";
model = "unsloth/gemma-4-12B-it-qat-GGUF:UD-Q4_K_XL";
api_key = "this-is-ignored-on-llama.cpp";
max_tokens = 100;
temperature = 0.1;
# if your llm server doesn't have a GPU, you might want to increase the timeout
timeout = 30.0;
# Parse LLM reply as JSON (module expects key "probability", not "spam")
json = true;
prompt = "You are an expert email spam classifier. Analyze the following email headers, subject, and body. Respond with a JSON object containing two keys: 'probability' (a floating point number between 0.0 and 1.0 indicating spam probability) and 'reason' (a short sentence explaining why). Output only the raw JSON object, no markdown code fences.";
# Per-recipient conversation context: keeps a compact digest of recent mail
# (labels, top senders, 512-char summaries) in redis and injects it into the
# LLM prompt once 5+ messages are collected, so classification can use the
# recipient's mail history. Local feature, redis-backed, no external calls.
context {
enabled = true;
level = "user";
# scope digest per recipient mailb