【问题标题】:Applying TLS to a working ingress results in default backend - 404将 TLS 应用于工作入口会导致默认后端 - 404
【发布时间】:2020-07-02 20:53:48
【问题描述】:

我已经在 ingress 命名空间中通过 helm 安装了 Nginx Ingress Controller。

helm ls --namespace ingress
NAME            NAMESPACE   REVISION    UPDATED                                 STATUS      CHART                   APP VERSION
nginx-ingress   ingress     1           2020-03-15 10:47:51.143159 +0530 IST    deployed    nginx-ingress-1.34.2    0.30.0  

服务和部署如下

apiVersion: v1
kind: Service
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: '"true"'
spec:
  type: LoadBalancer
  ports:
    - port: 8080
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: test-service
    app.kubernetes.io/instance: test-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: test-service
      app.kubernetes.io/instance: test-service
  template:
    metadata:
      labels:
        app.kubernetes.io/name: test-service
        app.kubernetes.io/instance: test-service
    spec:
      containers:
        - name: test-service
          image: "<acr-url>/test-service:c93c58c0bd4918de06d46381a89b293087262cf9"
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 8080
              protocol: TCP
          livenessProbe:
            httpGet:
              path: /devops/health/liveness
              port: 8080
            initialDelaySeconds: 60
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            httpGet:
              path: /devops/health/readiness
              port: 8080
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          env:
            - name: test-serviceClientId
              valueFrom:
                secretKeyRef:
                  key: test-serviceClientId
                  name: test-service-133
            - name: test-serviceClientSecret
              valueFrom:
                secretKeyRef:
                  key: test-serviceClientSecret
                  name: test-service-133
            - name: test-serviceTenantClientId
              valueFrom:
                secretKeyRef:
                  key: test-serviceTenantClientId
                  name: test-service-133
            - name: test-serviceTenantClientSecret
              valueFrom:
                secretKeyRef:
                  key: test-serviceTenantClientSecret
                  name: test-service-133
          resources:
            limits:
              cpu: 800m
            requests:
              cpu: 300m

使用重写配置服务的入口,如下所示

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
  - hosts:
    - apiexample.centralus.cloudapp.azure.com
    secretName: tls-secret
  rules:
    - host: "apiexample.centralus.cloudapp.azure.com"
      http:
        paths:
          - path: /testservice(/|$)(.*)
            backend:
              serviceName: test-service
              servicePort: 8080

tls-secret 已使用

生成
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=apiexample.centralus.cloudapp.azure.com/O=apiexample.centralus.cloudapp.azure.com"

$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt

在入口应用 tls 配置之前,我能够从 api 端点获得响应。 api 端点由 oauth 保护。

API 端点:

http://apiexample.centralus.cloudapp.azure.com/testservice/tenant/api/v1/endpoint

在入口应用 TLS 配置并点击

https://apiexample.centralus.cloudapp.azure.com/testservice/tenant/api/v1/endpoint

我得到默认后端 404。

我已经使用另一个示例服务(不受 oauth 保护)测试了带有入口的 TLS,它似乎适用于该服务。 这是其他服务的配置

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tea
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tea
  template:
    metadata:
      labels:
        app: tea
    spec:
      containers:
      - name: tea
        image: nginxdemos/nginx-hello:plain-text
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: tea-svc
  labels:
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: tea

服务的入口配置如下

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: cafe-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
  - hosts:
    - apiexample.centralus.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: apiexample.centralus.cloudapp.azure.com
    http:
      paths:
      - path: /teaprefix(/|$)(.*)
        backend:
          serviceName: tea-svc
          servicePort: 80

端点

https://apiexample.centralus.cloudapp.azure.com/teaprefix/someurl

工作正常。

如果我的配置中缺少任何内容以及我可能忽略的任何潜在问题,请告诉我。

注意:Service 和 Ingress 部署在 default 命名空间中,Ingress Controller 运行在 ingress 命名空间中 Nginx Ingress Controller 在 2 个 Pod 中运行

带有 TLS 配置的 Ingress Controller 的日志

