# 启用 TLS

传输层安全性 (TLS) 是一种加密协议，可为 Alluxio 服务提供安全通信。通过启用 TLS，您可以确保在客户端和 Alluxio 之间以及 Alluxio 组件本身之间传输的数据都经过加密并受到保护，免受窃听。

本指南全面介绍了在 Alluxio 中配置 TLS 的过程，从生成证书到部署和验证安全集群。

**注意：** 启用 TLS 会带来计算开销，这可能会影响数据传输性能。

### 证书格式

Alluxio 支持两种标准证书格式：

* **PEM**：现代推荐的格式，与 OpenSSL 兼容，并广泛用于容器化环境。
* **Java 密钥库 (JKS)**：传统的 Java 原生格式。

本指南重点介绍 PEM 格式。有关在格式之间进行转换的说明，请参阅附录。

## 第 1 部分：生成证书

在启用 TLS 之前，您必须有一组证书来验证您的服务。以下步骤使用 `openssl` 创建一个简单的证书颁发机构 (CA) 并为服务器和客户端颁发证书。

### 1. 创建证书颁发机构 (CA)

CA 用于签名和验证集群中的所有证书。

```bash
# 为 CA 生成私钥
openssl genrsa -out ca.key 2048

# 生成自签名 CA 证书
openssl req -x509 -new -nodes -key ca.key -sha256 -days 3650 -out ca.pem \
  -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=rootCA"
```

### 2. 生成服务器证书

每个 Alluxio 服务器（Coordinator、Worker、网关）都需要一个服务器证书。

```bash
# 为服务器生成私钥
openssl genrsa -out server-key.pem 2048

# 为服务器生成证书签名请求（CSR）
# 注意：CN（通用名称）和 subjectAltName（SAN）必须与客户端用于连接的主机名一致。

# Kubernetes 中的一个 worker 示例：
openssl req -new -key server-key.pem -out server.csr \
  -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=serverhost" \
  -addext "subjectAltName = DNS:alluxio-worker.default.svc.cluster.local"

# 使用CA 签发服务器证书
openssl x509 -req -in server.csr -CA ca.pem -CAkey ca.key -CAcreateserial \
  -out server.pem -days 365 -sha256
```

### 3. 生成客户端证书

客户端证书是双向 TLS (mTLS) 所必需的，在这种情况下，服务器也会验证客户端的身份。

```bash
# 为客户端生成私钥
openssl genrsa -out client-key.pem 2048

# 为客户端生成证书签名请求（CSR）
openssl req -new -key client-key.pem -out client.csr \
  -subj "/C=US/ST=State/L=City/O=Organization/OU=OrgUnit/CN=localhost"

# 使用CA 签发客户端证书
openssl x509 -req -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial \
  -out client.pem -days 365 -sha256
```

## 第 2 部分：配置 Alluxio 服务

准备好证书后，您现在可以配置 Alluxio 服务来使用它们。以下属性应该在 `alluxio-site.properties` 中设置。

### 保护内部集群通信

此配置加密 Alluxio Coordiantor和Worker之间的 RPC 流量。

```properties
# 在服务器之间启用 TLS
alluxio.network.tls.enabled=true

# PEM 证书配置
alluxio.network.tls.ca.cert=/path/to/ca.pem
alluxio.network.tls.server.cert=/path/to/server.pem
alluxio.network.tls.server.key=/path/to/server-key.pem

# 注意：启用 TLS 需要将传输类型设置为 MAPPED，这会禁用零拷贝。
alluxio.worker.network.netty.file.transfer=MAPPED
```

### 保护 S3 API

您可以对 worker上的 Alluxio S3 API 端点进行保护。这与内部 RPC 加密是独立配置的。

#### 选项 1：仅 TLS 模式

此模式对所有 S3 API 访问强制使用 HTTPS。

