views:

670

answers:

2

I'm having a problem running Apache + Subversion with SSL behind an Nginx proxy and I'm hoping someone might have the answer. I've scoured google for hours looking for the answer to my problem and can't seem to figure it out. What I'm seeing are "502 (Bad Gateway)" errors when trying to MOVE or COPY using subversion; however, checkouts and commits work fine. Here are the relevant parts (I think) of the nginx and apache config files in question:

Nginx

upstream subversion_hosts {
    server 127.0.0.1:80;
}


server {
        listen       x.x.x.x:80;
        server_name  hostname;

        access_log   /srv/log/nginx/http.access_log main;
        error_log    /srv/log/nginx/http.error_log info;

        # redirect all requests to https
        rewrite ^/(.*)$ https://hostname/$1 redirect;
}

# HTTPS server
server {
        listen       x.x.x.x:443;
        server_name  hostname;

        passenger_enabled    on;
        root /path/to/rails/root;

        access_log   /srv/log/nginx/ssl.access_log main;
        error_log    /srv/log/nginx/ssl.error_log info;

        ssl                  on;
        ssl_certificate      server.crt;
        ssl_certificate_key  server.key;

        add_header Front-End-Https on;

        location /svn {
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                set $fixed_destination $http_destination;
                if ( $http_destination ~* ^https(.*)$ )
                {
                    set $fixed_destination http$1;
                }
                proxy_set_header Destination $fixed_destination;

                proxy_pass http://subversion_hosts;
        }
}

Apache

Listen 127.0.0.1:80
<VirtualHost *:80>
        # in order to support COPY and MOVE, etc -  over https (443),
        # ServerName _must_ be the same as the nginx servername
        # http://trac.edgewall.org/wiki/TracNginxRecipe
        ServerName hostname
        UseCanonicalName on

        <Location /svn>
                DAV svn
                SVNParentPath "/srv/svn"
                Order deny,allow
                Deny from all
                Satisfy any
                # Some config omitted ...
        </Location>

        ErrorLog /var/log/apache2/subversion_error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog /var/log/apache2/subversion_access.log combined
</VirtualHost>

From what I could tell while researching this problem, the server name has to match on both the apache server as well as the nginx server, which I've done. Additionally, this problem seems to stick around even if I change the configuration to use http only.

+1  A: 

I faced this exact problem today.

Adding the following in the apache2 configuration fixed it:

RequestHeader edit Destination ^https http early

Cheers,
  Ignace M


Source:

ghantoos
I had tried that in the past, but figured it was worth a shot again. Unfortunately for me, that did not do the trick.
steve.platz
A: 

I found out that the cause of my problem was not the proxy between nginx and apache, but rather was an issue with Apache itself.

What I didn't mention in the original question was what was in the # Some config omitted. This block contained the following:

AuthType Basic
AuthName "Redmine SVN Repository"
Require valid-user
PerlAccessHandler Apache::Authn::Redmine::access_handler
PerlAuthenHandler Apache::Authn::Redmine::authen_handler

For suberversion, I'm controlling user access using Redmine's authentication handler. After turning options on and off and narrowing down the problem, I learned that their authentication module is not thread-safe. I was running into the error because Apache was using the Worker MPM. Switching to the Prefork MPM (sudo aptitude install apache2-mpm-prefork in Ubuntu) resolved the issue.

steve.platz