TLS+Nginx+MinIO+django-minio-storage 负载均衡+加密传输
想实现MinIO的负载均衡? 想实现HTTPS加密传输? django-minio-storage老报错?? 你也跟我一样被折磨过了吗? 来我叫你做事!!!!

想解决报错?:
S3Error('S3 operation failed; code: AccessDenied, message: Access denied, resource: /data-process-engine-static, request_id: 17BEB7CAA12CB598, host_id: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8, bucket_name: data-process-engine-static')
想解决?:
S3 operation failed; code: InvalidRequest, message: Invalid Request (invalid hostname)
狠货来了!!!!!!!!
Nginx开启负载均衡:
upstream minio_s3 {least_conn;server minio-01.internal-domain.com:9000;server minio-02.internal-domain.com:9000;server minio-03.internal-domain.com:9000;server minio-04.internal-domain.com:9000;}upstream minio_console {least_conn;server minio-01.internal-domain.com:9001;server minio-02.internal-domain.com:9001;server minio-03.internal-domain.com:9001;server minio-04.internal-domain.com:9001;}server{listen [::]:80;server_name minio.example.net;# Allow special characters in headersignore_invalid_headers off;# Allow any size file to be uploaded.# Set to a value such as 1000m; to restrict file size to a specific valueclient_max_body_size 0;# Disable bufferingproxy_buffering off;proxy_request_buffering off;location / {proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Authorization $http_authorization;proxy_connect_timeout 300;# Default is HTTP/1, keepalive is only enabled in HTTP/1.1proxy_http_version 1.1;proxy_set_header Connection "";chunked_transfer_encoding off;proxy_pass http://minio_s3; # This uses the upstream directive definition to load balance}}
以上配置会MinIO的集群中各个节点之间进行负载均衡
django-minio-storage 配置:
MINIO_STORAGE_ENDPOINT = 'minio.example.net'# 因为MINIO中不光存储静态资源还会存储动态资源,相对比较铭感,必须强制加密通信MINIO_STORAGE_USE_HTTPS = True
Nginx开启https:
server{listen 80;listen 443 ssl http2;server_name minio.example.net;# index index.php index.html index.htm default.php default.htm default.html;root /www/wwwroot/minio.example.net;#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则ssl_certificate /www/server/panel/vhost/cert/minio.example.net/fullchain.pem;ssl_certificate_key /www/server/panel/vhost/cert/minio.example.net/privkey.pem;ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;add_header Strict-Transport-Security "max-age=31536000";error_page 497 https://$host$request_uri;#SSL-END# MinIO专用配置# Allow special characters in headersignore_invalid_headers off;# Allow any size file to be uploaded.# Set to a value such as 1000m; to restrict file size to a specific valueclient_max_body_size 0;# Disable bufferingproxy_buffering off;proxy_request_buffering off;# MinIO专用配置结束location / {proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Authorization $http_authorization;proxy_connect_timeout 300;# Default is HTTP/1, keepalive is only enabled in HTTP/1.1proxy_http_version 1.1;proxy_set_header Connection "";chunked_transfer_encoding off;proxy_pass http://minio_s3; # This uses the upstream directive definition to load balance}}
到这里是不是觉得已经完工了? 是不是急着尝试? 结果还是报错了?
来, 我教你如何巧妙的绕过这中烦人的鉴权验证机制:
首先我们在Nginx这边开启强制Https:
#HTTP_TO_HTTPS_STARTif ($server_port !~ 443){rewrite ^(/.*)$ https://$host$1 permanent;}#HTTP_TO_HTTPS_END
把以上的内容添加到Server模块里即可.
其次, 我们在django这边也得改一下了:
MINIO_STORAGE_USE_HTTPS = False
这里我就解释一下, 为什么Nginx开启Https, 反而django这边就关掉https呢?
原因如下:
-
关闭django-minio-storage的https协议是因为避免鉴权验证失败.
-
又开启nginx的强制Https呢, 是因为这个传输过程必须要加密. 一旦开启了强制https, 就算django-minio-storage用http协议请求, 也会以https协议进行传送, 而minio-storage计算的signature是按照http协议来计算的, 经过nginx proxy_pass时就不会因为协议不通而出现鉴权失败

Nginx的完整配置:
upstream minio_s3 {least_conn;server minio-01.internal-domain.com:9000;server minio-02.internal-domain.com:9000;server minio-03.internal-domain.com:9000;server minio-04.internal-domain.com:9000;}upstream minio_console {least_conn;server minio-01.internal-domain.com:9001;server minio-02.internal-domain.com:9001;server minio-03.internal-domain.com:9001;server minio-04.internal-domain.com:9001;}server{listen 80;listen 443 ssl http2;server_name minio.example.net;# index index.php index.html index.htm default.php default.htm default.html;root /www/wwwroot/minio.example.net;#SSL-START SSL相关配置,请勿删除或修改下一行带注释的404规则#error_page 404/404.html;#HTTP_TO_HTTPS_STARTif ($server_port !~ 443){rewrite ^(/.*)$ https://$host$1 permanent;}#HTTP_TO_HTTPS_ENDssl_certificate /www/server/panel/vhost/cert/minio.example.net/fullchain.pem;ssl_certificate_key /www/server/panel/vhost/cert/minio.example.net/privkey.pem;ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;ssl_prefer_server_ciphers on;ssl_session_cache shared:SSL:10m;ssl_session_timeout 10m;add_header Strict-Transport-Security "max-age=31536000";error_page 497 https://$host$request_uri;#SSL-END#ERROR-PAGE-START 错误页配置,可以注释、删除或修改#error_page 404 /404.html;#error_page 502 /502.html;#ERROR-PAGE-END# MinIO专用配置# Allow special characters in headersignore_invalid_headers off;# Allow any size file to be uploaded.# Set to a value such as 1000m; to restrict file size to a specific valueclient_max_body_size 0;# Disable bufferingproxy_buffering off;proxy_request_buffering off;# MinIO专用配置结束# #REWRITE-START URL重写规则引用,修改后将导致面板设置的伪静态规则失效include /www/server/panel/vhost/rewrite/minio.example.net.conf;# #REWRITE-END# 禁止访问的文件或目录location ~ ^/(\.user.ini|\.htaccess|\.git|\.svn|\.project|LICENSE|README.md){return 404;}# #一键申请SSL证书验证目录相关设置location ~ \.well-known{allow all;}location / {proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header Authorization $http_authorization;proxy_connect_timeout 300;# Default is HTTP/1, keepalive is only enabled in HTTP/1.1proxy_http_version 1.1;proxy_set_header Connection "";chunked_transfer_encoding off;}location /minio/ui/ {rewrite ^/minio/ui/(.*) /$1 break;proxy_set_header Host $http_host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto $scheme;proxy_set_header X-NginX-Proxy true;# This is necessary to pass the correct IP to be hashedreal_ip_header X-Real-IP;proxy_connect_timeout 300;# To support websockets in MinIO versions released after January 2023proxy_http_version 1.1;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";# Some environments may encounter CORS errors (Kubernetes + Nginx Ingress)# Uncomment the following line to set the Origin request to an empty string# proxy_set_header Origin '';chunked_transfer_encoding off;proxy_pass http://minio_console; # This uses the upstream directive definition to load balance}access_log /www/wwwlogs/minio.example.net.log;error_log /www/wwwlogs/minio.example.net;.error.log;}
django-minio-storage的完整配置:
MINIO_STORAGE_ENDPOINT = 'minio.example.net'DEFAULT_FILE_STORAGE = "minio_storage.storage.MinioMediaStorage"STATICFILES_STORAGE = "minio_storage.storage.MinioStaticStorage"MINIO_STORAGE_USE_HTTPS = FalseMINIO_STORAGE_ENDPOINT = os.getenv('MINIO_STORAGE_ENDPOINT')MINIO_STORAGE_ACCESS_KEY = os.getenv('MINIO_STORAGE_ACCESS_KEY')MINIO_STORAGE_SECRET_KEY = os.getenv('MINIO_STORAGE_SECRET_KEY')MINIO_STORAGE_MEDIA_OBJECT_METADATA = {"Cache-Control": "max-age=1000"}MINIO_STORAGE_MEDIA_BUCKET_NAME = 'data-process-engine-media'MINIO_STORAGE_MEDIA_BACKUP_BUCKET = 'data-process-engine-recycle-bin'MINIO_STORAGE_MEDIA_BACKUP_FORMAT = '%c/'MINIO_STORAGE_AUTO_CREATE_STATIC_BUCKET = TrueMINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET = TrueMINIO_STORAGE_STATIC_BUCKET_NAME = 'data-process-engine-static'
浙公网安备 33010602011771号