```properties
# 为 S3 API 启用 TLS
alluxio.worker.s3.tls.enabled=true
alluxio.worker.s3.https.port=29996
alluxio.worker.s3.only.https.access=true

# PEM 证书配置
alluxio.network.tls.ca.cert=/path/to/ca.pem
alluxio.network.tls.server.cert=/path/to/server.pem
alluxio.network.tls.server.key=/path/to/server-key.pem

# 出于安全保护禁用零拷贝
alluxio.worker.s3.local.page.transfer.enabled=false
```

#### 选项 2：双端口模式（HTTP 和 HTTPS）

此模式同时允许安全 (HTTPS) 和不安全 (HTTP) 连接。

```properties
# 为 S3 API 启用 TLS，但允许非 TLS 访问
alluxio.worker.s3.tls.enabled=true
alluxio.worker.s3.https.port=29996
alluxio.worker.s3.only.https.access=false
# 指定非 TLS 端口
alluxio.worker.rest.port=29998

# （按照选项 1 所示添加 PEM 证书配置）
```

#### 选项 3：双向 TLS (mTLS)

为了获得最大安全性，启用 mTLS 以要求客户端提供有效证书。

```properties
# 将此属性添加到现有的 S3 TLS 配置中 
alluxio.worker.s3.tls.mutual.enabled=true
```

### 保护网关

Alluxio 网关提供管理 API，可以配置为支持 TLS 连接。当网关暴露给外部网络时，这一点尤为重要。

**注意：** 网关 TLS 设置通常在 Kubernetes 部署的 `alluxio-cluster.yaml` 中配置。

#### 选项 1：仅 TLS 模式

此模式对所有网关 API 访问强制使用 HTTPS。

```yaml
# 在 alluxio-cluster.yaml 中
spec:
  gateway:
    tls:
      enabled: true
      secretName: "my-pem-secret"
      certFile: server.pem
      certKeyFile: server-key.pem
      caFile: ca.pem
      mtlsEnabled: true
    service:
      ports:
        api: 8443 # 仅使用 TLS 端口 
```

#### 选项 2：双端口模式（HTTP 和 HTTPS）

此模式同时允许安全 (HTTPS) 和不安全 (HTTP) 连接。

```yaml
#  在 alluxio-cluster.yaml 中
spec:
  gateway:
    tls:
      enabled: true
      secretName: "my-pem-secret"
      certFile: server.pem
      certKeyFile: server-key.pem
      caFile: ca.pem
      mtlsEnabled: true
    service:
      ports:
        api: 80      # 非 TLS 端口
        tlsApi: 8443 # TLS 端口
```

### 配置 Alluxio 客户端

连接到启用 TLS 的 Alluxio 集群的客户端必须配置为信任服务器的 CA。

```properties
# 为客户端启用 TLS
alluxio.network.tls.enabled=true

# 提供客户端信任的 CA 证书
alluxio.network.tls.ca.cert=/path/to/ca.pem

# 可选：如有需要可禁用主机名验证（例如，用于测试）
alluxio.network.tls.client.no.endpoint.identification=true
```

### 保护 ETCD 通信

如果您使用外部 ETCD 集群进行服务发现，可以对与其的连接进行安全保护。

```properties
alluxio.etcd.endpoints=https://<etcd-server>:2379
alluxio.etcd.tls.enabled=true
alluxio.etcd.tls.ca.cert=/path/to/etcd-ca.crt
alluxio.etcd.tls.client.cert=/path/to/etcd-client.crt
alluxio.etcd.tls.client.key=/path/to/etcd-client-key-pkcs8.pem
# alluxio.etcd.tls.client.key.password=<your_password>
```

**重要提示**：ETCD 客户端密钥必须是 PKCS8 格式。使用以下命令转换标准 PEM 密钥：

```bash
openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in client-key.pem -out client-key-pkcs8.pem
```

### 高级：指定 TLS 协议

为了增强安全性，您可以将服务器限制为特定的 TLS 协议版本。将以下属性添加到 `alluxio-site.properties`：