Pod1

 10.244.0.1 - - [22/Mar/2020:06:57:12 +0000] "GET /testservice/tenant/api/v1/endpoint HTTP/1.1" 302 0 "-" "PostmanRuntime/7.23.0" 1495 0.004 [default-test-service-8080] [] 10.244.0.7:8080 0 0.004 302 f4671ede2f95148220c21fe44de6fdad
 10.244.0.1 - - [22/Mar/2020:06:57:13 +0000] "GET /tenant/api/v1/endpoint HTTP/1.1" 404 21 "http://apiexample.centralus.cloudapp.azure.com/tenant/api/v1/endpoint" "PostmanRuntime/7.23.0" 1563 0.001 [upstream-default-backend] [] 10.244.0.225:8080 21 0.004 404 ed41b36bc6b89b60bc3f208539a0d44c

Pod2

    10.244.0.1 - - [22/Mar/2020:06:57:12 +0000] "GET /tenant/api/v1/endpoint HTTP/1.1" 308 171 "https://apiexample.centralus.cloudapp.azure.com/testservice/tenant/api/v1/endpoint" "PostmanRuntime/7.23.0" 1580 0.000 [upstream-default-backend] [] - - - - ce955b7bb5118169e99dd4051060c897

来自没有 TLS 配置的 Ingress Controller 的日志

10.244.0.1 - - [22/Mar/2020:07:04:34 +0000] "GET /testservice/tenant/api/v1/endpoint HTTP/1.1" 200 276 "-" "PostmanRuntime/7.23.0" 1495 2.165 [default-test-service-8080] [] 10.244.0.4:8080 548 2.168 200 e866f277def90c398df4e509e45718b2

更新

在后端服务 (test-service) 上禁用身份验证也会导致相同的行为。 在不应用 TLS 的情况下,无需任何承载令牌即可使用 http 访问端点。 应用 TLS 后,当我使用 https/http 访问端点时,获取默认后端 - 404

更新

在没有

的情况下通过 ClusterIP 公开服务
service.beta.kubernetes.io/azure-load-balancer-internal: '"true"'

注释而不是 LoadBalancer 似乎也没有帮助。端点在没有 TLS 且应用 TLS 的情况下工作,获取默认后端 - 404

更新

测试服务是具有以下 WebSecurityConfiguration 的 Spring Boot 应用程序

@Component
@EnableResourceServer
public class WebSecurityConfiguration extends ResourceServerConfigurerAdapter {

  private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfiguration.class);

  private final HealthCheckWebSecurity healthCheckWebSecurity = new HealthCheckWebSecurity();

  private final Oauth2Settings oauth2Settings;
  private final JwtTokenStore jwtTokenStore;
  private final TenantService tenantService;
  private final TransportGuaranteeWebSecurity transportGuaranteeWebSecurity;

  @Autowired
  public WebSecurityConfiguration(
      Oauth2Settings oauth2Settings,
      JwtTokenStore jwtTokenStore,
      TenantService tenantService,
      TransportGuaranteeWebSecurity transportGuaranteeWebSecurity) {
    this.oauth2Settings = oauth2Settings;
    this.jwtTokenStore = jwtTokenStore;
    this.tenantService = tenantService;
    this.transportGuaranteeWebSecurity = transportGuaranteeWebSecurity;
  }

  @Override
  public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
    String resourceId = oauth2Settings.getResource("default").getResourceId();
    LOGGER.info("Resource service id: {}", resourceId);

    resources.resourceId(resourceId).tokenStore(jwtTokenStore);
  }

  @Override
  public void configure(HttpSecurity http) throws Exception {
    http.requestMatchers().anyRequest();
    http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    http.csrf().disable();

    healthCheckWebSecurity.configure(http);
    transportGuaranteeWebSecurity.configure(http);

    http.authorizeRequests().anyRequest().permitAll();
    http.addFilterAfter(buildTenancyContextFilter(), ChannelProcessingFilter.class);
    http.addFilterAfter(buildLongUrlFilter(), ChannelProcessingFilter.class);
  }

  private TenancyContextFilter buildTenancyContextFilter() {
    return new TenancyContextFilter(tenantService,
        new PathVariableTenantExtractor(Arrays.asList("/{tenantAlias}/api/**")));
  }

  private LongRequestHttpFilter buildLongUrlFilter() {
    return new LongRequestHttpFilter();
  }
}

public final class TransportGuaranteeWebSecurity {

