nextcloud / social

🎉 Social can be used for work, or to connect to the fediverse!
https://apps.nextcloud.com/apps/social
GNU Affero General Public License v3.0
488 stars 59 forks source link

Cannot interact with others - UnauthorizedFediverseException #1810

Open sylvainmetayer opened 1 year ago

sylvainmetayer commented 1 year ago

Describe the bug Everytime an external service tries to communicate with Social the messages cannot be processed and result in a UnauthorizedFediverseException

When I dig into the SignatureService while debugging to find the cause, I find that the exception thrown is the SignatureException

https://github.com/nextcloud/social/blob/c8bf03bf3f68f4203f102ecbeb3b482443e11c16/lib/Service/SignatureService.php#L360

This is a bug already mentioned in https://github.com/nextcloud/social/issues/375 and https://github.com/nextcloud/social/issues/269

The origin of the distant server is correctly detected, but for an unknown reason, the signature verification fails https://github.com/nextcloud/social/blob/c8bf03bf3f68f4203f102ecbeb3b482443e11c16/lib/Service/SignatureService.php#L399

My setup is the following :

internet -> VPS -> nginx (443) -> nginx (linuxserver container on port 80) -> PHP

To Reproduce Steps to reproduce the behavior:

  1. Follow any account
  2. Wait for the server to ping back (in the /inbox endpoint)
  3. Check for SignatureException exception in the logs
  4. See error

Expected behavior

No SignatureException in the log.

You'll find in the details my nginx configuration, there is maybe an error with it, but I can't find it.

Client details:

