.well-known webfinger

The Basics

  • Nextcloud Server version (e.g., 29.x.x):
    • Nextcloud Hub 10 (31.0.0)
  • Operating system and version (e.g., Ubuntu 24.04):
    • Debian 12
  • Web server and version (e.g, Apache 2.4.25):
    • nginx/1.22.1
  • Reverse proxy and version _(e.g. nginx 1.27.2)
    • none
  • PHP version (e.g, 8.3):
    • 8.3
  • Is this the first time you’ve seen this error? (Yes / No):
    • Yes
  • When did this problem seem to first start?
    • after web installer completion
  • Installation method (e.g. AlO, NCP, Bare Metal/Archive, etc.)
    • web installer on webspace
  • Are you using CloudfIare, mod_security, or similar? (Yes / No)
    • No

Summary of the issue you are facing:

After installing Nextcloud via the web-installer for webservers (On ISPConfig 3.2) i’m getting the following warning:

  • Your web server is not properly set up to resolve .well-known URLs, failed on: /.well-known/webfinger For more details see the documentation :arrow_upper_right:.

Steps to replicate it (hint: details matter!):

  1. Creating ISPConfig 3.2 NGINX website
  2. Defining NGINX directives and PHP.ini overrides
  3. Installing via web installer
  4. Checking the admin overview
  5. discovered the warning

Log entries

Nextcloud

None logs that are regarding this issue available

Web Browser

Nothing related

Web server / Reverse Proxy

2025/03/13 10:58:14 [error] 203298#203298: *16 access forbidden by rule, client: REDUCTED-IP, server: next.domain.tld, request: "GET /data/.ncdata HTTP/1.1", host: "next.domain.tld"

2025/03/13 10:58:15 [error] 203300#203300: *27 access forbidden by rule, client: REDUCTED-IP, server: next.domain.tld, request: "GET /index.php/.well-known/webfinger HTTP/1.1", host: "next.domain.tld"

Configuration

Nextcloud

The output of occ config:list system or similar is best, but, if not possible, the contents of your config.php file from /path/to/nextcloud is fine (make sure to remove any identifiable information!):

{
    "system": {
        "instanceid": "***REMOVED SENSITIVE VALUE***",
        "passwordsalt": "***REMOVED SENSITIVE VALUE***",
        "secret": "***REMOVED SENSITIVE VALUE***",
        "trusted_domains": [
            "next.domain.tld"
        ],
        "datadirectory": "***REMOVED SENSITIVE VALUE***",
        "dbtype": "mysql",
        "version": "31.0.0.18",
        "overwrite.cli.url": "https:\/\/next.domain.tld",
        "dbname": "***REMOVED SENSITIVE VALUE***",
        "dbhost": "***REMOVED SENSITIVE VALUE***",
        "dbport": "",
        "dbtableprefix": "oc_",
        "mysql.utf8mb4": true,
        "dbuser": "***REMOVED SENSITIVE VALUE***",
        "dbpassword": "***REMOVED SENSITIVE VALUE***",
        "installed": true,
        "maintenance": false
    }
}

Apps

Enabled:
  - activity: 4.0.0
  - app_api: 5.0.2
  - bruteforcesettings: 4.0.0
  - circles: 31.0.0-dev.0
  - cloud_federation_api: 1.14.0
  - comments: 1.21.0
  - contactsinteraction: 1.12.0
  - dashboard: 7.11.0
  - dav: 1.33.0
  - federatedfilesharing: 1.21.0
  - federation: 1.21.0
  - files: 2.3.1
  - files_downloadlimit: 4.0.0
  - files_pdfviewer: 4.0.0
  - files_reminders: 1.4.0
  - files_sharing: 1.23.1
  - files_trashbin: 1.21.0
  - files_versions: 1.24.0
  - firstrunwizard: 4.0.0
  - logreader: 4.0.0
  - lookup_server_connector: 1.19.0
  - nextcloud_announcements: 3.0.0
  - notifications: 4.0.0
  - oauth2: 1.19.1
  - password_policy: 3.0.0
  - photos: 4.0.0-dev.1
  - privacy: 3.0.0
  - profile: 1.0.0
  - provisioning_api: 1.21.0
  - recommendations: 4.0.0
  - related_resources: 2.0.0
  - serverinfo: 3.0.0
  - settings: 1.14.0
  - sharebymail: 1.21.0
  - support: 3.0.0
  - survey_client: 3.0.0
  - systemtags: 1.21.1
  - text: 5.0.0
  - theming: 2.6.1
  - twofactor_backupcodes: 1.20.0
  - updatenotification: 1.21.0
  - user_status: 1.11.0
  - viewer: 4.0.0
  - weather_status: 1.11.0
  - webhook_listeners: 1.2.0
  - workflowengine: 2.13.0
