Sanctum || 一个安全可靠且沙箱化的 VPN 守护进程
Sanctum || A pq-safe and sandboxed VPN daemon

原始链接: https://github.com/jorisvink/sanctum

Sanctum是一个安全、权限隔离的VPN守护进程,适用于OpenBSD、Linux和macOS,它优先考虑安全性,采用进程沙箱和密钥分离技术。它使用多个进程进行加密、解密和流量管理,保证数据完整性。Sanctum通过混合密钥交换(ECDH & ML-KEM-1024)和使用AES256-GCM加密的ESP封装来实现后量子安全性。 它支持标准隧道和专用模式:“pilgrim”(只发送)和“shrine”(只接收),用于单向流量。“cathedral”模式充当经过身份验证的中继,用于NAT穿越和使用“ambries”的安全密钥分发,防止cathedral访问会话密钥。 Sanctum需要仔细配置,包括为每个进程分配专用用户。它依赖于pkg-config和libsodium,并提供AES-GCM实现或Agelas密码的选项。高级用户可以使用libkyrka将sanctum协议直接集成到应用程序中,但这缺乏守护进程的沙箱保护。

Hacker News 用户们正在盛赞一款名为“Sanctum”的新型 VPN 守护进程,该程序强调安全性和沙箱机制。用户们对代码的设计印象深刻,尤其赞赏其对最小权限原则的遵守。一位评论者认为,如果更多软件都采用这种方式构建,就能减少对网络安全行业的依赖。另一位用户虽然被其复杂性折服,但也表达了钦佩之情。第三位用户将 Sanctum 的设计与 OpenBSD 的 letskencrypt/acme-client 相比,认为它更有优势。总的来说,反响非常积极,一位用户称其为近期看到过的最佳代码之一。

原文

This is a small, reviewable, capable, pq-safe and fully privilege separated VPN daemon for OpenBSD, Linux and MacOS.

Due to its privilege separated design, sanctum guarantees that all of its important assets are separated from the processes that talk to the internet or handle non-cryptography related things.

Additionally when making use of sanctum's cathedrals one can get peer-to-peer tunnels that are able to traverse NAT, allowing your devices to talk to each other directly no matter where they are without having to open pesky firewall ports or fiddle with forward rules.

See The Reliquary for an example on this.

There are several processes that make up a sanctum instance:

Process name Description
bless The process responsible for encrypting packets.
confess The process responsible for decrypting packets.
chapel The process responsible for deriving new TX/RX keys from a key.
heaven-rx The process receiving packets on the inner interface.
heaven-tx The process sending packets on the inner interface.
purgatory-rx The process receiving packets on the outer interface.
purgatory-tx The process sending packets on the outer interface.
pilgrim The process handling TX keys when running in pilgrim mode.
shrine The process handling RX keys when running in shrine mode.
cathedral The process forwarding traffic when running in cathedral mode.
liturgy The process responsible for autodiscovery of peers in a cathedral.
bishop The process responsible for configuring autodiscovered tunnels.
guardian The process monitoring all other processes.

Each process should be run as its own user.

Each process is sandboxed and only has access to the system calls required to perform its task. There are two exceptions: guardian (the main process), and bishop (liturgy manager), neither of these are sandboxed due what they are responsible for.

The guardian process is only monitoring its child processes and has no other external interfaces. The bishop process must be privileged due to the fact it is fork+exec'ing the hymn configuration tool for setting up new tunnels (only if using liturgy mode).

The processes share packets between each other in a very well defined way.

For incoming packets:

purgatory-rx (black) -> confess (decryption) -> heaven-tx (red)

For outgoing packets:

heaven-rx (red) -> bless (encrypt) -> purgatory-tx (black)

When the processes start they will remove any of the queues they do not need for operating.

As an example of why this is important, it is impossible for a packet that arrives on the plaintext interface to be moved to the ciphertext interface without passing the encryption process.

Sanctum is post-quantum safe due to its unique approach to deriving session keys based on a shared symmetrical secret in combination with a hybridized asymmetrical exchange. It combines both classic ECDH (x25519) and the PQ-safe NIST standardized ML-KEM-1024.

See docs/crypto.md for details on the key exchange.

Traffic is encapsulated with ESP in tunnel mode, using incrementing 64-bit sequence numbers. It is encrypted under AES256-GCM using keys negotiated as described above.

A 96-bit nonce is used, constructed as follows:

nonce = 32-bit salt from key exchange || 64-bit packet counter

You can select what cipher sanctum will use by specifying a CIPHER environment variable at compile time with one of the following:

  • libsodium-aes-gcm (AES256-GCM via libsodium) [default]
  • intel-aes-gcm (AES256-GCM via Intel its highly performant libisal_crypto lib).
  • nyfe-agelas (Agelas via nyfe, an AEAD cipher based on Keccak).

Note that no matter which CIPHER is selected libsodium is always a dependency as it is used for x25519.

Sanctum supports one-directional tunnels, this is called the pilgrim and shrine mode.

In pilgrim mode, sanctum will be able to send encrypted traffic to its shrine peer. It will however never send an RX key to its peer (a shrine).

In shrine mode, sanctum will be able to verify and decrypt the arriving traffic but will never receive a TX key from its peer.

This allows one-way traffic to flow from a pilgrim to the shrine with a strong guarantee that the shrine cannot send data back (there are no keys nor are there any processes to do so).

A cathedral is a sanctum mode that can run on a machine somewhere and is an authenticated relay and key distribution point. A cathedral can never read, modify or inject valid traffic as it does not hold any of the session keys.

Peers can use a cathedral to move to a peer-to-peer end-to-end encrypted connection if both peers are behind a not too restrictive NAT.

A cathedral may also be used as an Ambry distribution point for shared secret rollover. These ambry bundles are wrapped with unique per-device KEKs and are unable to be read by the cathedral.

This essentiallys solves the key distribution problem with symmetrical keys by providing you with a way to allow the cathedrals to hand out black keys to devices.

See docs/crypto.md for details on the ambries and docs/cathedral.md for details on a cathedral.

A default build requires pkg-config and libsodium.

$ git clone https://github.com/jorisvink/sanctum
$ cd sanctum
$ make
# make install

If this is to complicated for you, this isn't your software.

Sanctum builds on MacOS 13+, OpenBSD 6.8+ and Linux-y things like Ubuntu 22.04.

Sanctum uses a configuration file. Find an example of a simple configuration below.

# Name of this sanctum instance.
instance laptop

# Uncomment if you want l2 instead of l3.
#tap yes

# Path to the shared secret.
secret /etc/sanctum/laptop_secret.key

# The control socket for pontifex.
run control as joris
control /tmp/sanctum-control joris

# The tunnel configuration
tunnel 1.0.0.1/30 1422

# Add additional routes over the tunnel
route 2.0.0.0/24

# The local address to which sanctum binds.
local x.x.x.x:2333

# Optional peer address, ignore if you have a peer that
# moves networks a lot.
peer y.y.y.y:2333

# The encryption and decryption processes.
run bless as _bless
run confess as _confess

# Run the internal io processes as one user.
run heaven-rx as _heaven
run heaven-tx as _heaven

# Run the external io processes as another.
run purgatory-rx as _purgatory
run purgatory-tx as _purgatory

# Run the bishop as privileged root.
run bishop as root

# Run chapel for the key exchange as yet another user.
run chapel as _chapel

You can use libkyrka to implement the sanctum protocol and tunnels into your application directly. Note that this does not provide the same type of sandboxing as the daemon.

联系我们 contact @ memedata.com