Welcome to Centmin Mod Community
Register Now

Nginx Build Hybrid or Multi-Cloud Applications with Access Controls

Discussion in 'Nginx and PHP-FPM news & discussions' started by eva2000, Jun 4, 2014.

  1. eva2000

    eva2000 Administrator Staff Member

    27,757
    6,335
    113
    May 24, 2014
    Brisbane, Australia
    Ratings:
    +9,336
    Local Time:
    8:38 PM
    Nginx 1.13.x
    MariaDB 5.5
    With the increased availability of dedicated cloud storage, such as Amazon S3, websites are moving assets to the cloud. The benefits are clear – near infinite scalability, usage-based costs and the simplicity of storage-as-a-service. This raises some important questions, such as how you apply access control for these assets when they are stored on one service while your application runs elsewhere – on a compute cloud or in a local, on-premise data center? Also, how do you mask the details of where the assets are stored from clients? NGINX allows you to separate your access control logic from your asset storage. Your access control application can perform the necessary authentication operations (check cookie, verify credentials, etc.) and has the necessary meta-data to instruct NGINX to either serve up a login or access denied form, or the requested resource. At all times, the resource is proxied by NGINX and the actual URL is never revealed to the client, so a devious user has no way of circumventing NGINX and accessing the resource directly. This idea can be applied to even more sophisticated use cases, such as when the assets are stored in a hybrid or multi-cloud architecture. Using multiple services allows companies to find the best price on data storage, lets them avoid vendor lock in and can also be used for disaster recovery. For example, some assets can stored in a local on-premise data center, being served directly by NGINX and with other assets being stored on multiple public or private cloud services. Below is an example where NGINX and the access control application are running in the local on-premise data center, with some assets stored locally and other assets being stored on three different cloud storage services: [​IMG] NGINX supports this functionality through the use of the X-Accel-Redirect response header. This header is set by an upstream server, functionality also sometimes known as XSendfile. The value set by the upstream server in the X-Accel-Redirect header provides the actual URL for the asset to be served by NGINX and causes an internal redirect, so that the asset served cannot be accessed directly by clients. To better understand how this works, let’s look at the request/response flow:

    1. The client makes a request to download a file. This request is received by NGINX and is passed to an upstream server containing the access control application.
    2. The upstream server checks to see if the user is logged in and has access to the resource being requested. If the user is not logged in or does not have access, then they are redirected to a login or access denied form.
    3. If the user is logged in and has access to the requested resource, then the internal URL of the resource will be set in the X-Accel-Redirect header.
    4. NGINX, using the URL from the X-Accel-Redirect header will do an internal redirect and serve the content, either locally or from a cloud server, discarding the actual response body returned by the access control server.

    This allows for a division of effort — NGINX performs the functions it is designed for, such as delivering static content and reverse proxy load balancing, and the application logic resides in the application freed from the details of delivering static content. This also allows for the URLs used by clients to be unrelated to the actual location of the resource. The content can therefore be moved from cloud to cloud without having to change the URLs used by clients or any reconfiguration of NGINX. The mapping of external URLs to the actual location of the resource is handled by the application. NGINX handles the redirect specified in the X-Accel-Header automatically, simplifying the NGINX configuration.

    Example Configurations

    Local Files


    Here is an NGINX configuration file snippet and PHP code for handling a simplified version of the use case discussed above, where the files are being served by NGINX locally. In this example, the client enters the URL path “/download/<file name>. NGINX directs this to “/download.php?path=<file name>” and the download.php program will set the X-Accel-Redirect header to “/files/<file name>” which will cause NGINX to do an internal redirect and serve the file “/var/www/<file name> from the “/files” location. To keep the example simple we have left out the authorization logic as well as the processing that would determine the internal URL to return. NGINX Configuration:

    server {
    listen 80;
    server_name www.example.com​

    location ~* ^/download/(.*) {
    proxy_pass http://127.0.0.1:8080/download.php?path=$1;
    }

    location /files {
    root /var/www;
    internal;
    }
    }​

    PHP Program:

    <?php
    # Get the file name
    $path = $_GET["path"];​

    # Do an internal redirect using the X-Accel-Redirect header
    header("X-Accel-Redirect: /files/$path");

    # PHP will default Content-Type to text/html.
    # If left blank, NGINX will set it correctly
    header('Content-Type:');
    ?>​

    Using this configuration, with the php program available at 127.0.0.1:8080, the file abc.jpg in the /var/www/files directory on the NGINX server and www.example.com mapped to the IP address of the NGINX server, if you were to enter “http://www.example.com /download/abc.jpg” you will see abc.jpg displayed in the browser and the URL will remain set to “http://www.example.com /download/abc.jpg” even though it was served at “/files/abc.jpg”.

    External Files


    Here is an NGINX configuration file snippet and PHP code for handling the use case where the resource will be retrieved from an external server, in this case from Amazon S3. In this example, the client still enters the URL path “/download/<file name>” and NGINX still directs this to “/download.php?path=<file name>”but the download.php program will set the X-Accel-Redirect header to “/internal_redirect/s3.amazonaws.com/nginx-data/<file name>” which will cause NGINX to do an internal redirect and proxy the request to the Amazon S3. Again, to keep the example simple we have left out the authorization logic as well as the processing that would determine the internal URL to return. NGINX Configuration:

    server {
    listen 80;
    server_name www.example.com;
    location ~* ^/download/(.*) {
    proxy_pass http://127.0.0.1:8080/download.php?path=$1;
    }

    location ~* ^/internal_redirect/(.*) {
    internal;
    resolver 8.8.8.8;
    proxy_pass http://$1;
    }
    }​

    PHP Program:

    <?php
    # Get the file name​

    $prefix = "s3.amazonaws.com/nginx-data/";
    $path = $_GET["path"];​

    # Do an internal redirect using the X-Accel-Redirect header
    header("X-Accel-Redirect: /internal_redirect/$prefix$path);​

    # PHP will default Content-Type to text/html.
    # If left blank, NGINX will set it correctly
    header('Content-Type:');
    ?>​

    Using this configuration, if you enter “http://www.example.com /download/30-banner” you will see the NGINX AMI banner page displayed in the browser. The URL will remain set to “http://www.example.com/download/30-banner” even though it was served from Amazon S3. In a real world use case, there would be logic added to the PHP program to make a decision about how NGINX should response to the client’s request and additional headers may need to be set by NGINX and the PHP program and additional NGINX directives may need to be used, but these examples have been simplified to show just the basics of what is required.

    Summary


    Using NGINX and the X-Accel-Redirect header gives you the flexibility of running NGINX and storing your files anywhere in different places and to easily grow and change your environment. This means that NGINX and your data can be stored in local data centers as well as public, private and hybrid cloud environments all while keeping your files secure and hiding the actual location of the resources from clients. As more and more companies move to utilize public, private and hybrid clouds, the need for this type of functionality will grow. Some additional examples of using the X-Accel-Redirect header with NGINX: Use Nginx to proxy files from remote location using X-Accel-Redirect Using X-Accel-Redirect in Nginx to Implement Controlled Downloads X-Accel-Redirect From Remote Servers Nginx Fast Private File Transfer for Drupal using X-Accel-Redirect For more information on NGINX: NGINX documentation NGINX and NGINX Plus features NGINX Plus Technical Specifications

    The post Build Hybrid or Multi-Cloud Applications with Access Controls appeared first on NGINX.

    Continue reading...