All Products
Search
Document Center

Object Storage Service:Access OSS through an ECS reverse proxy

Last Updated:Oct 10, 2025

Because the IP addresses for Object Storage Service (OSS) provided through DNS resolution are dynamic, you may encounter access restrictions or failures when you configure firewall whitelists or perform specific system integrations. To resolve this issue, you can deploy an Nginx reverse proxy on an Elastic Compute Service (ECS) instance that has a static public IP address. The proxy forwards access requests to OSS, which lets you access OSS resources using a static IP address.

How it works

This solution uses one or more ECS instances with static public IP addresses as traffic ingresses. Nginx runs as a reverse proxy server on these instances and forwards public access requests to OSS. The workflow is as follows:

  1. A client initiates a request to access an OSS resource through the static public IP address (EIP) of the ECS instance.

  2. The Nginx service on the ECS instance receives and processes the request.

  3. Based on its configuration, Nginx forwards the request to the target OSS bucket.

  4. OSS processes the request and returns the response data to Nginx.

  5. Nginx sends the response data back to the client over the Internet, completing the proxy process.

image

Configure the ECS reverse proxy

Step 1: Create an ECS instance

The ECS instance serves as the runtime environment for the Nginx reverse proxy software.

  1. Log on to the ECS console and click Create Instance.

  2. Create an ECS instance with the following configurations. You can use the default settings for other parameters.

    • Billing Method: Select Pay-As-You-Go.

    • Region: Select the region where the OSS bucket that you want to proxy is located. This lets you use an internal endpoint to save traffic costs.

    • Network and Zone: Select the default virtual private cloud (VPC) and zone.

    • Instance: Click All Instance Types, and then search for and select ecs.e-c1m2.large.

      Note

      If this instance type is sold out, select another instance type.

    • Image: Select Public Image and then select Alibaba Cloud Linux (Alibaba Cloud Linux 3.2104 LTS 64-bit).

    • System Disk: Set the capacity of the ESSD Entry disk to 40 GiB.

    • Public IP Address: Select Assign Public IPv4 Address.

    • Bandwidth Billing Method: Select Pay-By-Traffic to save costs.

    • Bandwidth: Select 5 Mbps or higher.

    • Security Group: Select New Security Group. In the Open IPv4 Ports/Protocols section, select HTTP (TCP: 80) to open the Nginx listener port.

    • Logon Credentials: Select Custom Password. Set the logon name to root. Set and save the Logon Password.

Step 2: Install and configure the Nginx reverse proxy

After you create the ECS instance, install Nginx and configure reverse proxy rules on the instance.

  1. Install the Nginx service.

    yum install -y nginx
  2. Create and edit the configuration file. For easier management, create a separate configuration file, such as oss_proxy.conf, in the /etc/nginx/conf.d/ directory.

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

    Copy the following production-grade configuration template to the configuration file. Then, modify the internal endpoint of the bucket and the public IP address of the ECS instance based on the comments in the template.

    # Define the OSS backend and enable persistent connections to improve performance. upstream oss_backend { # [Required] Replace with the internal endpoint of the bucket. server your-bucket.oss-cn-hangzhou-internal.aliyuncs.com:80; # Recommended number of keepalive connections. Adjust this value based on the number of concurrent connections. keepalive 64; } # Define the log format for the production environment. This format includes key information such as the upstream response time. 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; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to this IP address. server_name your_ecs_public_ip_or_domain; # Access log path and format. access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # Dynamic DNS resolution. This ensures that Nginx is aware of changes to the IP address of the OSS backend. resolver 100.100.2.136 100.100.2.138 valid=60s; # Health check endpoint for Server Load Balancer or monitoring systems. location /health { access_log off; return 200 "healthy"; } location / { # Proxy requests to the upstream OSS backend. proxy_pass http://oss_backend; # Key configuration: Ensure that HTTP/1.1 and persistent connections are enabled. proxy_http_version 1.1; proxy_set_header Connection ""; # Key configuration: Set the Host header to the internal endpoint of the OSS bucket to ensure that signature verification is passed. # [Required] Replace with the internal endpoint of the bucket. proxy_set_header Host "your-bucket.oss-cn-hangzhou-internal.aliyuncs.com"; # Forward the real IP address of the client. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Real-IP $remote_addr; # Set proxy timeout periods. proxy_connect_timeout 10s; proxy_send_timeout 30s; proxy_read_timeout 30s; # The maximum size of a file that can be uploaded. A value of 0 indicates no limit. Set this parameter as needed. client_max_body_size 1024m; } }

    After you confirm that the configuration is correct, save the file and exit the editor.

  3. Check the syntax of the Nginx configuration file.

    nginx -t

    If syntax is ok and test is successful are displayed, the configuration syntax is correct.

  4. Start the Nginx service to apply the configuration.

    systemctl start nginx

