Hello.

My setup is as follows: I am running Debian on a VPS. I am using the reverse proxy pound, among other things, to provide SSL support for the webserver thttpd, which is serving the ikiwiki pages and running the ikiwiki CGI. The wiki is only accessible through https.

I recently upgraded from squeeze to wheezy. This broke page editing. It seems that the edit pages now include a base url that points to an http address, instead of the https address specified in the config. I guess this is a result of the changes discussed here:

http://ikiwiki.info/todo/want_to_avoid_ikiwiki_using_http_or_https_in_urls_to_allow_serving_both/

Because of the reverse proxy, I suppose that, as far as the webserver is concerned, it is receiving an http (rather than https) request. I don't think it's at all SSL-aware. So I don't think there's any way the webserver could tell the CGI that it's actually being accessed via https. (Feel free to correct me on this point if you are more knowledgeable about reverse proxies, HTTP and SSL. I see that, according to the Wikipedia page for thttpd, it doesn't pass on the X-Forwarded-For HTTP header to CGI scripts, but I don't see how that would be useful in detecting this anyhow.)

If ikiwiki's new behaviour is intentional, rather than a bug in ikiwiki or an error in my configuration, is there some option I can set or plugin I can enable to make it honour the URLs explicitly stated in my configuration? My current solution is to revert to the old version of ikiwiki from Debian Squeeze.

I see that a number of people have had vaguely similar problems from other bugs/forum posts. This person seems to be someone having the reverse problem, of the base URL being https instead of http:

http://ikiwiki.info/forum/CGI_script_and_HTTPS/

This person is also using a reverse proxy, and has problems with setting the base, but I think this is a feature request rather than a regression:

http://ikiwiki.info/bugs/trouble_with_base_in_search/

This one sounds most like my situation:

http://ikiwiki.info/forum/Dot_CGI_pointing_to_localhost._What_happened63/

There is a comment here that hints at a workaround. Am I right in reading this as a suggestion to patch the source? Is that the official recommended solution?

-- Martin.


From my .setup (domains changed):

    srcdir => '/home/myusername/wiki',
    # where to build the wiki
    destdir => '/var/www/secure.example.com/wiki',
    # base url to the wiki
    url => 'https://secure.example.com/wiki',
    # url to the ikiwiki.cgi
    cgiurl => 'https://secure.example.com/cgi-bin/wiki/ikiwiki.cgi',
    # filename of cgi wrapper to generate
    cgi_wrapper => '/var/www/secure.example.com/cgi-bin/wiki/ikiwiki.cgi',
    # mode for cgi_wrapper (can safely be made suid)
    cgi_wrappermode => '06755',

Old base in an edit page:

<base href="https://secure.example.com/wiki/" />

New base in an edit page, after upgrading ikiwiki package, but before regenerating wrapper:

<base href="http://localhost/wiki/" />

New base in an edit page, after regenerating wrapper:

<base href="http://secure.example.com/wiki/" />

One way to solve this would be a new $config{hard_code_urls} option whose semantics are "you're behind a reverse proxy, hard-code $config{cgiurl} and ${url} in output rather than using the address from the HTTP request" (in other words, selectively undo some of the automatic self-referential URL detection).

Another possibility would be to avoid using <base>, and when producing CGI pages, make all links look like /sandbox/ or /cgi-bin/ikiwiki.cgi?...; but that can only work if your content and CGI are on the same domain, and is likely to be more complex.

The <base href> is required to be an absolute URI (including the protocol and domain name) so the CGI output can't avoid doing a certain amount of hard-coding, unfortunately.

Comment by smcv Fri Dec 20 05:54:51 2013
I think the option to treat the URLs in the config as hard-coded (effectively ignoring the address from the HTTP request) would be most useful.
Comment by Martin Mon Dec 23 16:52:17 2013

Thank you for the analysis. I have worked around the issue by using the http://wiki.nginx.org/HttpSubModule, something like:

location {
    # Proxy stuff...
    sub_filter 'http://example.com' 'https://example.com';

}

Best regards, amc.

Comment by amcalvo Mon May 5 17:49:10 2014

A correction to the above comment, one needs activate multiple replacements:

        sub_filter 'http://example.com' 'https://example.com';
        sub_filter_once off;
Comment by amcalvo Mon May 5 17:56:36 2014

I got it working with Apache 2.4 and Virtual Hosts on both HTTP 1.1 and HTTPS (SNI). The procedure is somewhat analogous to the nginx procedure above. So here is my set-up in the hopes will help other avoid this pain.

Set-up

CLIENT <---- HTTPS ----> REVERSE PROXY <---- HTTP ----> IKIWIKI

The HTTP to HTTPS Redirect

To assure that all your HTTP requests are being redirected to HTTPS I chose to use mod_rewrite because simple Redirect does not pass query parameters. You will want an HTTP VHost that will redirect with something like the one below (notice the subtle ? before query string). Note: This will NOT re-write ikiwiki's http:// URLs (base tag, etc.). For that I use a content filter like you will see below. This HTTP to HTTPS redirect is required though for both security and for the /foo/?updated URI form in this set-up.


<VirtualHost *:80>
    ServerName imass.name
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}?%{QUERY_STRING}
    ErrorLog /var/log/imass.name-error.log
    LogLevel warn
    CustomLog /var/log/imass.name-access.log combined
</VirtualHost>

The SSL Virtual Host

This part is a bit more tricky. First I am using SNI as I don't care for non-SNI user agents. Second, you need to use a filter that replaces all http:// to https:// before the response is set. Note that this alone won't deal with ?update so you will need the HTTP to HTTPS set-up above anyway. Third, I use HTTP Auth so I don't know if this will work with your particular Auth set-up (although it should IMHO), YMMV:


<VirtualHost *:443>
    ServerName imass.name
    ProxyHTMLEnable On
    ProxyHTMLExtended On
    SSLEngine on
    SSLCertificateFile XXX
    SSLCertificateKeyFile XXX
    SSLCertificateChainFile XXX
    SSLOptions +StdEnvVars
    ProxyPreserveHost On
    ProxyHTMLURLMap http:// https://
    ProxyPass / http://192.168.101.101/
    ProxyPassReverse / http://192.168.101.101/
    LogLevel warn
    ErrorLog /var/log/imass.name-ssl-error.log
    TransferLog "/var/log/imass.name-ssl-access.log"
    CustomLog "/var/log/imass.name-ssl-request.log" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

Comment by Alejandro Wed Sep 10 14:58:24 2014

One way to solve this would be a new $config{hard_code_urls} option

I have added basically this in git master. It isn't in a release yet, and I renamed it to $config{reverse_proxy}.

Also in git master, if $config{html5} = 1 then the <base> URL will usually be host-relative or protocol-relative (/wiki/ or //example.com/wiki/) which reduces the need for that option.

These are still subject to change, for now.

Comment by smcv Sun Oct 5 18:54:06 2014