  private TransportGuaranteeSettings transportGuaranteeSettings;

  TransportGuaranteeWebSecurity(TransportGuaranteeSettings transportGuaranteeSettings) {
    this.transportGuaranteeSettings = transportGuaranteeSettings;
  }


  public void configure(HttpSecurity httpSecurity) throws Exception {
    if (httpsRequired()) {
      httpSecurity.requiresChannel().anyRequest().requiresSecure();
    } else {
      httpSecurity.requiresChannel().anyRequest().requiresInsecure();
    }
  }

  private boolean httpsRequired() {
    final String transportGuarantee = transportGuaranteeSettings.getTransportGuarantee();
    return !TransportGuaranteeSettings.TRANSPORT_GUARANTEE_NONE.equalsIgnoreCase(transportGuarantee);
  }

}


@ConfigurationProperties(prefix = "web.security")
public class TransportGuaranteeSettings {
  static final String TRANSPORT_GUARANTEE_NONE = "NONE";
  static final String TRANSPORT_GUARANTEE_CONFIDENTIAL = "CONFIDENTIAL";

  private static final Logger LOGGER = LoggerFactory.getLogger(TransportGuaranteeSettings.class);

  private static final String TRANSPORT_GUARANTEE_PROPERTY = "web.security.transportGuarantee";

  private String transportGuarantee;

  public String getTransportGuarantee() {
    return transportGuarantee;
  }

  public void setTransportGuarantee(String transportGuarantee) {
    this.transportGuarantee = transportGuarantee.trim();
    logUnexpectedValue();
  }

  private void logUnexpectedValue() {
    if (!TRANSPORT_GUARANTEE_NONE.equalsIgnoreCase(transportGuarantee)
        && !TRANSPORT_GUARANTEE_CONFIDENTIAL.equalsIgnoreCase(transportGuarantee)) {
      LOGGER.debug(
          "Unknown value '{}' for property '{}' (expected '{}' or '{}'). Defaulted to '{}'.",
          transportGuarantee, TRANSPORT_GUARANTEE_PROPERTY, TRANSPORT_GUARANTEE_NONE, TRANSPORT_GUARANTEE_CONFIDENTIAL,
          TRANSPORT_GUARANTEE_CONFIDENTIAL);
    }
  }
}

在我的 application.yaml 中,

web.security.transportGuarantee: NONE

租户上下文过滤器从 URL 中提取租户信息并设置一个 ThreadLocal。这应该没有任何问题,因为我可以在没有 TLS 配置的情况下访问端点。出于同样的原因,我也没有看到 TransportGuaranteeWebSecurity 有任何问题。

更多调试日志

kubectl 获取 pods -owide --namespace ingress

NAME                                             READY   STATUS    RESTARTS   AGE   IP             NODE                                NOMINATED NODE   READINESS GATES
nginx-ingress-controller-5fcbccd545-bdh25        1/1     Running   1          15d   10.244.0.22    aks-agentpool-44086776-vmss000000   <none>           <none>
nginx-ingress-controller-5fcbccd545-ptx6j        1/1     Running   0          15d   10.244.0.21    aks-agentpool-44086776-vmss000000   <none>           <none>
nginx-ingress-default-backend-554d7bd77c-zxzlf   1/1     Running   0          15d   10.244.0.225   aks-agentpool-44086776-vmss000000   <none>           <none>

kubectl 获取 svc

test-service                          LoadBalancer   10.0.231.35    13.89.111.39    8080:31534/TCP               14d
tea-svc                                   ClusterIP      10.0.12.216    <none>          80/TCP                       17d

kubectl 获取

test-service         apiexample.centralus.cloudapp.azure.com   10.240.0.4   80, 443      15d

【问题讨论】:

  • 提供来自 nginx 入口控制器 pod 的日志
  • @Arghya Sadhu 在帖子中添加了日志
  • 您说使用 TLS 测试了另一个服务并且它有效,因为您对两个入口使用相同的证书,那么两个后端服务之间的主要区别是什么?您提到了 OAUTH,也许这就是 link 帮助。
  • @KoopaKiller 我已禁用身份验证并尝试过。但是看到同样的行为。我已经用详细信息更新了票证。
  • @java_geek,在您的主要服务中,您正在使用service.beta.kubernetes.io/azure-load-balancer-internal: '"true"' 的注释,而在您的测试服务中则没有。我不确定是否会干扰某些事情。我将尝试使用 GCP 而不是 Azure 来重现您的场景,然后返回这里结果。

