#作者:闫乾苓
文章目录
- 1.问题及背景
- 2.方案说明
- 3.部署步骤
- 3.1 制作TLS/SSL私有证书
- 3.2 创建访问nginx账户密码文件并创建secret
- 3.3 为TLS/SSL私有证书创建secret
- 3.4 为Nginx 配置文件创建confimap
- 3.5 使用deployment,svc部署nginx
- 3.6 客户端curl上传下载文件
1.问题及背景
- 中间件巡检脚本生成报告需统一汇总至一台服务器,便于集中分析与管理。
- 巡检脚本需要集中存放,支持客户端下载更新,提高维护效率和一致性。
2.方案说明
- 在集中汇总服务器部署 Nginx,启用 WebDAV 模块以支持客户端使用 curl 上传巡检日志。
- Nginx 默认支持 HTTP 文件下载,用于客户端获取巡检脚本。
- 上传与下载过程通过 HTTP Basic 认证进行账户密码验证,确保安全性。
- 为加强数据传输安全,使用https。
3.部署步骤
3.1 制作TLS/SSL私有证书
使用自有CA签发的私有证书(Private CA + Signed Certificate),需要创建一个根CA(Root CA),然后用这个CA去签发服务器证书。
这样做的好处是:你可以将CA证书安装到多个客户端的信任库中,这样所有由该CA签发的证书都会被信任。更适合内部网络、企业内网服务、局域网部署等。
3.1.1生成自有CA私钥
需要使用openssl命令,如果系统中没有,可以使用如下命令进行安装:
~# yum install openssl~# openssl genpkey -algorithm RSA -out ca.key -aes256
记录输入的密码(生成环境部署时,密码请自行替换):abc@888.com
命令执行完成后生成如下文件:
-rw------- 1 root root 1.9K 6月 6 11:12 ca.key
3.1.2 生成CA证书(自签)
交互式命令需要提供的内容请参考以下内容:
~# openssl req -new -x509 -days 3650 -key ca.key -out ca.crt
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:InternalCA
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:MyInternalRootCA
Email Address []:mail@cmc.com
执行完成后,会生成一个根CA证书文件:
-rw-r--r-- 1 root root 1.5K 6月 6 11:14 ca.crt(可选)查看证书内容
~# openssl x509 -in ca.crt -text -noout
这会显示证书详细信息,包括颁发者、有效期、公钥、指纹等。
3.1.3生成服务器私钥和CSR
~# openssl genpkey -algorithm RSA -out server.key
生成的私钥
-rw------- 1 root root 1.7K 6月 6 11:15 server.key~# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:Beijing
Locality Name (eg, city) []:Beijing
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany IT Department
Organizational Unit Name (eg, section) []:SA
Common Name (e.g. server FQDN or YOUR name) []:report.server.com
Email Address []:mail@server.comPlease enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
注意:Common Name (e.g. server FQDN or YOUR name) []: 输入的内容需要和nginx要使用的域名保持一致。
以下两行直接回车,可以不输入。
A challenge password []:
An optional company name []:
命令执行完成后生成如下文件:
-rw-r--r-- 1 root root 1.1K 6月 6 11:21 server.csr
3.1.4使用自有CA签发服务器证书
-days 3650 指定证书有效期为10年
~# openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
Signature ok
subject=C = CN, ST = Beijing, L = Beijing, O = MyCompany IT Department, OU = SA, CN = report.server.com, emailAddress = mail@server.com
Getting CA Private Key
Enter pass phrase for ca.key: #输入第一步创建CA私钥时的密码
命令执行完成后生成的文件如下:
-rw------- 1 root root 1.7K 6月 6 11:15 server.key
-rw-r--r-- 1 root root 1.4K 6月 6 11:27 server.crt
3.2 创建访问nginx账户密码文件并创建secret
安装htpasswd命令的软件包:
~# yum install -y httpd-tools
使用htpasswd命令创建账户并设置密码,-c 指定文件名,user为用户名,请自行替换。
~# htpasswd -c htpasswd user
New password:
Re-type new password:
Adding password for user user
在k8s环境为此文件创建secret
~# kubectl create secret generic nginx-webdav-basic-auth --from-file=htpasswd~# kubectl get secret
NAME TYPE DATA AGE
nginx-webdav-basic-auth Opaque 1 11s
3.3 为TLS/SSL私有证书创建secret
kubectl create secret generic nginx-webdav-tls-certs \--from-file=ca.crt \--from-file=server.crt \--from-file=server.key
它会将本地的三个文件:
- ca.crt(CA证书)
- server.crt(服务器证书)
- server.key(服务器私钥)
打包成一个 Kubernetes Secret 对象,名为:nginx-webdav-tls-certs
Pod挂载时Secret 中的每个 key(即文件名)都会被挂载到 /etc/nginx/certs/ 目录下作为一个独立文件。
3.4 为Nginx 配置文件创建confimap
Nginx.conf示例配置文件如下,生产环境请更加实际情况进行调整:
worker_processes 1;events {worker_connections 1024;
}http {include mime.types;default_type application/octet-stream;server {listen 443 ssl;server_name report.server.com;ssl_certificate /etc/nginx/certs/server.crt;ssl_certificate_key /etc/nginx/certs/server.key;ssl_client_certificate /etc/nginx/certs/ca.crt;ssl_verify_client optional;# 文件下载配置location /down/ {alias /data/down/; # 注意结尾的斜杠autoindex on; # 自动列出目录内容(可选)auth_basic "Restricted";auth_basic_user_file /etc/nginx/htpasswd;}# WebDAV相关配置(上传) location /upload {# 启用WebDAVdav_methods PUT DELETE MKCOL COPY MOVE;# 允许创建新文件和目录create_full_put_path on;# 设置谁可以访问这个位置dav_access user:rw group:rw all:r;# 设置上传文件的存储目录alias /data/nginx_upload_data;# 允许浏览器访问现有文件(GET 请求)autoindex off; # 关闭目录列表(更安全)add_header Content-Disposition "inline"; # 浏览器内直接显示文件(非强制下载)# 限制仅允许 GET 和 WebDAV 方法if ($request_method !~ ^(GET|HEAD|PUT|DELETE|MKCOL|COPY|MOVE)$) {return 405;}# 可选:限制上传文件的最大尺寸client_max_body_size 50M;# 确保只有授权用户才能进行上传auth_basic "Restricted";auth_basic_user_file /etc/nginx/htpasswd;}}
}
创建configmap
~# kubectl create configmap nginx-webdav-conf --from-file=nginx.conf~# kubectl get cm
NAME DATA AGE
nginx-webdav-conf 1 2d18h
3.5 使用deployment,svc部署nginx
deployment示例中只设置了1个pod副本,并通过nodeName指定了pod固定调度的k8s node节点,文件持久存储使用HostPath,如需设置多个副本,为保证文件下载文件统一管理,建议使用nfs等共享存储方案
deployment.yaml 示例内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:name: report-nginx-webdavlabels:app: report-nginx
spec:replicas: 1selector:matchLabels:app: report-nginxtemplate:metadata:labels:app: report-nginxspec:nodeName: worker3 containers:- name: nginximage: nginx:1.27.5ports:- containerPort: 443volumeMounts:- name: tls-certsmountPath: /etc/nginx/certsreadOnly: true- name: basic-authmountPath: /etc/nginx/htpasswdsubPath: htpasswdreadOnly: true - name: custom-configmountPath: /etc/nginx/nginx.confsubPath: nginx.confreadOnly: true- name: download-datamountPath: /data/down- name: upload-datamountPath: /data/nginx_upload_datavolumes:- name: tls-certssecret:secretName: nginx-webdav-tls-certs- name: basic-authsecret:secretName: nginx-webdav-basic-auth- name: custom-configconfigMap:name: nginx-webdav-conf- name: download-datahostPath:path: /data/report-nginx-data/downtype: Directory- name: upload-datahostPath:path: /data/report-nginx-data/uploadtype: Directory
svc yaml 示例内容如下,生产环境看根据实际环境调整svc对外开放端口的方式:
apiVersion: v1
kind: Service
metadata:name: nginx-webdav-ssl-svc
spec:type: NodePortselector:app: report-nginxports:- protocol: TCPport: 443targetPort: 443nodePort: 30043namenode指定的主机节点创建hostpath目录,并设置为Nginx pod内nginx 的uid,gid
~# mkdir /data/report-nginx-data/{down,upload} -p
~# chown -R 101:101 report-nginx-data/
部署deployment, svc
~# kubectl apply -f deployment.yaml -f svc.yaml~# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod/report-nginx-webdav-5f977c7bfc-mpfcg 1/1 Running 1 (2d21h ago) 2d21h~# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-webdav-ssl-svc NodePort 10.110.106.124 <none> 443:30043/TCP 2d21h
3.6 客户端curl上传下载文件
客户端访问服务器端https时,需要指定CA证书去验证TLS/SSL证书,所以需要把自签的私有CA证书复制到客户端,在使用curl访问时指定。
-rw------- 1 root root 1.9K 6月 6 11:12 ca.key
另外为将htpasswd创建的基于Nginx Basic Auth 的账户和密码,访问的服务器域名存入一个文件中,方便使用。
~# vim .netrc
machine report.server.com
login user
password abc.888.com
上传文件到服务器upload目录示例命令:
~# curl --cacert ca.crt --netrc-file .netrc --upload-file file01.txt https://report.server.com:30043/upload/
从服务器down目录下载脚本到本地示例命令:
~# curl --cacert ca.crt --netrc-file .netrc -o file02.sh https://report.server.com:30043/down/file02.sh