分享免费的编程资源和教程

网站首页 > 技术教程 正文

Kong的代理详解之七——为路由配置TLS

goqiw 2024-10-11 15:08:50 技术教程 20 ℃ 0 评论

Kong提供了一种基于每个连接动态提供TLS证书的方法。TLS证书直接由核心处理,并通过管理API进行配置。通过TLS连接到Kong的客户端必须支持服务器名称指示扩展才能使用此特性。

TLS证书由Kong管理API的两个资源处理:

  • /certificates,存储您的密钥和证书。
  • /snis,它将注册证书与服务器名称指示关联起来。

您可以在Admin API参考资料中找到这两个参考资料的文档。

下面是如何在给定的路径上配置TLS证书:首先,通过Admin API上传您的TLS证书和密钥:

$ curl -i -X POST http://localhost:8001/certificates \
    -F "cert=@/path/to/cert.pem" \
    -F "key=@/path/to/cert.key" \
    -F "snis=*.tls-example.com,other-tls-example.com"
HTTP/1.1 201 Created
...

snis表单参数是一个装饰参数,直接插入一个SNI并将上传的证书关联到它。

注意,上面snis中定义的一个SNI名称包含一个通配符(*.tls-example.com)。SNI可以在最左边(前缀)或最右边(后缀)位置包含一个通配符。这在维护多个子域时非常有用。使用通配符名称配置的单个sni可以用于匹配多个子域,而不是为每个子域创建一个sni。

有效的通配符位置是mydomain.*, *.mydomain.com和*.www.mydomain.com。

在Kong配置中,可以使用以下参数添加默认证书:

  1. ssl_cert
  2. ssl_cert_key

或者通过动态配置SNI为*的默认证书:

$ curl -i -X POST http://localhost:8001/certificates \
    -F "cert=@/path/to/default-cert.pem" \
    -F "key=@/path/to/default-cert.key" \
    -F "snis=*"
HTTP/1.1 201 Created
...

snis的匹配遵循以下优先级:

  1. 确切的SNI匹配证书
  2. 根据前缀通配符搜索证书
  3. 通过后缀通配符搜索证书
  4. 搜索与SNI关联的证书*
  5. 文件系统上的默认证书

您现在必须在Kong内登记下列路由。为了方便起见,我们将只使用主机头来匹配此路由的请求:

$ curl -i -X POST http://localhost:8001/routes \
    -d 'hosts=prefix.tls-example.com,other-tls-example.com' \
    -d 'service.id=d54da06c-d69f-4910-8896-915c63c270cd'
HTTP/1.1 201 Created
...

现在可以预计Kong通过HTTPS提供路线:

$ curl -i https://localhost:8443/ \
  -H "Host: prefix.tls-example.com"
HTTP/1.1 200 OK
...

在建立连接和协商TLS握手时,如果客户端将prefix.tls-example.com作为SNI扩展的一部分发送,Kong将提供之前配置的cert.pem证书。对于HTTPS和TLS连接来说,这是相同的。

限制客户端协议(HTTP/HTTPS, GRPC/GRPCS, TCP/TLS)

路由有一个protocols属性来限制它们应该侦听的客户端协议。这个属性接受一组值,可以是“http”、“https”、“grpc”、“grpcs”、“tcp”或“tls”。

使用http和https的路由将接受这两种协议中的流量:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["http", "https"],
    "service": {
        "id": "..."
    }
}

不指定任何协议也有同样的效果,因为路由默认为["http", "https"]。

然而,仅使用https的路由将只接受https上的流量。如果TLS终止之前发生在一个受信任的IP上,它也会接受未加密的流量。如果请求来自trusted_ips中的一个已配置ip,并且头被设置为:X-Forwarded-Proto: https,终止被认为是有效的:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["https"],
    "service": {
        "id": "..."
    }
}

如果一个像上面这样的路由匹配了一个请求,但该请求是明文的,没有有效的之前的TLS终止,Kong响应:

HTTP/1.1 426 Upgrade Required
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: Upgrade
Upgrade: TLS/1.2, HTTP/1.1
Server: kong/x.y.z

{"message":"Please use HTTPS protocol"}

从Kong 1.0开始,可以在protocols属性中使用“TCP”创建原始的TCP(不一定是HTTP)连接的路由:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["tcp"],
    "service": {
        "id": "..."
    }
}

同样,我们可以创建接受原始TLS流量的路由(不一定是HTTPS),其值为“TLS”:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["tls"],
    "service": {
        "id": "..."
    }
}

只有TLS的路由只接受TLS上的流量。

同时接受TCP和TLS也是可能的:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["tcp", "tls"],
    "service": {
        "id": "..."
    }
}

为了让L4 TLS代理工作,有必要创建接受TLS协议的路由,以及上传适当的TLS证书,并将其sni属性正确设置为传入连接的sni匹配的值。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表