全部產品
Search
文件中心

Object Storage Service:通過ECS反向 Proxy訪問OSS

更新時間:Oct 11, 2025

由於OSS通過DNS解析提供的IP地址是動態變化的,在需要配置防火牆白名單或進行特定系統整合時,可能會因IP不定導致訪問受限或失敗。為解決該問題,可在已綁定固定公網IP的ECS執行個體上部署Nginx反向 Proxy,通過將訪問請求轉寄至OSS,實現通過固定IP地址訪問OSS資源。

工作原理

該方案的核心是將一台或多台具有固定公網IP的ECS執行個體作為流量入口,利用Nginx作為反向 Proxy伺服器,將公網訪問請求轉寄至OSS。具體工作流程如下:

  1. 用戶端通過ECS執行個體的固定公網IP(EIP)發起對OSS資源的訪問請求。

  2. 部署在ECS執行個體上的Nginx服務接收並處理該請求。

  3. Nginx根據預設配置,將請求轉寄至目標OSS Bucket。

  4. OSS處理請求並返迴響應資料給Nginx。

  5. Nginx將響應資料通過公網返回給用戶端,完成整個代理過程。

配置ECS反向 Proxy

步驟一:建立ECS執行個體

ECS執行個體將作為反向 Proxy軟體Nginx的運行環境。

  1. 登入ECS控制台,單擊建立執行個體

  2. 按照下方配置要求建立ECS執行個體,其餘配置項可保持預設設定。

    • 付費類型:選擇隨用隨付

    • 地區:選擇待代理的OSS Bucket所在地區,以便使用內網網域名稱訪問,節約流量成本。

    • 網路及可用性區域:選擇預設的專用網路和可用性區域。

    • 執行個體:單擊全部規格,搜尋並選擇 ecs.e-c1m2.large

      說明

      如果執行個體規格已售罄,請選擇其它執行個體規格。

    • 鏡像:選擇公用鏡像Alibaba Cloud Linux(Alibaba Cloud Linux 3.2104 LTS 64位)。

    • 系統硬碟:設定ESSD Entry的容量為 40 GiB。

    • 公網IP:勾選分配公網 IPv4 地址

    • 頻寬計費模式:選擇按使用流量,以節約成本。

    • 頻寬峰值:選擇5 Mbps或以上。

    • 安全性群組:選擇建立安全性群組,並在開通IPv4連接埠/協議中勾選HTTP (TCP:80),開放Nginx監聽連接埠。

    • 登入憑證:選擇自訂密碼,登入名稱選擇root登入密碼請自行設定並妥善儲存。

步驟二:安裝和配置Nginx反向 Proxy

ECS執行個體建立完成後,需要在執行個體上安裝Nginx並配置反向 Proxy規則。

  1. 安裝Nginx服務。

    yum install -y nginx
  2. 建立並編輯設定檔。為便於管理,建議在/etc/nginx/conf.d/目錄下建立獨立的設定檔,例如oss_proxy.conf

    vi /etc/nginx/conf.d/oss_proxy.conf

    將以下生產級配置模板複製到設定檔中,並根據注釋說明修改Bucket內網網域名稱和ECS執行個體公網IP。

    # 定義OSS後端,並啟用長串連複用,提高效能
    upstream oss_backend {
        # 【必須修改】替換為Bucket內網網域名稱
        server your-bucket.oss-cn-hangzhou-internal.aliyuncs.com:80;
        # 建議的keepalive串連數,可根據並發量調整
        keepalive 64;
    }
    
    # 定義生產環境的日誌格式,包含上遊回應時間等關鍵資訊
    log_format production '$remote_addr - $remote_user [$time_local] "$request" '
                          '$status $body_bytes_sent "$http_referer" '
                          '"$http_user_agent" "$http_x_forwarded_for" '
                          'rt=$request_time uct="$upstream_connect_time" uht="$upstream_header_time" urt="$upstream_response_time"';
    
    server {
        listen 80;
        # 【必須修改】替換為ECS公網IP或解析到該IP的網域名稱
        server_name your_ecs_public_ip_or_domain;
    
        # 訪問日誌路徑和格式
        access_log /var/log/nginx/oss_proxy.access.log production;
        error_log /var/log/nginx/oss_proxy.error.log;
    
        # 動態DNS解析,確保Nginx能感知OSS後端IP變化
        resolver 100.100.2.136 100.100.2.138 valid=60s;
    
        # 健全狀態檢查端點,用於負載平衡或監控系統
        location /health {
            access_log off;
            return 200 "healthy";
        }
    
        location / {
            # 代理到上遊定義的OSS後端
            proxy_pass http://oss_backend;
    
            # 關鍵配置:確保HTTP/1.1協議和長串連生效
            proxy_http_version 1.1;
            proxy_set_header Connection "";
    
            # 關鍵配置:將Host頭設定為OSS的Bucket內網網域名稱,確保簽名驗證通過
            # 【必須修改】替換為Bucket內網網域名稱
            proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com";
    
            # 轉寄用戶端真實IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Real-IP $remote_addr;
    
            # 設定代理逾時時間
            proxy_connect_timeout 10s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
    
            # 允許上傳的最大檔案大小,0表示不限制。根據業務需求設定
            client_max_body_size 1024m;
        }
    }

    確認配置內容無誤後,儲存並退出編輯器。

  3. 檢查Nginx設定檔文法正確性。

    nginx -t

    如果顯示syntax is oktest is successful,表示配置文法正確。

  4. 啟動Nginx服務使配置生效。

    systemctl start nginx