```properties
# 指定允许的 TLS 协议 
alluxio.network.tls.server.protocols=TLSv1.2,TLSv1.3
```

## 第 3 部分：在 Kubernetes 中使用 TLS 部署

在 Kubernetes 中配置 TLS 涉及使用 secrets 来管理证书，并通过 Helm chart 或 `alluxio-cluster.yaml` 应用配置。

### 1. 创建 Kubernetes Secret

将生成的 PEM 证书存储在 Kubernetes secret 中。

```bash
kubectl create secret generic my-pem-secret \
  --from-file=ca.pem=./ca.pem \
  --from-file=server.pem=./server.pem \
  --from-file=server-key.pem=./server-key.pem \
  --from-file=client.pem=./client.pem \
  --from-file=client-key.pem=./client-key.pem
```

### 2. 配置并挂载 Secret

在您的 `alluxio-cluster.yaml` 中，引用 secret 并配置 TLS 属性。

```yaml
spec:
  # 将密钥挂载到 Pod 的指定路径下 
  secrets:
    coordinator:
      my-pem-secret: /opt/alluxio/certs
    worker:
      my-pem-secret: /opt/alluxio/certs

  properties:
    # 为 S3 API 启用 TLS（示例）
    alluxio.worker.s3.api.enabled: "true"
    alluxio.worker.s3.tls.enabled: "true"
    alluxio.worker.s3.https.port: "29996"
    alluxio.worker.s3.only.https.access: "true"

    # 指向从 Secret 挂载的证书文件
    alluxio.network.tls.ca.cert: "/opt/alluxio/certs/ca.pem"
    alluxio.network.tls.server.cert: "/opt/alluxio/certs/server.pem"
    alluxio.network.tls.server.key: "/opt/alluxio/certs/server-key.pem"

    # 出于安全保护禁用零拷贝
    alluxio.worker.s3.local.page.transfer.enabled: "false"
```

### 3. 部署集群

将配置应用到您的 Kubernetes 集群。

```bash
kubectl apply -f alluxio-cluster.yaml
```

## 第 4 部分：验证 TLS 设置

部署后，使用 `curl` 或 `openssl` 等工具验证 TLS 配置是否正常工作。

### 验证 S3 API (mTLS)

```bash
curl --http1.1 --cacert ca.pem --cert client.pem --key client-key.pem \
  https://<alluxio_worker_svc>:29996/test -v
```

### 验证 S3 API（仅 TLS 模式）

当 `alluxio.worker.s3.only.https.access` 为 `true` 时，尝试通过 HTTP 连接应该失败。

```bash
curl http://<alluxio_worker_svc>:29998/test -v
```

此命令应该导致"Connection refused"错误。

### 验证网关 (mTLS)

```bash
curl --http1.1 --cacert ca.pem --cert client.pem --key client-key.pem \
  https://<alluxio_gateway_svc>:8443/api/v1/mount -v
```

## 第 5 部分：安全最佳实践

* **证书轮换**：定期更新和轮换您的证书，以限制密钥泄露时的暴露窗口。
* **安全密钥存储**：保护您的私钥。在文件系统上，使用严格的权限：

  ```bash
  chmod 600 /path/to/keys/*.key
  chmod 644 /path/to/certs/*.pem
  ```
* **环境隔离**：为开发、测试和生产环境使用单独的 CA 和证书。

## 附录

### PEM 到 JKS 格式转换

```bash
# 1. 将 PEM 证书转换为 PKCS12
openssl pkcs12 -export -in server.pem -inkey server-key.pem -out server.p12 -name alluxio

# 2. 将 PKCS12 转换为 JKS
keytool -importkeystore -deststorepass keypass -destkeystore keystore.jks \
  -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass keypass
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.alluxio.io/ee-ai-cn/ai-3.7/administration/security/securing-alluxio-with-tls.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
