четверг, 15 ноября 2012 г.

Wicket, nginx, ssl, proxy

HI there !

This post has answer to question - "How to configure reverse proxy and tomcat for Wicket application". Wicket itself has declarative instructions, what pages should be secured, and what - not. This configured via appropriate annotation @RequireHttps on page class and application configuration , like this:

final HttpsConfig httpsConfig = new HttpsConfig(

             8080,8443
            );
final HttpsMapper httpsMapper = new HttpsMapper(getRootRequestMapper(), httpsConfig);

setRootRequestMapper(httpsMapper);

//to be correct need to use 80 and 443 ports for this article


How it works - in case if page with @RequireHttps annotation is openet via not secured port, wicket send http error code 302 with url, which point  to secure url for requested page. And vise versa if not secure page opening via secure url wicket redirect to unsecure version. This sophisticated behavior not always aligned with usual web application behavior, so to support it need correct configuration on ngnix, tomcat.

Configure nginx to be an reverse proxy for apache tomcat with ssl termination very simple and fast.

First step generate certificate and key
openssl req -new -x509 -days 2000 -nodes -out cert.pem -keyout cert.key

Second step configure nginx

server {

        listen 443;

        ssl on;
        ssl_session_timeout 5m;
        ssl_protocols  SSLv3 TLSv1;
    ssl_certificate /var/cert/cert.pem;
        ssl_certificate_key /var/cert/cert.key;
        #ssl_session_cache shared:SSL:10m; #Not works in win 7
        location / {
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
       proxy_set_header X-Forwarded-Proto https;
            proxy_redirect off;
            proxy_connect_timeout      240;
            proxy_send_timeout         240;
            proxy_read_timeout         240;
            # note, there is not SSL here! plain HTTP is used
            proxy_pass http://localhost:8080/;
        }
     }

    server {
        listen       80;
        server_name  localhost;

        location / {
       proxy_pass http://localhost:8080/;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

Be sure, than X-Forwarded-Proto present in your configuration in server record for 443 port

According to this configuration ssl will be terminated on ngnix and forwarded to unsecure port 8080 on tomcat, but wicket will perform check, described about and send redirect to secure url and loop will be created. To avoid redirect looping need add some configuration line to tomcat config



            unpackWARs="true" autoDeploy="true">
... skipped ...
...skipped ...

This valve analyse the X-Forwarded-Proto header, and it it set , in our case by nginx, valve set schema and secure flag in http request to https and true.