驗證反向 Proxy效果

請根據Bucket的讀寫權限設定選擇相應的驗證方式。

公用讀取和公用讀寫Bucket

在瀏覽器中通過URL:http://ecs_public_ip/object_path訪問OSS中的對象檔案,其中ecs_public_ip為ECS執行個體的公網IP(可在ECS控制台擷取),object_path為檔案在Bucket內的訪問路徑。例如,檔案dest.jpg存放在Bucket的exampledir目錄下,則object_pathexampledir/dest.jpg。訪問效果如下圖所示:

image

私人Bucket

如果需要訪問的Bucket讀寫權限為私人,則需要在訪問檔案的URL中包含簽名資訊。以下操作示範如何通過控制台擷取檔案的簽名URL,關於簽名的詳細資料和產生方式請參見簽名版本4(推薦)

  1. 前往Bucket列表,單擊目標Bucket。

  2. 單擊需要訪問的目標檔案右側操作列的詳情

  3. 單擊複製檔案URL,將URL中的https替換為http,並將URL中的Bucket網域名稱替換為ECS執行個體的公網IP。

  4. 在瀏覽器中訪問修改後的URL。

image

應用於生產環境

在生產環境中使用此方案時,請遵循以下最佳實務,以確保服務的穩定性、安全性和成本效益。

最佳實務

  • 高可用架構:務必採用"負載平衡 + 多可用性區域ECS執行個體組"的生產架構設計,避免單點故障風險。

  • 啟用HTTPS:生產環境中應強制啟用HTTPS訪問以確保資料轉送安全。需要為Nginx配置SSL認證並設定HTTP到HTTPS的自動跳轉,具體配置方法如下所示。

    說明

    為確保HTTPS服務能夠正常訪問,ECS執行個體所屬的安全性群組必須開放443連接埠。具體配置方法,請參見添加/修改/刪除安全性群組規則

    # ... upstream 和 log_format 配置保持不變 ...
    
    # HTTP server塊:強制跳轉到HTTPS
    server {
        listen 80;
        # 【必須修改】替換為ECS公網IP或解析到該IP的網域名稱
        server_name your_ecs_public_ip_or_domain;
    
        # 將所有HTTP請求通過301重新導向到HTTPS
        return 301 https://$host$request_uri;
    }
    
    # HTTPS server塊:處理實際的代理業務
    server {
        # 在443連接埠上監聽SSL串連
        listen 443 ssl http2;
        # 【必須修改】替換為ECS公網IP或解析到該IP的網域名稱
        server_name your_ecs_public_ip_or_domain;
    
        # --- SSL認證配置 ---
        # 【必須修改】替換為你的SSL認證和私密金鑰檔案的路徑
        ssl_certificate /path/to/your/fullchain.pem;
        ssl_certificate_key /path/to/your/private.key;
    
        # --- SSL安全增強配置 ---
        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers 'TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384';
        ssl_prefer_server_ciphers on;
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;
    
        # 訪問日誌路徑和格式
        access_log /var/log/nginx/oss_proxy.access.log production;
        error_log /var/log/nginx/oss_proxy.error.log;
    
        # 動態DNS解析 (與原配置相同)
        resolver 100.100.2.136 100.100.2.138 valid=60s;
    
        # 健全狀態檢查端點 (與原配置相同)
        location /health {
            access_log off;
            return 200 "healthy";
        }
    
        location / {
            # ... 所有的 proxy_* 配置與原配置完全相同 ...
            proxy_pass http://oss_backend;
            proxy_http_version 1.1;
            proxy_set_header Connection "";
            # 【必須修改】替換為Bucket內網網域名稱
            proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com";
            proxy_set_header X-Forwarded-For $proxy_add_x_forw_for;
            proxy_set_header X-Real-IP $remote_addr;
            # 增加X-Forwarded-Proto頭,讓後端知道用戶端是通過HTTPS訪問的
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_connect_timeout 10s;
            proxy_send_timeout 30s;
            proxy_read_timeout 30s;
            client_max_body_size 1024m;
        }
    }
  • 配置代理緩衝區:對於大檔案下載或上傳情境,開啟併合理配置代理緩衝區,可以最佳化伺服器記憶體使用量,並避免因用戶端網路速度慢而長時間佔用與後端OSS的串連,從而提升整體服務效能。可在location塊中添加如下配置:

    location / {
        # ... 其他proxy_*配置 ...
    
        # 開啟代理緩衝,並設定緩衝區的數量和大小
        proxy_buffering on;
        proxy_buffers 8 128k;
        proxy_buffer_size 128k;
        proxy_busy_buffers_size 256k;
    }
  • 使用EIP:為代理叢集的入口(SLB或ECS)綁定Elastic IP Address(EIP),確保入口IP地址的穩定性。

  • 使用網域名稱訪問:建議佈建網域名解析到Proxy 伺服器IP,通過網域名稱而非IP地址提供服務,便於後續營運管理和擴充。

