打开 WireGuard 端点
Open WireGuard Endpoints

原始链接: https://proxylity.com/articles/now-available-open-wireguard-endpoints-and-async-lambda.html

UDP Gateway 引入了两项新功能,旨在简化面向公众的事件驱动型 WireGuard 服务的部署。 首先,**AllowUnknownPeers** 属性使 WireGuard 监听器能够接受来自任何客户端的连接,而无需预先注册。这模仿了 HTTPS 模型,即在应用层验证身份之前先建立加密。为提高安全性,管理员可以使用 **UnknownPeerPreSharedKey** 属性,要求所有未知客户端提供共享凭据。 其次,**UseAsyncInvoke** 参数允许异步触发 Lambda 目标。网关无需等待同步响应,而是直接发送数据包批次并立即释放连接。这非常适合触发持久且耗时较长的工作流(如设备配置或多步验证),这些工作流的生命周期超出了单个数据包的持续时间。 这些功能既可以独立使用,也可以组合使用,以构建无需手动密钥管理或持久化基础设施的可扩展服务。这两项功能现已在所有受支持的区域中可用,并完全保持与现有配置的向后兼容性。

Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Open WireGuard Endpoints (proxylity.com) 6 分,由 mlhpdx 发布于 58 分钟前 | 隐藏 | 过往 | 收藏 | 讨论 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 加入 YC | 联系 搜索:
相关文章

原文

By Lee Harding | June 3, 2026 | 7 min read

Diagram showing open WireGuard endpoint accepting any peer and async Lambda workflow

Two new capabilities are available in UDP Gateway today. The first allows WireGuard Listeners to accept connections from any client without pre-registration — the same model HTTPS uses for websites. The second allows Lambda destinations to be invoked asynchronously, firing a packet into a long-running workflow without the Gateway waiting for a response. Together they open up a class of public-facing, event-driven WireGuard services that previously required significant custom infrastructure to build.

WireGuard Open Endpoints

WireGuard Listeners have always required every connecting client to be pre-registered: you list each peer's public key in your CloudFormation template, and the Listener rejects any handshake from an unknown key. That model fits private services with a managed set of devices. But it creates a problem for anything that needs to be accessible by a large or unknown set of clients.

Consider a mobile app that generates a WireGuard keypair on first launch. Or a fleet of devices provisioned on demand where central key management is operationally impractical. Or any public-facing service where clients you've never seen before need to connect. With the previous model, every one of those clients required an out-of-band registration step and a CloudFormation update before it could complete a handshake. That's not a model that scales to public services.

The new AllowUnknownPeers property removes that restriction. Set it to true on a WireGuard Listener and the Gateway will complete the handshake with any valid WireGuard client, regardless of whether its public key is listed. The connection is still fully encrypted — WireGuard's cryptographic properties don't change. The difference is simply that the Listener no longer requires the key to be known in advance.

The analogy to HTTPS is intentional. When you visit a website over HTTPS, the server doesn't need to know who you are before establishing an encrypted connection. The TLS handshake completes, the channel is encrypted, and authentication (if it happens at all) is a separate concern at the application layer. Open WireGuard endpoints work the same way: the transport is encrypted, and identity can be handled by your Lambda or Step Functions destination however your application requires.

Adding a shared credential gate

Fully open enrollment — accepting literally any WireGuard client — is appropriate for some services. For others, you want the encryption and the open handshake, but you also want to prevent connections from clients that weren't issued credentials. The UnknownPeerPreSharedKey property provides a lightweight gate for exactly this case.

When UnknownPeerPreSharedKey is set, unknown peers must include that PSK in their WireGuard configuration or the handshake fails. It's not per-device authentication — every client uses the same secret — but it meaningfully restricts access to clients that were issued the PSK. Think of it like a shared API key for transport-layer access: not strong identity, but a real barrier against arbitrary connections from clients who were never given credentials.

Distributing the PSK to clients is your application's responsibility. Store it in AWS Secrets Manager and reference it from your CloudFormation stack on the infrastructure side; provision it to devices during manufacturing or enrollment on the client side.

