Skip to content

Discourse und sekondäre Tor .onion services

Der Tor hidden service für unser discourse scheint schon ne zeit lang nicht mehr funktioniert zu haben, seit irgendnem Discourse upgrade schickt das ding jetzt Content-Security-Policy header mit die “brav” mit default-deny resources von diversen pfaden nur von https://meta.it-syndikat.org erlauben. Das problem dabei is halt das beim onion service die URL dann ne andere is… das kann nicht funktionieren.

Der erste versuch das zu fixen war mit ner “multisite” config, wo man im config file discourse secondary hostnames angeben kann die auch erlaubt sind. Dafür haben wir in der discourse VM im /var/discourse/containers/app.yml jetzt:

hooks:
  [...]
  # Allow onion hidden service hostname as secondary hostname. We need
  # this so discourse sets the right CSP for the onion site. --DXLD
  before_bundle_exec:
    - file:
        path: $home/config/multisite.yml
        contents: |
         mainsite:
           adapter: postgresql
           database: discourse
           pool: 5
           timeout: 5000
           host_names:
             - meta.it-syndikat.org
             - meta.itsyndikatgcsfuh.onion

Das heißt zwar “multi” site, wir definieren hier aber nur eine. Das scheint so OK zu sein. Damit bekommt man dann vom onion service mal die richtigen hostnamen im CSP, aber die URL kommt leider wegen dem discourse force_ssl setting mit https: scheme, was bei onion nicht passt.

Wenn man das setting abschaltet kommen aber wieder diverse URLs auf der https://meta.it-syndikat.org als http: raus was dem browser da dann natürlich auch wieder nicht passt.

Wir haben dann ewig im Discourse sourcecode gegraben, es scheint wirklich keine möglichkeit zu geben das in beiden fällen richtig hin zu bekommen. Das zu patchen wäre leider auch ein größeres refactoring. Der code verwendet in manchen fällen das conditional: SiteSetting.force_https? ? "https" : "http" (siehe `lib/discourse.rb), in diesem kontext scheint man aber einfach nicht immer ein request in der hand zu haben aus dem man sich das richtige scheme holen könnte weil der common code zb. auch zum asynchronen email generieren verwendet wird wo man garnicht wirklich ein request in der hand hat.

Die “lösung” war dann den CSP header im onion fall einfach wegzuhauen und https URLs im response body zu rewriten. Siehe das etckeeper commit:

commit fc1a465bcc0ee8eb47c336bee93341062683ba7e (HEAD -> master)
Author: root <root@yxorp.parabox.it-syndikat.org>
Date:   Fri Jan 15 16:53:44 2021 +0100

    Fix meta onion service
    
    The Content-Security-Policy header is wrong for on the onion site. We tried
    to use a multisite.yml config with multiple host_names to get the correct
    urls in the header, while that works we still get https instead of http since
    discourse's force_ssl logic can't allow for a different scheme depending on
    the host.
    
    Disabling force_ssl has it's own problems, namely that we'll get mixed content
    warnings on https instead.
    
    To "fix" this mess we enable force_ssl, and on onion:
    
     - ignore the CSP header and
     - rewrite https://meta.*.onion to http://meta.*.onion in the html response
       bodies.

diff --git a/nginx/sites-available/meta.itsyndikatgcsfuh.onion b/nginx/sites-available/meta.itsyndikatgcsfuh.onion
index 9cad63f..fcecd29 100644
--- a/nginx/sites-available/meta.itsyndikatgcsfuh.onion
+++ b/nginx/sites-available/meta.itsyndikatgcsfuh.onion
@@ -18,5 +18,11 @@ server {
         proxy_set_header X-Real-IP         fd50:7012:7012:7012:7012:7012:7012:7012;
         proxy_set_header X-Forwarded-For   fd50:7012:7012:7012:7012:7012:7012:7012;
         proxy_max_temp_file_size 0;
+
+        proxy_hide_header Content-Security-Policy;
+
+        sub_filter 'https://meta.itsyndikatgcsfuh.onion'  'http://meta.itsyndikatgcsfuh.onion';
+        sub_filter_once off;
+        sub_filter_types text/html;
     }
 }

Leider hab ich kein nginx modul gefunden mit dem man das search/replace auch im CPS header machen kann.

1 post - 1 participant

Read full topic