read-write-web / rww-play

read write web Play
59 stars 19 forks source link

Not able to use reverse proxy for SSL termination #153

Open reederz opened 9 years ago

reederz commented 9 years ago

Instead of exposing rww-play directly to the Internet, I want to use a reverse proxy for terminating SSL connections to rww-play. However, I'm not able to do that.

Starting rww-play:

run -Dhttp.port=8080 -Dhttps.port=8443 -Dhttps.trustStore=noCA -Dakka.loglevel=DEBUG -Dakka.debug.receive=on -Dhttp.hostname=christian.jolocom.com -Drww.root.container.path=jolocom-test-data/ldpc-christian

NGINX host config:

server {
        listen 443;
        server_name christian.jolocom.com;

        root html;
        index index.html index.htm;

        ssl on;
        ssl_certificate /etc/nginx/ssl/nginx.crt;
        ssl_certificate_key /etc/nginx/ssl/nginx.key;

        ssl_session_timeout 5m;

        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
        ssl_prefer_server_ciphers on;

        location / {
                proxy_pass         http://localhost:8080/;
                proxy_redirect     off;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
        }
}

Querying a resource through reverse proxy:

[  4:54PM ]  [ justas@choedankal:~ ]
 $ curl -i -k https://christian.jolocom.com/2013/people/justas     
HTTP/1.1 404 Not Found
Server: nginx/1.4.6 (Ubuntu)
Date: Mon, 27 Apr 2015 14:55:06 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 1076
Connection: keep-alive

could not find actor for Actor[akka://rww/user/rootContainer/people/justas/justas]rww.ldp.LDPExceptions$ResourceDoesNotExist: could not find actor for Actor[akka://rww/user/rootContainer/people/justas/justas]
    at rww.ldp.actor.RWWActorSystemImpl$$anonfun$3$$anon$1$$anonfun$receive$1.applyOrElse(RWWActorSystemImpl.scala:94)
    at akka.actor.Actor$class.aroundReceive(Actor.scala:465)
    at rww.ldp.actor.RWWActorSystemImpl$$anonfun$3$$anon$1.aroundReceive(RWWActorSystemImpl.scala:89)
    at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)
    at akka.actor.ActorCell.invoke(ActorCell.scala:487)
    at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:254)
    at akka.dispatch.Mailbox.run(Mailbox.scala:221)
    at akka.dispatch.Mailbox.exec(Mailbox.scala:231)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)

Querying the same resource directly:

[  5:02PM ]  [ justas@choedankal:~ ]
 $ curl -i -k https://christian.jolocom.com:8443/2013/people/justas
HTTP/1.1 200 OK
Accept-Patch: application/sparql-update
Accept-Post: application/rdf+xml,text/html,text/turtle,image/gif,image/png,text/html,application/javascript,image/jpeg,application/pdf
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: OPTIONS, GET, HEAD, SEARCH, PUT, DELETE, POST, PATCH
Access-Control-Allow-Origin: *
Content-Type: text/turtle
ETag: "1428361985000|Success(4096)"
Last-Modified: Mon, 06 Apr 2015 23:13:05 GMT
Link: <http://www.w3.org/ns/ldp#BasicContainer>; rel=type, <http://www.w3.org/ns/ldp#Resource>; rel=type, <.acl>; rel=acl
Content-Length: 1102

<https://christian.jolocom.com:8443/2013/people/justas/> <http://xmlns.com/foaf/0.1/maker> <https://my-profile.eu/people/reederz/card#me> ;
    a <http://www.w3.org/ns/ldp#BasicContainer> ;
    <http://www.w3.org/ns/ldp#contains> <https://christian.jolocom.com:8443/2013/people/justas/.acl> .

<https://christian.jolocom.com:8443/2013/people/justas/.acl> <http://www.w3.org/ns/posix/stat#mtime> 1428361985000 ;
    <http://www.w3.org/ns/posix/stat#size> 455 .

<https://christian.jolocom.com:8443/2013/people/justas/> <http://www.w3.org/ns/ldp#contains> <https://christian.jolocom.com:8443/2013/people/justas/card> .

<https://christian.jolocom.com:8443/2013/people/justas/card> <http://www.w3.org/ns/posix/stat#mtime> 1428361985000 ;
    <http://www.w3.org/ns/posix/stat#size> 698 .

<https://christian.jolocom.com:8443/2013/people/justas/> <http://www.w3.org/ns/ldp#contains> <https://christian.jolocom.com:8443/2013/people/justas/card.acl> .

<https://christian.jolocom.com:8443/2013/people/justas/card.acl> <http://www.w3.org/ns/posix/stat#mtime> 1428361985000 ;
    <http://www.w3.org/ns/posix/stat#size> 464 .

P.S. gold also has problems with this https://github.com/linkeddata/gold/issues/41

bblfish commented 9 years ago

I think with reverse proxies you'll have trouble with Authentication. Why do you need a reverse proxy?

reederz commented 9 years ago

I haven't tested authentication yet.

As for why- it's because @peacekeeper wants to package an LDP server on a freedombox. However, LDP server is only 1 of several http servers which are running on freedombox. To be able to share the same port (443), we need a reverse proxy. Other HTTP servers don't care if they are behind a proxy and it would be preferable if our LDP server didn't care either.

bblfish commented 9 years ago

I don't exactly know how reverse proxies function, but IF the SSL connection ends at the proxy then one has

  1. to develop a protocol and implement it to pass the certificate onto rww-play
  2. to avoid authenticating a client when it does not need it one would need either
    1. the reverse proxy to implement Web Access Control so that it knows when to request the proxy
    2. develop a protocol to send a message to the reverse proxy so that it can renegotiate the SSL session
    3. develop another WebID based authentication mechanism not based on SSL

Perhaps one should go the route of 2 (iii), as I assume Play does function with reverse proxies out of the box by now... But that will take a rewrite of the authentication layer.

Anyway that's assuming I got the initial point about reverse proxies right.

reederz commented 9 years ago

Yes, you got the initial point right- the SSL connection ends at the proxy, the proxy in turn forwards a normal HTTP request to the desired endpoint (rww-play).

And yes, Play already works with reverse proxies https://www.playframework.com/documentation/2.1.1/HTTPServer .

I don't see the best way to proceed solving this problem but 2(iii) seems like a reasonable option.

bblfish commented 8 years ago

Authentication will now work with remote proxies but will limit you to HTTP Signature for the moment. See https://github.com/solid/solid-spec/issues/52