#作者:閆乾苓
文章目錄
- 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