Verify the reverse proxy

Select a verification method based on the access permissions of your bucket.

Public-read and public-read-write buckets

In a browser, access the object in OSS using the URL http://ecs_public_ip/object_path. Replace ecs_public_ip with the public IP address of your ECS instance, which you can obtain from the ECS console. Replace object_path with the access path of the object in the bucket. For example, if the file dest.jpg is stored in the exampledir directory of the bucket, the object_path is exampledir/dest.jpg. The following figure shows a successful access attempt:

image

Private buckets

If the bucket you want to access is private, the access URL must include signature information. The following steps describe how to obtain a signed URL for a file from the console. For more information about signatures and how to generate them, see Signature Version 4 (Recommended).

  1. Go to the Buckets page and click the target bucket.

  2. In the row of the file that you want to access, click Details in the Actions column.

  3. Click Copy File URL. In the URL, replace https with http and replace the domain name of the bucket with the public IP address of your ECS instance.

  4. Access the modified URL in a browser.

image

Apply in a production environment

When you use this solution in a production environment, follow these best practices to ensure service stability, security, and cost-effectiveness.

Best practices

  • High-availability architecture: Use a production architecture of 'Server Load Balancer + ECS instances in a multi-zone deployment' to prevent single points of failure.

  • Enable HTTPS: In a production environment, enforce HTTPS access to ensure data transmission security. You must configure an SSL certificate for Nginx and set up automatic redirection from HTTP to HTTPS. The following code shows the configuration method.

    Note

    To ensure that the HTTPS service can be accessed, you must open port 443 in the security group to which the ECS instance belongs. For more information about how to configure the port, see Add, modify, or delete security group rules.

    # ... The upstream and log_format configurations remain unchanged ... # HTTP server block: Force a redirect to HTTPS. server { listen 80; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to this IP address. server_name your_ecs_public_ip_or_domain; # Redirect all HTTP requests to HTTPS using an HTTP 301 status code. return 301 https://$host$request_uri; } # HTTPS server block: Handle the actual proxy service. server { # Listen for SSL connections on port 443. listen 443 ssl http2; # [Required] Replace with the public IP address of the ECS instance or a domain name that resolves to this IP address. server_name your_ecs_public_ip_or_domain; # --- SSL certificate configuration --- # [Required] Replace with the paths to your SSL certificate and private key files. ssl_certificate /path/to/your/fullchain.pem; ssl_certificate_key /path/to/your/private.key; # --- SSL security hardening configuration --- 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 path and format. access_log /var/log/nginx/oss_proxy.access.log production; error_log /var/log/nginx/oss_proxy.error.log; # Dynamic DNS resolution (same as the original configuration). resolver 100.100.2.136 100.100.2.138 valid=60s; # Health check endpoint (same as the original configuration). location /health { access_log off; return 200 "healthy"; } location / { # ... All proxy_* configurations are the same as the original configuration ... proxy_pass http://oss_backend; proxy_http_version 1.1; proxy_set_header Connection ""; # [Required] Replace with the internal endpoint of the 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; # Add the X-Forwarded-Proto header to inform the backend that the client is accessing the service over 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; } }
  • Configure proxy buffers: For scenarios that involve downloading or uploading large files, enable and properly configure proxy buffers. This can optimize server memory usage and prevent slow clients from occupying connections to the backend OSS for extended periods, which improves overall service performance. You can add the following configuration in the `location` block:

    location / { # ... Other proxy_* configurations ... # Enable proxy buffering and set the number and size of buffers. proxy_buffering on; proxy_buffers 8 128k; proxy_buffer_size 128k; proxy_busy_buffers_size 256k; }
  • Use EIPs: Associate an elastic IP address (EIP) with the ingress of your proxy cluster (an SLB instance or an ECS instance) to ensure a stable IP address for the ingress.

  • Use a domain name for access: Configure domain name resolution to point to the IP address of the proxy server. Provide the service using the domain name instead of the IP address. This simplifies future operations management and scaling.

Fault tolerance strategies

  • Health checks: Configure Server Load Balancer to perform regular health checks on the /health endpoint of Nginx to automatically isolate faulty instances.

  • Timeout settings: Properly configure Nginx timeout parameters, such as proxy_connect_timeout and proxy_read_timeout, to prevent many stacked connections caused by response latency from the backend OSS.

  • Retry mechanism: If your client application supports retries, add retry logic for 5xx errors at the application layer.

Risk prevention

  • Security hardening: In the security group and network ACL of the ECS instance, grant access permissions only to the required IP addresses and ports. Consider deploying a Web Application Firewall (WAF) at the frontend of the proxy to defend against common web attacks.

  • Monitoring and alerting: Monitor the access logs and error logs of Nginx, and key performance metrics, such as request latency, error rate, and the CPU, memory, and network usage of the ECS instance. Set alert thresholds for these metrics as needed.

  • Change and rollback management: Thoroughly test and verify any changes to the Nginx configuration. Keep historical versions of the configuration files to allow for quick rollbacks if issues occur.

FAQ

How can I preview images or web files from a bucket in a browser?

Due to the security mechanism of OSS, when you access images or web files in OSS from a browser using the default domain name, the files are forcibly downloaded instead of being previewed. To preview these files directly in a browser, you must map a custom domain name to the bucket and use the mapped custom domain name in the Nginx configuration. For more information about how to map a custom domain name, see Access OSS over a custom domain name.

How do I troubleshoot a 403 Forbidden error that is returned when I access a private bucket?

A 403 error is usually related to signature verification or permission configurations. You can troubleshoot the error as follows:

  1. Check the Nginx configuration: Ensure that the value of the proxy_set_header Host directive exactly matches the internal endpoint of the bucket that you want to access. This is a key factor for successful V4 signature verification.

  2. Check signature generation: Confirm that the Host header used to calculate the signature for the signed URL is the same as the Host header in the Nginx configuration.

  3. Check bucket permissions: Check whether the bucket policy or RAM policy grants the required permissions.

  4. Check ECS role authorization: If the application accesses OSS using an instance RAM role, make sure the role is granted the required permissions to access the target bucket.

What do I do if a large file fails to upload and a 413 Request Entity Too Large error is returned?

This error occurs because the size of the uploaded file exceeds the default limit of Nginx. In the Nginx configuration file, adjust the value of client_max_body_size in the server or location block. For example, set client_max_body_size 2048m; to allow files up to 2 GB to be uploaded. After you modify the configuration, reload the Nginx configuration to make the change take effect.

Why does access occasionally fail and a 502 Bad Gateway error appear in the Nginx logs?

A 502 error indicates that Nginx cannot obtain a valid response from the backend (OSS). Possible causes include the following:

  1. DNS resolution issue: Check whether the resolver directive is included in the Nginx configuration. If this directive is missing, Nginx may still use a cached old IP address to access OSS.

  2. Network connectivity: Check the outbound rules of the security group and the network ACL settings of the ECS instance to ensure that access to port 80 of the OSS endpoint in the destination region is allowed.

  3. Endpoint configuration error: Check whether the OSS endpoint configured in proxy_pass and proxy_set_header Host is spelled correctly and is valid.

How can I use a single Nginx instance to proxy multiple different buckets?

You can use the map directive of Nginx to dynamically select a backend bucket to proxy based on the Host header of the request.

# /etc/nginx/conf.d/multi_oss_proxy.conf # Dynamically map the Host header to the internal endpoint of an OSS bucket. map $http_host $oss_backend_host { # [Required] Map a.example.com to the internal endpoint of bucket-a. "a.example.com" "bucket-a.oss-cn-hangzhou-internal.aliyuncs.com"; # [Required] Map b.example.com to the internal endpoint of bucket-b. "b.example.com" "bucket-b.oss-cn-shenzhen-internal.aliyuncs.com"; # Default value. You can leave this parameter empty or set it to a default bucket. default ""; } server { listen 80; # Listen on multiple domain names. server_name a.example.com b.example.com; # ... Other configurations, such as logs and resolver ... location / { # If the mapping result is empty, a 404 error is returned. if ($oss_backend_host = "") { return 404; } # Dynamically set the proxy_pass and Host headers. proxy_pass http://$oss_backend_host; proxy_set_header Host $oss_backend_host; # ... Other proxy_* configurations ... } }