容錯策略

  • 健全狀態檢查:配置負載平衡器對Nginx的/health端點進行定期健全狀態檢查,自動隔離故障執行個體。

  • 逾時設定:合理配置Nginx的proxy_connect_timeoutproxy_read_timeout等逾時參數,避免因後端OSS響應延遲導致大量串連堆積。

  • 重試機制:如果用戶端應用支援,建議在應用程式層增加對5xx錯誤的重試邏輯。

風險防範

  • 安全強化:在ECS安全性群組和網路ACL中,僅對必要的IP地址和連接埠開放存取權限。考慮在代理前端部署Web Application Firewall(WAF)以抵禦常見Web攻擊。

  • 監控與警示:監控Nginx的訪問日誌和錯誤記錄檔,以及關鍵效能指標(如請求延遲、錯誤率、ECS的CPU/記憶體/網路使用率),並設定相應的警示閾值。

  • 變更與復原:對Nginx配置的任何變更都應經過充分測實驗證。保留歷史版本的設定檔,以便在出現問題時快速復原。

常見問題

如何通過瀏覽器預覽Bucket中的圖片或網頁檔案?

由於OSS的安全機制,通過預設網域名稱在瀏覽器中訪問OSS的圖片或網頁檔案時,檔案會被強制下載而非直接預覽。如果需要在瀏覽器中直接預覽Bucket中的圖片或網頁檔案,需要為Bucket綁定自訂網域名,並在Nginx配置中使用已綁定的自訂網域名。關於如何綁定自訂網域名,請參見通過自訂網域名訪問OSS

訪問私人Bucket中的檔案返回403 Forbidden錯誤,如何排查?

403錯誤通常與簽名驗證或許可權配置相關。請按以下步驟進行排查:

  1. 檢查Nginx配置:確保proxy_set_header Host指令設定的值與訪問的Bucket內網Endpoint完全一致。這是V4簽名驗證成功的關鍵要素。

  2. 檢查簽名產生:確認在產生簽名URL時,計算簽名所用的Host頭與Nginx配置中的Host頭保持一致。

  3. 檢查Bucket許可權:檢查Bucket Policy或RAM策略是否允許相應的操作許可權。

  4. 檢查ECS角色授權:如果應用通過ECS執行個體RAM角色訪問OSS,請確保該角色已被授予訪問目標Bucket的相應許可權。

上傳大檔案失敗,返回413 Request Entity Too Large錯誤,怎麼辦?

這是因為上傳的檔案大小超過了Nginx的預設限制。請在Nginx設定檔的serverlocation塊中,調整client_max_body_size的值。例如,設定client_max_body_size 2048m;允許上傳最大2GB的檔案。修改後需重載Nginx配置使其生效。

訪問偶爾失敗,Nginx日誌中出現502 Bad Gateway錯誤,是什麼原因?

502錯誤表示Nginx無法從後端(OSS)擷取有效響應。可能的原因包括:

  1. DNS解析問題:檢查Nginx配置中是否包含resolver指令。如果缺少該配置,Nginx可能仍在使用緩衝的舊IP地址訪問OSS。

  2. 網路連通性:檢查ECS執行個體的安全性群組出方向規則以及網路ACL設定,確保允許訪問目標地區OSS Endpoint的80連接埠。

  3. Endpoint配置錯誤:檢查proxy_passproxy_set_header Host中配置的OSS Endpoint是否拼字正確且有效。

如何通過一個Nginx執行個體代理多個不同的Bucket?

可以使用Nginx的map指令,根據請求的Host頭動態選擇要代理的後端Bucket。

# /etc/nginx/conf.d/multi_oss_proxy.conf

# 動態映射Host到OSS內網Endpoint
map $http_host $oss_backend_host {
    # 【必須修改】將 a.example.com 映射到 bucket-a 的內網Endpoint
    "a.example.com" "bucket-a.oss-cn-hangzhou-internal.aliyuncs.com";
    # 【必須修改】將 b.example.com 映射到 bucket-b 的內網Endpoint
    "b.example.com" "bucket-b.oss-cn-shenzhen-internal.aliyuncs.com";
    # 預設值,可不設定或指向一個預設Bucket
    default "";
}

server {
    listen 80;
    # 監聽多個網域名稱
    server_name a.example.com b.example.com;

    # ... 其他配置如日誌、resolver等 ...

    location / {
        # 如果映射結果為空白,則返回404
        if ($oss_backend_host = "") {
            return 404;
        }
        
        # 動態設定proxy_pass和Host頭
        proxy_pass http://$oss_backend_host;
        proxy_set_header Host $oss_backend_host;

        # ... 其他proxy_*配置 ...
    }
}