Synology DSM – Reverse Proxy (Part 2)

On my previous post Synology virtual sites for FileStation and others we could see how to create new sub domains under the main DNS name for your Synology to access the DSM applications like FileStation, Notes Station, and so on.

The configuration that is done creates a new full virtual site, on other words, all URL paths under the new sub domain are proxied to the redirected application. By other words, supposing that http://fs.domain.myds.me points to FileStation, all URL paths below to that URL are redirected to the FileStation site (for example http://fs.domain.myds.me/path1).

The following configuration is a bit different and it’s purpose is to redirect a URL path from the main site http://domain.myds.me to something else serving that path. For example, redirecting http://domain.myds.me/api to a backend Node.js REST server. The main reason to this is to allow Synology to host a site that uses, for example JQuery, or AngularJS, to also host the REST API that needs to be on the same domain due to the browser CORS protection. CORS protection means that a loading page from a site can only request data, by REST for example, from the origin web site. For example, my pages on http://domain.myds.me can call only REST services also on the same domain. It needs to be the same FQDN and PORT to the REST request be able to work. See more info at the Wikipedia page: Same-origin policy

And that’s because the above reason (CORS) that we need be able to proxy URL paths, and not full virtual sites, as the previous post as pointed out above.

To do this is quite simple, and the conditions are that the redirected path will be redirected from the main Synology user site.

So let’s redirect the path /api to a back end server:

Create a file named (for example) httpd-api-redirect.conf with the following content, replacing the backend_address and backend_port with the right information:

<Location /api>
  ProxyPass http://backend_address:backend_port/api
</Location>

Save this file at /etc/httpd/sites-enabled-user, and stop and restart the Apache server:

(Edit: In DSM 6.0 the path is /usr/local/etc/httpd/sites-enabled  )

To stop the Web Station: /sbin/initctl stop httpd-user
To start the Web Station:  /sbin/initctl start httpd-user

After that accessing http://domain.myds.me should work as usual, but http://domain.myds.me/api should be redirected to the backend server.

And that’s it, we can now host JQuery and/or Angular sites that use REST services hosted on the Synology Apache server.

There also some caveats regarding this configuration, if serving another site, not a REST api, like the full/relative paths issue with the proxied site, and also, regarding REST, the use of the Accept-origin header. But for the simplest purpose of hosting the site and the REST api under the same domain name, this works fine.

Advertisements

17 thoughts on “Synology DSM – Reverse Proxy (Part 2)

  1. Thanks for replying.
    Proxy modules are loading.
    My problem is that probably nginx server is intercepting the requests, and I get a 403 or 404 code.

    1. The “backend_address:backend_port/api ” means something like “192.168.1.104:5000/api” or the FQDN?
    2. I’m now trying to do the same thing but with fiddling with nginx configuration, as I suspect this is the problem.

    • Hummm, I also have nginx at the front-end doing the reverse proxy stuff that is standard now on DSM 6.0, and also this and it works fine so probably is not that. Nginx will redirect full sites while the above Apache configuration only redirect paths.

      The backend address and port is the server address and port where we want to redirect the URL path to, not the Synology address and port.

      So for example if I have a domain named ds.myds.me it shows my DSM web server home page, but ds.myds.me/backend is redirected to the backend server. I do not change the base URL or add new port. The rule only intercepts and redirects /backend to backend_address:backend_port/api to somewhere else.

      The above configuration will only work for redirecting url paths, not full sites.

  2. I’m sorry. I cannot understand it.

    I’m also trying to redirect only a url path ( http://fnt.synology.me/api ) to the backend path ( http://fnt.synology.me:5000 ).
    My reason is the same as yours : to overcome the Same Origin Policy.

    To explain my situation :
    I’m using the Synology Filestation API ( through an PHP application ) to access files directly on the DS .
    Till now I’ve managed with HTTP Requests to the Synology REST API, to Authenticate, List Share Folders, etc.
    But when I try to make an AJAX call through query (or plain JS) to the DS, in order to Download a file,I get back the
    ‘Origin “fnt.synology.me” is not allowed by Access-Control-Allow-Origin
    message.
    The same file is downloaded correctly if I use a direct HTTP GET request through PHP.

    I also tried to set some headers to Allow Cross Origin in httpd conf files ( and .htaccess file ) but with no success.

    Do you have something else to suggest?

    • So with a direct request to fnt.synology.me and fnt.synology.me/api it works? But through a web service caller it fails with the CORS error?

  3. No, this is not the case.
    Without any modification to any file, the AJAX call fails due different ports (5000 vs 80).
    My PHP application lives also in fnt.synology.me and is served through 80, BUT the Synology REST API should be called through port 5000 !
    This is the problem I’m trying to solve and google presented your page.

    Trying to follow your guide :
    After adding the following to /usr/local/etc/httpd/sites-enabled/api-redirect.conf

    ProxyPass http://fnt.synology.me:5000/api

    and restarting httpd via
    httpd -k restart (because /sbin/initctl stop httpd-user does not work with DSM 6.0)
    it does not work : http:/fnt.synology.me/api brings back 403.

    Sorry for asking too much, but I’m searching for a couple of days for a solution, without any success.

    • Ok, I was able to make it work, so:

      Not sure if your following my example, that is a bit generic 🙂 As it seems for DSM 6.0 the correct URL to access the API would be http:server_ip:5000//webapi/entry.cgi

      So the proxy pass command should be Proxypass http://internal_syno_ip:5000/webapi/entry.cgi

      1) So you must create a file named, for example synoapi-site.conf at the following directory: /usr/local/etc/httpd/sites-enabled/

      2) On that file, you put the Location tag and the Proxypass command as above

      3) Save the file

      4) Restart the Apache Server with the command: synoservice –reload pkgctl-WebStation

      5) Access the Syno Web site: http://fnt.synology.me

      6) Acess the redirected URL at: http://fnt.synology.me/api

      If it fails check the logs at /var/log/httpd, mainly the user-error.log file

      If it is still failing due to missing CORS header, you might need a proxy for the API like this: https://github.com/fcgdam/RestProxy

      Tell me how it goes 🙂

  4. It worked!
    Thank you!

    But afterwards I stumbled on another issue that I haven’t considered :
    AJAX requests cannot “download” files..

    So I didn’t use AJAX requests after all, just a window.open(“url”)

    Thanks anyway. I learned much from this.

  5. Looks like the latest synology update killed this capability.

    Now having such a .conf file in /usr/local/etc/httpd/sites-enabled/, the apache package cannot start emitting :

    service [pkgctl-Apache2.2] restart failed, synoerr=[0x2000]

    Removing the .conf file, apache starts again.

    I haven’t changed anything else.
    The contents are :

    ProxyPass http://192.168.1.104:5000/webapi/entry.cgi
    ProxyPassReverse http://192.168.1.104:5000/webapi/entry.cgi

    It used to work flawlessly before the update..

    Any thoughts?

    • OK. I managed to started it again by prepending the following as you are suggesting :

      ! IfModule !proxy_module
      LoadModule proxy_module modules/mod_proxy.so
      LoadModule proxy_connect_module modules/mod_proxy_connect.so
      LoadModule proxy_http_module modules/mod_proxy_http.so
      /IfModule

      apache did not load mod_proxy by default.
      From now on I’ll be more careful with synology updates.

      • The rewrite rule should be something like:

          location / 
          ProxyPass http://ds_name.myds.com/photo
          location
        

        Where ds_name.myds.com is your real address. Also make sure that the location tags are between the less and greater signal, not sure if the they get commented out on this reply.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s