Endpoint 安全最佳实践

本文介绍了保护 Quicknode 区块链 endpoint 的多种策略,包括密钥轮换、使用 .env 文件和后端代理、速率限制、方法白名单、域名白名单、IP 白名单以及 JSON Web Tokens (JWT)。每种策略都有其优缺点,选择合适的策略组合可以有效提高 endpoint 的安全性。

概述

在构建与区块链交互的应用程序时,你的 Quicknode endpoint 充当你访问网络的网关。无论你是构建去中心化应用程序(dApp)、交易机器人还是后端服务,保护你的 endpoint 都至关重要。你可以将你的 endpoint URL 视为敏感的 API 密钥;如果落入坏人手中,可能会被滥用。暴露或未受保护的 endpoint 可能会被恶意行为者利用,从而可能增加你的费用并导致性能问题。在本指南中,你将学习保护你的 endpoint 的各种策略:

策略 简易度/复杂度 有效性 Quicknode 计划
轮换密钥 🟡 中等 🟢 高 所有计划
Dot Env 与后端代理 🟢 简单 ⚪ 中等 不适用
速率限制 🟢 简单 ⚪ 中等 所有计划*
方法白名单 🟢 简单 ⚪ 中等 Build 计划及以上
域名白名单 🟡 中等 ⚪ 中等 Build 计划及以上
IP 白名单 🟢 简单 🟢 高 Build 计划及以上
JSON Web Tokens (JWT) 🔴 复杂 🟢 高 Build 计划及以上

*所有计划都提供基础速率限制。按方法进行速率限制需要 Accelerate 计划或更高版本。有关更多详细信息,请参阅定价页面。

专家提示:使用控制台 API 自动化

管理多个 endpoint?你无需为每个安全设置点击仪表板。使用控制台 API 自动化你的安全设置。查看 使用 Quicknode 控制台 API 管理你的 RPC 基础设施 指南以获取演练。

轮换密钥

轮换密钥是保护你的 endpoint 的一种简单而有效的方法。它涉及定期轮换你的 endpoint 的私有 token,以防止未经授权的访问。这意味着即使你的 endpoint 被暴露,它也只会受到有限时间的攻击。Quicknode 允许你直接从 Quicknode 仪表板轮换你的密钥。

打开你的 Quicknode 仪表板 并选择你要轮换密钥的 endpoint。单击安全选项卡,然后在身份验证选项卡中找到Tokens部分。在这里,你可以添加或删除新密钥。新密钥将立即可用。只需复制新密钥并在你的应用程序中使用它即可。你可以通过单击要删除的密钥旁边的 🗑️ 按钮来删除旧密钥。任何先前泄露的已删除密钥都将不再有效。

Quicknode 仪表板 - 基于 Token 的身份验证 - 轮换密钥

定期轮换你的密钥可以显着降低未经授权访问你的 endpoint 的风险。有关如何轮换密钥的更多信息,请查看我们的指南:如何在 Quicknode 上设置多 Token 身份验证

轮换密钥的优点和缺点

  • 优点:简单、安全
  • 缺点:耗时(需要定期轮换密钥)、密钥管理

Dot Env 和后端代理

Dot Env

Dot Env (.env) 是一种简单而有效的方法,用于管理应用程序中的环境变量。它涉及使用 .env 文件来存储配置设置和敏感信息,例如 API 密钥和数据库密码。这种方法集中了配置管理,使其更易于更新和维护。Dot Env 有几个优点:

  1. 安全性:将敏感数据保存在代码库之外,从而降低了在版本控制系统中暴露它的风险。
  2. 灵活性:允许为不同的环境(例如,开发、测试、生产)使用不同的配置,而无需更改代码。
  3. 易用性:简化了管理特定于环境的变量。

后端代理

虽然 .env 组织了你的密钥,但如果你正在构建客户端应用程序(如 React 或 Vue dApp),它不会隐藏它们。如果你将 .env 变量捆绑到前端构建中,则任何检查你网站代码的人都可以看到它们。

后端代理解决了这个问题。你的前端不是直接与 Quicknode 通信,而是与你自己的服务器(代理)通信。然后,你的服务器附加 API 密钥并将请求转发到 Quicknode。它可以处理需要敏感数据的请求,例如你的 endpoint,而无需将它们暴露给客户端。