标签: nginx kubernetes kubernetes-ingress nginx-ingress azure-aks


【解决方案1】:

我在我的 GCP 帐户中重现了您的场景,但没有得到相同的结果,因此我发布了对每个组件进行故障排除的步骤,以确保所有组件都正常工作。在简历中,主要问题似乎是应用程序如何处理pathshost

Kubernetes:1.15.3 (GKE) Nginx Ingress:安装在offical docs之后

根据您的 yaml,我删除了 readinessliveness 探针,以及要测试的环境 env,并将映像更改为 nginx 映像(在端口 80 上):

apiVersion: v1
kind: Service
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
  annotations:
    service.beta.kubernetes.io/azure-load-balancer-internal: '"true"'
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: http
      protocol: TCP
      name: http
  selector:
    app.kubernetes.io/name: test-service
    app.kubernetes.io/instance: test-service
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: test-service
      app.kubernetes.io/instance: test-service
  template:
    metadata:
      labels:
        app.kubernetes.io/name: test-service
        app.kubernetes.io/instance: test-service
    spec:
      containers:
        - name: test-service
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - name: http
              containerPort: 80
              protocol: TCP

应用后,我们可以在应用入口规范之前检查(部署和服务)是否按预期运行。

要检查这一点,我们可以使用 curl 镜像来 curl 目标或由官方 kubernetes docs 提供的 dnsutil 容器。 在这种情况下,我使用了curlimages/curl 进行测试:

apiVersion: v1
kind: Pod
metadata:
  name: curl
  namespace: default
spec:
  containers:
  - name: curl
    image: curlimages/curl
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always

随着 curl 容器的运行,我们可以首先检查我们的 nginx 镜像的容器是否正确运行,并直接回答“curling”他们的 IP 请求。

下面的命令将从带有标签app.kubernetes.io/name=test-service的pod创建一个名为$pod的变量,并带有pod的ip。

$ pod=$(kubectl get pods -ojsonpath='{.items[*].status.podIP}' -l app.kubernetes.io/name=test-service)

$ echo $pod
192.168.109.12

使用curl pod create 之前,我们可以检查 pod 是否正在处理请求:

$ kubectl exec curl -- curl -Is $pod

HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Tue, 24 Mar 2020 09:08:21 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
Connection: keep-alive
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes

看到响应HTTP/1.1 200 OK,我们继续测试服务:

$ kubectl exec curl -- curl -Is test-service
HTTP/1.1 200 OK
Server: nginx/1.17.9
Date: Tue, 24 Mar 2020 09:11:13 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
Connection: keep-alive
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes

同样,HTTP/1.1 200 OK 用于服务。

让我们更进一步,部署 没有 TLS 的 nginx 入口,在之前和之后进行测试:

生成和应用证书:

$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=apiexample.centralus.cloudapp.azure.com/O=apiexample.centralus.cloudapp.azure.com"
...
$ kubectl create secret tls tls-secret --key tls.key --cert tls.crt
secret/tls-secret created

没有 TLS 的入口(我已更改为端口 80 以匹配我的 nginx 映像):

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  rules:
    - host: "apiexample.centralus.cloudapp.azure.com"
      http:
        paths:
          - path: /testservice(/|$)(.*)
            backend:
              serviceName: test-service
              servicePort: 80

使用 GCP 提供的 IP(省略)从我的桌面到互联网进行测试:

$ curl -ILH "Host: apiexample.centralus.cloudapp.azure.com" http://34.77.xxx.xx/testservice
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Tue, 24 Mar 2020 10:41:21 GMT
Content-Type: text/html
Content-Length: 612
Connection: keep-alive
Vary: Accept-Encoding
Last-Modified: Tue, 03 Mar 2020 14:32:47 GMT
ETag: "5e5e6a8f-264"
Accept-Ranges: bytes

