众所周知,nginx的50x页面/404页面都是类似如下:

由于此界面暴露了web容器信息,在漏洞扫描时是无法过关的。

在k8s集群里,不重新制作nginx镜像的情况下,如何替换掉默认的nginx的50x/404界面呢?

在nginx里,错误界面的默认配置如下:

error_page   500 502 503 504  /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}

我们要重新指定错误界面,修改成如下配置即可:

error_page   500 502 503 504  /502.html;
location = /502.html {
root /usr/share/nginx/html;
}

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}

当然,这个需要事先准备好502.html和404.html,这个很简单,直接在deployment的preStart里动态写入即可。

完整的yaml如下:

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-pvc
namespace: component
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 3Gi
storageClassName: storage-class
---
apiVersion: v1
data:
default.conf: >
server {
listen 80;
listen [::]:80;
server_name localhost;

#access_log /var/log/nginx/host.access.log main;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}

#error_page 404 /404.html;

# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /502.html;
location = /502.html {
root /usr/share/nginx/html;
}

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html;
}
}

kind: ConfigMap
metadata:
annotations: {}
labels: {}
name: nginx-configmap
namespace: component

---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx
namespace: component
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
nodeName: master
containers:
- env:
- name: TZ
value: Asia/Shanghai
image: 'nginx:alpine3.18'
imagePullPolicy: IfNotPresent
lifecycle:
postStart:
exec:
command:
- /bin/sh
- '-c'
- |
echo '<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>502 Bad Gateway</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f2f2f2;
color: #333;
}
.container {
text-align: center;
}
h1 {
font-size: 72px;
margin: 0;
}
p {
font-size: 24px;
margin: 10px 0 20px;
}
a {
color: #007bff;
text-decoration: none;
font-size: 18px;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>502</h1>
<p>Bad Gateway</p>
<p>服务暂时不可用,请稍后再试。</p>
</div>
</body>
</html>' > /usr/share/nginx/html/502.html

echo '<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f2f2f2;
color: #333;
}
.container {
text-align: center;
}
h1 {
font-size: 72px;
margin: 0;
}
p {
font-size: 24px;
margin: 10px 0 20px;
}
a {
color: #007bff;
text-decoration: none;
font-size: 18px;
}
a:hover {
text-decoration: underline;
}
</style>
</head>
<body>
<div class="container">
<h1>404</h1>
<p>Not Found</p>
<p>您访问的页面不存在。</p>
</div>
</body>
</html>' > /usr/share/nginx/html/404.html
name: nginx
livenessProbe:
httpGet:
path: /
port: 80
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
failureThreshold: 3
initialDelaySeconds: 3
periodSeconds: 3
successThreshold: 1
timeoutSeconds: 10
ports:
- containerPort: 32125
name: http3
protocol: TCP
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/nginx/conf.d/default.conf
name: config-volume
subPath: default.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
fsGroup: 0
runAsUser: 0
terminationGracePeriodSeconds: 30
volumes:
- name: nginx-pvc-claim
persistentVolumeClaim:
claimName: nginx-pvc
- configMap:
defaultMode: 420
items:
- key: default.conf
path: default.conf
name: nginx-configmap
name: config-volume
---
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
app: nginx
name: nginx
namespace: component
spec:
ports:
- name: port2
nodePort: 30080
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 10800
type: NodePort