这是一个后端代理发出 Solana getBalance 请求的示例:

backendProxy.js

const dotenv = require('dotenv');
const express = require('express');
const solanaWeb3 = require('@solana/web3.js');
const PRIVATE_ENDPOINT = process.env.PRIVATE_ENDPOINT;

dotenv.config();
const app = express();

app.get('/getBalance', async (req, res) => {
  const connection = new solanaWeb3.Connection(
    PRIVATE_ENDPOINT,
    'confirmed',
  );
  const publicKey = new solanaWeb3.PublicKey(req.query.publicKey)
  const balance = await connection.getBalance(publicKey);
  res.send(balance);
});

app.listen(3000, () => {
    console.log('Server is running on port 3000');
});

这种方法有几个优点:

  1. 安全数据处理:后端代理可以安全地处理请求并管理敏感数据(如 API 密钥),而无需将它们暴露给客户端。
  2. 环境变量:将敏感数据存储在服务器上的 .env 中,并使用后端代理来调解与外部服务的交互。
  3. 降低暴露风险:这种方法显着降低了敏感信息暴露的风险,因为数据永远不会到达前端。

最佳实践

  • 在服务器端使用 Dot Env:将敏感变量存储在 .env 服务器文件中,而不是客户端代码中。
  • 不要提交 .env 文件:确保 .env 文件未提交到公共存储库(使用 .gitignore)。
  • 实施后端代理:使用后端代理来处理需要敏感数据的请求,确保此数据不会在客户端应用程序中暴露。

通过将 Dot Env 与后端代理相结合,你可以保持环境变量管理的简易性和安全性,同时防范客户端暴露的风险。

Dot Env 和后端代理的优点和缺点

  • 优点:适应性强、可扩展、安全
  • 缺点:代码库复杂性(额外的服务器端代码)以及性能开销

速率限制

速率限制对于 endpoint 安全至关重要,尤其是在 Web 应用程序和 API 中。它涉及设置你的 endpoint 在给定的时间范围内可以处理的最大请求数。虽然这不能阻止其他人访问你的 endpoint,但它会限制他们可以发出的请求数。这有助于防止滥用和过度使用资源,从而可能导致性能问题和成本增加。

设置速率限制

Quicknode 允许你直接从 Quicknode 仪表板为任何 endpoint 设置速率限制。转到你的 Quicknode 仪表板 并选择你要应用速率限制的 endpoint。在安全选项卡下,单击速率限制选项卡。在这里,你可以对你的 endpoint 应用有关每秒、每分钟、每天或每月的请求数的限制。此外,你可以限制每个 IP 地址的请求数,这有助于防止来自单个 IP 地址的滥用。

Quicknode 仪表板 - 速率限制

选择你要应用的速率限制类型,输入限制,然后单击添加。你的速率限制将立即应用。

方法速率限制

Quicknode 还提供特定于方法的速率限制。这些限制可以在仪表板上的同一 endpoint 安全页面上找到。方法速率限制允许你为不同的 API 方法设置不同的限制,从而提供对你的 endpoint 使用情况更精细的控制。

Quicknode 仪表板 - 方法速率限制

速率限制的优点和缺点

  • 优点:易于实施/修改
  • 缺点:如果限制太低,可能会影响用户体验,无法阻止对 endpoint 的访问

方法白名单

一种非常有效的安全策略是限制你的 endpoint 可以接受哪些 JSON-RPC 方法。通过创建方法白名单,你可以确保仅处理你的 dApp 需要的特定功能。任何其他方法调用都将被禁止。

例如,如果你的应用程序只需要使用 getBlockgetBalance 从区块链读取数据,则可以仅启用这两种方法。这将阻止处理任何其他方法调用,从而降低未经授权的访问以及滥用你的 endpoint 的风险。

启用方法白名单

转到你的 Quicknode 仪表板 并选择你要应用方法限制的 endpoint。在安全选项卡下,单击白名单选项卡,然后找到方法部分。在这里,你可以将方法添加到你的白名单。从下拉列表中选择方法,然后单击添加。你的白名单将立即应用。你可以轻松地修改列表或在需要时禁用限制。