直到这里一切正常。我们现在可以将 TLS 添加到入口规范并重试:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-service
  labels:
    app.kubernetes.io/name: test-service
    helm.sh/chart: test-service-0.1.0
    app.kubernetes.io/instance: test-service
    app.kubernetes.io/managed-by: Helm
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  tls:
  - hosts:
    - apiexample.centralus.cloudapp.azure.com
    secretName: tls-secret
  rules:
    - host: "apiexample.centralus.cloudapp.azure.com"
      http:
        paths:
          - path: /testservice(/|$)(.*)
            backend:
              serviceName: test-service
              servicePort: 80

使用 curl 进行测试:

curl -ILH "Host: apiexample.centralus.cloudapp.azure.com" https://34.77.147.74/testservice -k
HTTP/2 200 
server: nginx/1.17.8
date: Tue, 24 Mar 2020 10:45:25 GMT
content-type: text/html
content-length: 612
vary: Accept-Encoding
last-modified: Tue, 03 Mar 2020 14:32:47 GMT
etag: "5e5e6a8f-264"
accept-ranges: bytes
strict-transport-security: max-age=15724800; includeSubDomains

好的,这可以与 TLS 一起使用,因此基于此我们可以得出结论,您的 yaml 规范正在运行,并且您可能在入口定义和您的应用程序中遇到了 path 的一些问题:

您正在使用注解nginx.ingress.kubernetes.io/rewrite-target: /$2 和路径/testservice(/|$)(.*)

这意味着(.*)捕获的任何字符都将分配给占位符$2,然后将其用作rewrite-target注释中的参数。

基于你的入口path 正则表达式:

  • apiexample.centralus.cloudapp.azure.com/testservice 重写为apiexample.centralus.cloudapp.azure.com/

  • apiexample.centralus.cloudapp.azure.com/testservice/ 重写为 apiexample.centralus.cloudapp.azure.com/

  • apiexample.centralus.cloudapp.azure.com/testservice/tenant/api/v1/endpoint 重写为 apiexample.centralus.cloudapp.azure.com/tenant/api/v1/endpoint

在 nginx pod 日志中检查时,您可以看到重写后请求的 url:

2020/03/24 10:59:33 [error] 7#7: *186 open() "/usr/share/nginx/html/tenant/api/v1/endpoint" failed (2: No such file or directory), client: 10.20.1.61, server: localhost, request: "HEAD /tenant/api/v1/endpoint HTTP/1.1", host: "apiexample.centralus.cloudapp.azure.com"

因此,通过这次测试,我可以得出结论,您的部署、服务和入口都可以正常工作,并且没有任何拼写错误或格式问题。所以我的建议是仔细检查应用程序

  • 确保您的应用程序正确处理path
  • 如果您的应用程序正在执行一些 URL 验证,请确保它可以处理 http 和 https;
  • 如果您启用了 CORS,请按照 here 所述调整入口。

由于您没有发布任何应用程序作为示例进行复制,因此我的测试仅限于通用应用程序作为后端。如果您可以提供有关后端应用程序或一些产生相同行为的通用应用程序的更多详细信息,请告诉我,我们很乐意提供更多详细信息来改进我的答案。

参考资料:

https://kubernetes.github.io/ingress-nginx/deploy/

https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/

https://kubernetes.github.io/ingress-nginx/user-guide/ingress-path-matching/

【讨论】:

  • 嗨@KoopaKiller。谢谢你的帖子。正如我所提到的,在不应用 TLS 的情况下,我能够达到我的端点;这意味着路径都很好。它是一个弹簧启动应用程序;如果可以帮助解决任何问题,我可以分享 WebSecurityConfiguration。
  • 嗨@java_geek,我会尝试使用一些spring boot应用程序进行相同的测试,您可以分享的任何帮助信息都是有效的。 =)
  • @java_geek,如果您确定不是重定向/路径问题,请提供kubectl get pods -owide 的输出以显示 nginx 部署的 pod,kubectl get svckubectl get ing... 还有,请提供命令的输出:curl -ILH "Host: apiexample.centralus.cloudapp.azure.com" https://&lt;INGRESS-IP&gt;/testservice -k.
  • 抱歉回复延迟;忙于一些承诺。在帖子中添加您要求的一些详细信息。
猜你喜欢
  • 2017-11-04
  • 1970-01-01
  • 2020-01-04
  • 2020-06-21
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-19
相关资源
最近更新 更多