WireGuardListener:
  Type: Custom::ProxylityUdpGatewayListener
  Properties:
    ServiceToken: !FindInMap [ProxylityConfig, !Ref "AWS::Region", ServiceToken]
    ApiKey: !FindInMap [ProxylityConfig, Account, ApiKey]
    Protocols:
      - wg
    AllowUnknownPeers: true
    UnknownPeerPreSharedKey: !Sub "{{resolve:secretsmanager:${WireGuardPSK}:SecretString}}"
    Destinations:
      - Name: packet-handler
        DestinationArn: !GetAtt HandlerLambda.Arn
        Role:
          Arn: !GetAtt ProxylityRole.Arn

Named peers (listed in the Peers array) are unaffected by AllowUnknownPeers and UnknownPeerPreSharedKey. They use their own per-peer SharedSecret as before. The two models can coexist on a single Listener: a fixed set of known devices with per-device PSKs, and an open slot for dynamic clients behind a shared credential.

Lambda Async Invocation

Lambda destinations in UDP Gateway have always used synchronous RequestResponse invocation: the Gateway delivers a batch of packets, waits for the function to complete, and uses the function's return value to send reply packets back to clients. That model is the default to align with how UDP request/response patterns work.

But synchronous invocation becomes limiting for workloads where a function's job is to kick off processing that outlives a single invocation. Lambda durable functions address exactly this: using a checkpoint-and-replay mechanism, a durable function can execute for up to one year, automatically resuming after failures without losing progress. The Event invocation type is the right delivery model here — the Gateway fires the packet batch and moves on while the durable execution continues independently.

The new UseAsyncInvoke argument changes the invocation type to Lambda's Event mode. The Gateway delivers the packet batch and immediately receives an HTTP 202 Accepted without waiting for the function to complete. No reply is sent to the UDP client. The function runs to completion independently of the Gateway's request lifecycle.

The primary use case is triggering durable workloads. A function invoked with UseAsyncInvoke receives the inbound packet batch, starts a durable execution (or dispatches to Step Functions if you prefer that orchestration model), and returns immediately. The remote client sent a UDP packet; a long-running, fault-tolerant workflow is now running on its behalf, with checkpointed progress and automatic recovery from failures — none of which requires the Gateway to hold a connection open.

Destinations:
  - Name: workflow-trigger
    DestinationArn: !GetAtt WorkflowTriggerLambda.Arn
    Role:
      Arn: !GetAtt ProxylityRole.Arn
    Arguments:
      UseAsyncInvoke: "true"

A few things to keep in mind when using async invocation:

  • No replies: The function's return value is discarded. If a packet needs a reply, async invocation is the wrong tool — use standard synchronous invocation or response streaming instead.
  • AWS retries on failure: Lambda will automatically retry a failed async invocation up to twice. Make sure your function (and any downstream workflow it starts) is idempotent, or configure a dead-letter queue to capture failures without silent data loss.
  • Mutual exclusion with streaming: UseAsyncInvoke and UseResponseStreaming cannot both be true on the same destination — they represent opposite delivery models.

Putting them together

These two features are independent, but they combine naturally for a specific pattern: a public WireGuard endpoint that triggers a long-running backend workflow.

Imagine a device provisioning service. Devices are manufactured without pre-registered keys — they generate a keypair on first boot, connect to the open WireGuard Listener using the shared PSK, and send a provisioning request packet. A Lambda function receives the packet, starts a Step Functions state machine that handles the full provisioning workflow — identity registration, certificate issuance, DynamoDB record creation, SNS notification — and returns. The state machine runs for minutes or hours. The device receives no immediate reply; provisioning confirmation comes through a separate channel once the workflow completes.

None of that requires managing a key registry before devices ship. None of it requires the Gateway to hold a connection open for the duration of provisioning. It's a packet in, a workflow started, and no infrastructure running between events.

The same pattern applies to any inbound-triggered workflow where the sender doesn't need an immediate response, such as device commands that kick off multi-step validation before execution, and audit events that need durable processing guarantees across multiple systems.

Getting started

Both features are available now across all regions where UDP Gateway is supported. Neither requires changes to existing Listeners or destinations — AllowUnknownPeers defaults to false and existing peer-list behavior is unchanged, and Lambda destinations continue to use synchronous invocation unless UseAsyncInvoke is explicitly set.

For complete configuration details, see the WireGuard Listeners documentation and the Lambda destination documentation. The full CloudFormation property reference for AllowUnknownPeers and UnknownPeerPreSharedKey covers all options including mixing named and unknown peers on the same Listener.

联系我们 contact @ memedata.com