Quicknode 仪表板 - 方法限制

保存方法限制后,你可以通过向未列入白名单的方法发出请求来测试你的 endpoint。你应该收到表明该方法不被允许的错误响应。

例如,此请求:

curl https://your-endpoint.solana-mainnet.quiknode.pro/123/ \
  -X POST  \
  -H "Content-Type: application/json"  \
  --data '{"jsonrpc":"2.0","id":1, "method":"getSlot"}'

应返回:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32611,
    "message": "rejected due to request filter settings"
  }
}

域名白名单

域名白名单(也称为引用站点白名单)根据发出请求的网站来限制访问。这是专门为基于浏览器的应用程序设计的,其中请求包括指示原始网站的引用站点。Quicknode 允许你直接从 Quicknode 仪表板为任何 endpoint 列入多个引用站点白名单。

通过将 myapp.com 列入白名单,你可以确保你的 endpoint 在从你的网站调用时有效,但如果有人尝试从其他网站使用它,则会失败。

请注意,域名白名单不是完全安全的。虽然它阻止了未经授权的网站使用你的密钥,但攻击者可以使用脚本轻松地伪造他们的域名来绕过此限制。将其用作基本保护层,但不要将其作为你唯一的安全措施。

将域名列入白名单

转到你的 Quicknode 仪表板 并选择你要应用白名单的 endpoint。在安全选项卡下,单击白名单选项卡,然后找到引用站点部分。在这里,你可以将域名(不带 http://https:// 前缀)添加到你的白名单。输入你要列入白名单的域名,然后单击添加。你的白名单将立即应用。你可以通过单击要删除的域名旁边的 🗑️ 按钮来轻松删除列入白名单的域名。

注意:如果你的应用程序通过 WebSockets (WSS) 连接,则不能使用域名白名单。

Quicknode 仪表板 - 域名白名单

保存后,你可以通过使用 cURL 脚本或从未列入白名单的域名向你的 endpoint 发出请求来测试你的白名单。你应该收到 UNAUTHORIZED 响应。

例如,此请求:

curl https://your-endpoint.solana-mainnet.quiknode.pro/123/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","id":1, "method":"getBlock"}'

现在应返回:

{
    "error":"UNAUTHORIZED",
    "instance":"your-endpoint",
    "request-id":""
}

域名白名单的优点和缺点

  • 优点:易于实施/修改
  • 缺点:有效性有限

有关如何将域名列入白名单的更多信息,请查看我们的指南:如何使用 Quicknode 设置引用站点白名单

IP 白名单

IP 白名单是可用的最强大的安全控制之一,尤其适用于后端基础设施。它将 endpoint 访问限制为特定的 IP 地址。启用后,仅接受来自列入白名单的 IP 的请求,而所有其他请求将被拒绝。你最多可以将 25 个 IP 地址添加到你的白名单。

如果你正在运行后端代理(如上所述)、交易机器人或服务器端索引器,则你的服务器可能具有静态 IP 地址。通过将此 IP 列入白名单,即使攻击者窃取了密钥,他们也无法使用它,因为他们没有从列入白名单的 IP 发送请求。

IP 白名单不适用于用户从浏览器访问你的 dApp 的前端应用程序。最终用户具有经常更改的动态 IP 地址(家庭网络、移动设备、VPN),这使得不可能将所有潜在用户 IP 列入白名单。

将 IP 列入白名单

转到你的 Quicknode 仪表板 并选择你要应用白名单的 endpoint。在安全选项卡下,单击白名单选项卡,然后找到源 IP 部分。在这里,你可以启用 IP 白名单并将 IP 地址添加到你的白名单。输入你要列入白名单的 IP 地址,然后单击添加。你的白名单将立即应用。你可以通过单击要删除的 IP 旁边的 🗑️ 按钮来轻松删除列入白名单的 IP。

Quicknode 仪表板 - IP 白名单

保存后,来自未在白名单上的 IP 地址的任何请求都将被拒绝访问你的 endpoint。

例如,此请求:

curl https://your-endpoint.solana-mainnet.quiknode.pro/123/ \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","id":1, "method":"getBlock"}'

现在应返回:

{
  "error": "UNAUTHORIZED",
  "instance":"your-endpoint",
  "request-id": ""
}

IP 白名单的优点和缺点

  • 优点:非常有效、易于配置、强大的访问控制
  • 缺点:仅适用于静态 IP 环境、不适用于面向最终用户的应用程序、需要随 IP 更改而更新

JSON Web Tokens (JWT)

JSON Web Tokens (JWT) 是一种流行的 API 安全方法。它们是一种开放标准 (RFC 7519),定义了一种紧凑且自包含的方式,用于在各方之间安全地将信息作为 JSON 对象传输。可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对对 JWT 进行签名。JWT 通常用于 Web 应用程序和 API 中的身份验证和信息交换。

JWT 通过验证 token 中包含的信息的完整性来防止未经授权的访问。这是通过使用密钥或公钥/私钥对对持续时间有限的 token 进行签名来实现的。收到的没有 token 或 token 无效(因为已过期或未使用正确的密钥签名)的请求将被拒绝。

实施 JWT

这是一个如何在你的应用程序中实施 JWT 的简单示例(有关更详细的演练,请查看我们的指南:如何使用 Quicknode 实施 JWT 授权):

  1. 密钥生成:使用 RSA 或 ECDSA 生成公钥/私钥对。示例:
const { generateKeyPairSync } = require('crypto');
var jwt = require('jsonwebtoken');

// Generate RSA keys
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
        type: 'spki',
        format: 'pem'
    },
    privateKeyEncoding: {
        type: 'pkcs8',
        format: 'pem',
    }
});
  1. 定义密钥:将你的公钥添加到你的 Quicknode 仪表板(安全选项卡,身份验证部分)。
  2. Token 生成:使用你的私钥生成持续时间有限的 JWT(例如,60 秒用于处理交易请求)。示例:
const app = express();
const jwt = require("jsonwebtoken");

app.get('/get_token', (req, res) => { // endpoint to retrieve JWT
  const privateKey = process.env.PRIVATE_KEY;
  var token = jwt.sign({}, privateKey, {
    algorithm: 'RS256', // RSA signature with SHA-256
    expiresIn: "60000"  // 60 seconds
  });
  return res.json({ token: token }); // return an object containing the signed JWT
});
  1. 使用 Token:在对你的 Quicknode endpoint 的请求中包含 JWT。示例:
import { createSolanaRpcFromTransport, createDefaultRpcTransport } from '@solana/kit';

async function makeRequest() {
    const response = await fetch('/get_token'); // fetch JWT from your token service
    const { token } = await response.json();

    // Create a transport with the Authorization header
    const transport = createDefaultRpcTransport({
        url: 'https://example.solana-devnet.quiknode.pro/12345/',
        headers: {
            Authorization: `Bearer ${token}`
        }
    });

    // Create the RPC client using the transport
    const rpc = createSolanaRpcFromTransport(transport);

    // Make RPC calls
    const slot = await rpc.getSlot().send();
    // do something with the slot
}

makeRequest();
  1. Token 验证:当我们收到请求时,我们可以使用你添加到 Quicknode 仪表板的公钥来验证 token。这将确保 token 有效且未被篡改。

最佳实践

  • 密钥管理:安全地管理并定期轮换加密密钥。
  • Token 过期:设置适当的 token 过期时间以降低 token 滥用的风险。

JSON Web Tokens (JWT)

  • 优点:安全、可扩展、适应性强
  • 缺点:代码库复杂性(额外的服务器端代码和密钥管理)

总结

实践良好的 endpoint 安全对于保护你的 endpoint 免受未经授权的访问和滥用至关重要。通过实施本指南中概述的策略(无论你是构建前端 dApp 还是后端服务),你可以显着降低未经授权访问你的 endpoint 的风险。

如果你遇到问题或有疑问,请在我们的 Discord 中提出。请在 X (@Quicknode) 或我们的 Telegram 公告频道 上关注我们,以获取最新信息。

我们 ❤️ 反馈!

如果你有任何反馈或对新主题的要求,请告诉我们。我们很乐意听取你的意见。

资源

  • 原文链接: quicknode.com/guides/qui...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。