问题描述
我试图让我的入口通过 https 运行,但我收到了 HTTP ERROR 403
,我不知道我在这里遗漏了什么。
我试图在 my-local-domain.com
上访问它们,并且我在我的 etc/hosts
文件中添加了该条目作为
127.0.0.1 my-local-domain.com
这样我就可以通过这种方式访问它。
这是我的发行人
apiVersion: cert-manager.io/v1
kind: Issuer
Metadata:
name: cert-issuer
namespace: my-namespace
spec:
selfSigned: {}
这是我的证书
apiVersion: cert-manager.io/v1
kind: Certificate
Metadata:
name: self-signed-cert
namespace: my-namespace
spec:
secretName: my-secret-tls
dnsNames:
- my-local-domain.com
- www.my-local-domain.com
issuerRef:
name: cert-issuer
虽然这是我的 Nginx 入口:
apiVersion: networking.k8s.io/v1
kind: Ingress
Metadata:
name: ingress-service
labels:
name: ingress-service
namespace: my-namespace
annotations:
Nginx.ingress.kubernetes.io/rewrite-target: /$1
Nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
Nginx.ingress.kubernetes.io/ssl-redirect: 'true'
namespace: my-namespace
spec:
tls:
- hosts:
- my-local-domain.com
- www.my-local-domain.com
secretName: my-secret-tls
rules:
- host: my-local-domain.com
http:
paths:
- path: /api/(.*)
pathType: Prefix
backend:
service:
name: web-api
port:
number: 443
- path: /(.*)
pathType: Prefix
backend:
service:
name: web-client
port:
number: 80
Nginx.conf 用于我的网络客户端服务
server {
listen 80;
location / {
root /usr/share/Nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
gzip on;
}
当我尝试使用 https://my-local-domain.com
Access to my-local-domain.com was denied
You don't have authorization to view this page.
HTTP ERROR 403
我也试过跑
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "//CN=my-local-domain.com\O=my-local-domain.com" -addext "subjectAltName = DNS:my-local-domain.com"
kubectl create secret tls tls-secret --key tls.key --cert tls.crt -n my-namespace
删除 Certificate
和 CertificateIssuer
并在入口中添加 tls-secret
作为 secretName
,并将这些 tls.key
和 tls.crt
添加到我的网络-client Nginx 并将其更新为:
server {
listen 443 ssl default_server;
ssl_protocols SSLv3 TLSv1;
server_name www.my-local-domain.com my-local-domain.com;
access_log /var/log/Nginx/access.log;
error_log /var/log/Nginx/error.log info;
keepalive_timeout 75 75;
ssl_certificate /etc/ssl/certs/self-signed.crt;
ssl_certificate_key /etc/ssl/private/self-signed.key;
ssl_session_timeout 5m;
add_header Strict-Transport-Security "max-age=7200";
location / {
root /usr/share/Nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
}
附言这样做时,我在端口 443
而不是 80
上运行 everyrhin。
当我从入口中删除 tls
部分时,它确实通过 HTTP 工作。而且我还尝试将我的 dns/host 从 my-local-domain.com
更改为仅 localhost
但仍然相同。即使我尝试访问 https://localhost
,我也会得到 HTTP ERROR 403
。
解决方法
我不知道这是否会有所帮助,但这里有一些建议:
-
确定错误的来源
您向我们提供了大量代码,但没有提供错误的详细信息。 403 是由您的网络服务、您的 api 还是您的入口控制器抛出的?您可以在错误页面中检查。来自 ingress-controller 的错误通常在页脚中包含一些类似“openresty”的想法。但这几乎不取决于您在 k8s 中使用的入口控制器。
您还可以检查容器的日志(nginx 将日志写入/var/log/nginx/error.log
)。您可以在此处找到一些更详细的信息,说明您收到 403 的原因。 -
让集群处理 SSL 终止
不要将 ssl 认证放入容器中。它几乎不会增加您的应用程序的复杂性。
当集群处理它时,它会容易得多。因此,您的应用可以更快地部署在具有其他环境的其他集群上。 -
在使用自签名证书时避免使用证书管理器
正如您已经测试过的,但我建议仅在需要来自 Let encrypt 的证书时才使用 cert-manager。否则会再次增加复杂性。 -
不要混淆 HTTP 和 HTTPS
您的 webapi 使用 HTTPS 进行内部通信(内部表示:ingress-controller -> webapi-service,通常未加密)...但不适用于您的 web-server。
保持简单 - 为所有人或任何人使用 HTTPS。 -
尽量避免 url 重写
只要可能,尽量避免 url-rewrite。我经常看到它的问题,所以我建议避免它。
我知道这并不总是可能的,但是当所有组件都由您开发时......您为什么需要它?这是您在“简单”中的入口:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-service labels: name: ingress-service namespace: my-namespace annotations: nginx.ingress.kubernetes.io/ssl-redirect: 'true' spec: tls: - hosts: - my-local-domain.com - www.my-local-domain.com secretName: my-secret-tls rules: - host: my-local-domain.com http: paths: - path: /api/ backend: service: name: web-api port: number: 80 - path: / backend: service: name: web-client port: number: 80
-
无根是最好的
对于您的问题不是很重要,但不要使用标准的 nginx-image,而是使用无特权的 nginx-image。如果您的服务(在本例中为nginx
)被黑客入侵,则黑客拥有与 nginx 相同的权限。这意味着,他可以轻松地将工具安装到 nginx-container 中并做非常糟糕的事情。
如果您使用的是非特权映像,那么黑客可以……几乎什么也做不了。他需要第二次利用来提升他的权利。
祝你好运找到你的错误。当您与我们分享您的后续步骤时,我们很高兴。