Server details **Social app version:** 0.6.1 **Operating system**: Debian 11.7 **Web server:** nginx/1.18.0 **Database:** mysql Ver 15.1 Distrib 10.5.19-MariaDB, for debian-linux-gnu (x86_64) using EditLine wrapper **PHP version:** PHP 8.2.7 **Nextcloud version:** [Nextcloud Hub 5](https://nextcloud.com/) (27.0.0)
Logs #### Nextcloud log (data/nextcloud.log) ```json {"reqId":"zQnx9t9ps8FvFa8MqIEg","level":2,"time":"July 09, 2023 17:23:34","remoteAddr":"192.168.144.1","user":"--","app":"no app in context","method":"POST","url":"/index.phpal/inbox","message":"500 - {\"status\":-1,\"exception\":\"OCA\\\\Social\\\\Exceptions\\\\UnauthorizedFediverseException\",\"message\":\"Empty Origin\"}","userAgent":"http.rb/5.1.1 (Mastodon/4.1.4; +https://MASTODON_SERVER_URL/)","version":"27.0.0.8","data":[]} ``` #### Nginx configuration (443, with custom domain) ```nginx upstream nextcloud { server 127.0.0.1:9003; } server { listen 443 ssl http2; server_name NC_DOMAIN; root /var/www/default/; index index.php; client_max_body_size 1G; location = /robots.txt { access_log off; log_not_found off; } location = /favicon.ico { access_log off; log_not_found off; } # Deny access to .htaccess files, if Apache's document root concurs with nginx's one location /.ht { deny all; } # Deny access to hidden dotfiles (beginning with '.') location /. { deny all; } access_log /var/log/nginx/NC_DOMAIN.access.log combined; error_log /var/log/nginx/NC_DOMAIN.error.log; location / { include proxy_params; proxy_pass_request_headers on; proxy_pass http://nextcloud; } # Make a regex exception for `/.well-known` so that clients can still # access it despite the existence of the regex rule # `location ~ /(\.|autotest|...)` which would otherwise handle requests # for `/.well-known`. location ^~ /.well-known { # The rules in this block are an adaptation of the rules # in `.htaccess` that concern `/.well-known`. location = /.well-known/carddav { return 301 /remote.php/dav/; } location = /.well-known/caldav { return 301 /remote.php/dav/; } #location = /.well-known/webfinger { return 301 /public.php?service=webfinger; } location /.well-known/acme-challenge { try_files $uri $uri/ =404; } location /.well-known/pki-validation { try_files $uri $uri/ =404; } # Anything else is dynamically handled by Nextcloud location ^~ /.well-known { return 301 $scheme://$host/index.php$uri$is_args$args; } try_files $uri $uri/ =404; } # https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/ # Send cert validity information ourselves, so the user does not have to ask the CA (who # then knows the user visited the website). # Test with openssl s_client -connect www.example.com:443 -servername www.example.com -status < /dev/null | grep OCSP ssl_stapling on; ssl_stapling_verify on; resolver 1.1.1.1; # https://ssl-config.mozilla.org/#server=nginx&version=1.14.2&config=modern&openssl=1.1.1d&hsts=false&guideline=5.6 ssl_certificate /etc/letsencrypt/live/NC_DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/NC_DOMAIN/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/NC_DOMAIN/chain.pem; ssl_session_timeout 1d; ssl_session_cache shared:MozSSL:10m; # about 40000 sessions ssl_session_tickets off; # modern configuration ssl_protocols TLSv1.3; ssl_prefer_server_ciphers off; } server { listen 80; server_name NC_DOMAIN; return 301 https://$host$request_uri; } ``` #### Nginx configuration (from linux server container) ```nginx ## Version 2023/06/23 - Changelog: https://github.com/linuxserver/docker-nextcloud/commits/master/root/defaults/nginx/site-confs/default.conf.sample # Set the `immutable` cache control options only for assets with a cache busting `v` argument map $arg_v $asset_immutable { "" ""; default "immutable"; } server { listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name _; include /config/nginx/ssl.conf; root /app/www/public; # Add headers to serve security related headers # Before enabling Strict-Transport-Security headers please read into this # topic first. add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload;" always; # display real ip in nginx logs when connected through reverse proxy via docker network set_real_ip_from 172.16.0.0/12; real_ip_header X-Forwarded-For; # https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html#nextcloud-in-the-webroot-of-nginx # set max upload size and increase upload timeout: client_max_body_size 1G; client_body_timeout 300s; fastcgi_buffers 64 4K; # Enable gzip but do not remove ETag headers gzip on; gzip_vary on; gzip_comp_level 4; gzip_min_length 256; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; # Pagespeed is not supported by Nextcloud, so if your server is built # with the `ngx_pagespeed` module, uncomment this line to disable it. #pagespeed off; # The settings allows you to optimize the HTTP2 bandwitdth. # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/ # for tunning hints client_body_buffer_size 512k; # HTTP response headers borrowed from Nextcloud `.htaccess` add_header Referrer-Policy "no-referrer" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Download-Options "noopen" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Permitted-Cross-Domain-Policies "none" always; add_header X-Robots-Tag "noindex, nofollow" always; add_header X-XSS-Protection "1; mode=block" always; # Remove X-Powered-By, which is an information leak fastcgi_hide_header X-Powered-By; # Specify how to handle directories -- specifying `/index.php$request_uri` # here as the fallback means that Nginx always exhibits the desired behaviour # when a client requests a path that corresponds to a directory that exists # on the server. In particular, if that directory contains an index.php file, # that file is correctly served; if it doesn't, then the request is passed to # the front-end controller. This consistent behaviour means that we don't need # to specify custom rules for certain paths (e.g. images and other assets, # `/updater`, `/ocm-provider`, `/ocs-provider`), and thus # `try_files $uri $uri/ /index.php$request_uri` # always provides the desired behaviour. index index.php index.html /index.php$request_uri; # Rule borrowed from `.htaccess` to handle Microsoft DAV clients location = / { if ( $http_user_agent ~ ^DavClnt ) { return 302 /remote.php/webdav/$is_args$args; } } location = /robots.txt { allow all; log_not_found off; access_log off; } #rewrite ^/.well-known/webfinger /public.php?service=webfinger last; # Make a regex exception for `/.well-known` so that clients can still # access it despite the existence of the regex rule # `location ~ /(\.|autotest|...)` which would otherwise handle requests # for `/.well-known`. location ^~ /.well-known { # The rules in this block are an adaptation of the rules # in `.htaccess` that concern `/.well-known`. location = /.well-known/carddav { return 301 /remote.php/dav/; } location = /.well-known/caldav { return 301 /remote.php/dav/; } #location = /.well-known/webfinger { return 301 /public.php?service=webfinger; } location /.well-known/acme-challenge { try_files $uri $uri/ =404; } location /.well-known/pki-validation { try_files $uri $uri/ =404; } # Anything else is dynamically handled by Nextcloud location ^~ /.well-known { return 301 $scheme://$host/index.php$uri; } try_files $uri $uri/ =404; # return 301 /index.php$request_uri; } # Rules borrowed from `.htaccess` to hide certain paths from clients location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } # Ensure this block, which passes PHP files to the PHP process, is above the blocks # which handle static assets (as seen below). If this block is not declared first, # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` # to the URI, resulting in a HTTP 500 error response. location ~ \.php(?:$|/) { # Required for legacy support rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri; fastcgi_split_path_info ^(.+?\.php)(/.*)$; set $path_info $fastcgi_path_info; try_files $fastcgi_script_name =404; include /etc/nginx/fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_param PATH_INFO $path_info; fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice fastcgi_param front_controller_active true; # Enable pretty urls fastcgi_pass 127.0.0.1:9000; fastcgi_intercept_errors on; fastcgi_request_buffering off; fastcgi_max_temp_file_size 0; } location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ { try_files $uri /index.php$request_uri; add_header Cache-Control "public, max-age=15778463, $asset_immutable"; access_log off; # Optional: Don't log access to assets location ~ \.wasm$ { default_type application/wasm; } } location ~ \.woff2?$ { try_files $uri /index.php$request_uri; expires 7d; # Cache-Control policy borrowed from `.htaccess` access_log off; # Optional: Don't log access to assets } # Rule borrowed from `.htaccess` location /remote { return 301 /remote.php$request_uri; } location / { # enable for basic auth #auth_basic "Restricted"; #auth_basic_user_file /config/nginx/.htpasswd; try_files $uri $uri/ /index.php$request_uri; } # deny access to .htaccess/.htpasswd files location ~ /\.ht { deny all; } # https://help.nextcloud.com/t/warning-rainloop-data-folder-is-accessible/33033/2 location ^~ /apps/rainloop/app/data { deny all; } } ```