Disabled:
  - admin_audit: 1.21.0
  - encryption: 2.19.0
  - files_external: 1.23.0
  - suspicious_login: 9.0.1
  - twofactor_nextcloud_notification: 5.0.0
  - twofactor_totp: 13.0.0-dev.0
  - user_ldap: 1.22.0

NGINX related configuration

location ~ \.php$ { ##delete##
}

location @php { ##delete##
}

# set max upload size
client_max_body_size 5G;
client_body_timeout 900s;
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/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;

# The settings allows you to optimize the HTTP2 bandwidth.
# See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/
# for tuning hints
client_body_buffer_size 512k;

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;

# Add .mjs as a file extension for javascript
# Either include it in the default mime.types list
# or include you can include that list explicitly and add the file extension
# only for Nextcloud like below:
include mime.types;

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;
}

# 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 /index.php$uri; }
    location = /.well-known/nodeinfo { return 301 /index.php$uri;  }    
    location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
    location /.well-known/pki-validation    { try_files $uri $uri/ =404; }

    # Let Nextcloud's API for `/.well-known` URIs handle all other
    # requests by passing them to the front-end controller.
    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(?:$|/) {
    rewrite ^\/(?!index|info|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy)\.php(?:$|\/) /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 HTTPS on;

    fastcgi_param modHeadersAvailable true;        # Avoid sending the security headers twice
    fastcgi_param front_controller_active true;    # Enable pretty urls
    {FASTCGIPASS}

    fastcgi_intercept_errors on;
    fastcgi_request_buffering off;

    fastcgi_max_temp_file_size 0;
}

# Serve static files
location ~ \.(?:css|js|mjs|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
    try_files $uri /index.php$request_uri;
    # HTTP response headers borrowed from Nextcloud `.htaccess`
    add_header Cache-Control                     "public, max-age=15778463$asset_immutable";
    add_header Referrer-Policy                   "no-referrer"       always;
    add_header X-Content-Type-Options            "nosniff"           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;
    access_log off;     # Optional: Don't log access to assets
}

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 / {
    try_files $uri $uri/ /index.php$request_uri;
}

php.ini Overrides

memory_limit = 1G
upload_max_filesize = 5G
post_max_size = 5G
max_execution_time = 3600
apc.enable_cli = 1
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.revalidate_freq = 60
opcache.interned_strings_buffer = 32
opcache.save_comments = 1
opcache.jit = 1255
opcache.jit_buffer_size = 128M
display_errors = Off
html_errors = Off

Additional information

When running:

curl -I https://next.domain.tld/.well-known/webfinger

The response is:

HTTP/2 302 
server: nginx/1.22.1
date: Thu, 13 Mar 2025 11:12:08 GMT
content-type: text/html
content-length: 145
location: https://next.domain.tld/index.php/.well-known/webfinger
referrer-policy: no-referrer
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-permitted-cross-domain-policies: none
x-robots-tag: noindex, nofollow
x-xss-protection: 1; mode=block

Following the new location:

curl -I https://next.domain.tld/index.php/.well-known/webfinger

returns in:

HTTP/2 403 
server: nginx/1.22.1
date: Thu, 13 Mar 2025 11:13:10 GMT
content-type: text/html
content-length: 153
referrer-policy: no-referrer
x-content-type-options: nosniff
x-download-options: noopen
x-frame-options: SAMEORIGIN
x-permitted-cross-domain-policies: none
x-robots-tag: noindex, nofollow
x-xss-protection: 1; mode=block

No one has any ideas? :frowning: