#54 How to configure x-static-delivery? Getting 404 on thumbnails

Open
opened 4 years ago by postblue · 9 comments

I'm using the latest master branch with NGINX and PHP-FPM. I tried to configure x-static-delivery, so I added the following in my configuration file:

$config['site']['x-static-delivery'] = 'X-Accel-Redirect';

After that I ran the checkschema.php script, then modified my NGINX configuration, adding the following:

location /file {
    internal; 
    root /var/www/social/;
}

The file/ (should it better be in public/?) folder's location is /var/www/social/file/ and so is it configured in the panel/paths administration page.

But I'm getting 404 on every thumbnail. Can you please elaborate the documentation on how to enable this feature? Thank you.

I'm using the latest ```master``` branch with NGINX and PHP-FPM. I tried to configure x-static-delivery, so I added the following in my configuration file: ```php $config['site']['x-static-delivery'] = 'X-Accel-Redirect'; ``` After that I ran the ```checkschema.php``` script, then modified my NGINX configuration, adding the following: ```nginx location /file { internal; root /var/www/social/; } ``` The ```file/``` (should it better be in ```public/```?) folder's location is ```/var/www/social/file/``` and so is it configured in the ```panel/paths``` administration page. But I'm getting 404 on every thumbnail. Can you please elaborate the documentation on how to enable this feature? Thank you.

That's rather interesting. As far as I can tell, that config seems correct. What commit are you on? Do you have any log messages? Is the nginx config block above other blocks? Maybe some regex is conflicting (specifically the location / block).

That's rather interesting. As far as I can tell, that config seems correct. What commit are you on? Do you have any log messages? Is the nginx config block _above_ other blocks? Maybe some regex is conflicting (specifically the `location /` block).
Guillaume commented 4 years ago
Poster

I am using commit 0bb35d7e7f. I enabled the access_log and error_log in my NGINX config and got this:

2019-08-16 08:36:34 LOG_ERR: [herds.eu:13965.a144484a GET /file/thumb/thumb-...] Exception thrown: 'Page not found.'

The NGINX block is weel above the other blocks, I copied the DOCUMENTATION/SYSTEM_ADMINISTRATORS/webserver_conf/nginx.conf.sample and made this:

server {
    listen [::]:80;
    listen 80;
    server_name herds.eu;
    rewrite ^ https://$host$request_uri? permanent;
}

server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;

    root /var/www/social/public;
    server_name herds.eu;

    ssl_certificate       /etc/letsencrypt/live/herds.eu/fullchain.pem;
    ssl_certificate_key   /etc/letsencrypt/live/herds.eu/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/herds.eu/chain.pem;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    ssl_ecdh_curve secp384r1;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "TLS13+AESGCM+AES128:EECDH+AESGCM:EECDH+CHACHA20";
    ssl_session_timeout  10m;
    ssl_session_cache shared:SSL:10m;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 9.9.9.9 149.112.112.112 valid=300s;
    resolver_timeout 5s;

    # Index
    index index.php;

    # X-Accel/X-Sendfile. Still needs to be enabled in the config
    location /file {
        internal;
        # Moved the /file folder in /public and
        # changed the path in config
        root /var/www/social/public;
    }

    # PHP
    #location ~ ^/(index|install)\.php(/.*)?$ {
    location ^~ /index.php {
        include fastcgi_params;
        include snippets/fastcgi-php.conf;

        fastcgi_pass unix:/run/php/social.sock;
        fastcgi_param SCRIPT_FILENAME $request_filename;
    }

    # Don't allow any PHP file other than index.php to be executed
    location ~ \.php$ {
        deny all;
    }

    # Location
    location / {
        try_files $uri $uri/ @index_handler;
    }

    # Fancy URLs
    error_page 404 @index_handler;
    location @index_handler {
        rewrite ^(.*)$ /index.php?p=$1 last;
    }

    # Restrict access that is unnecessary anyway
    location ~ /\.(ht|git) {
        deny all;
    }

    # Hardening (optional)
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload;";
    add_header X-Content-Type-Options nosniff;
    add_header Referrer-Policy strict-origin-when-cross-origin;
    # add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:;";
    add_header X-Permitted-Cross-Domain-Policies none;
    add_header X-Robots-Tag all; # Not really hardening, just here for strictness purposes
    add_header X-XSS-Protection "1; mode=block";
    add_header X-Frame-Options SAMEORIGIN;

    client_max_body_size 15M;
    client_body_buffer_size 128k;
    gzip_vary on;

    location ~* \.(?:css|js|woff|svg|gif|png|webp|ttf|ico|jpe?g)$ {
        gzip on;
        gzip_comp_level 4;
        add_header Cache-Control "public";
        expires 30d;
        access_log off;
        log_not_found off;
    }

    location ~ /(keybase|pgpkey).txt {
        root /var/www/social/public;
        add_header Cache-Control "public";
        add_header Content-Type text/plain;
        access_log off;
        log_not_found off;
    }
}

Here's also my PHP-FPM block:

[social]

user = www-data
group = www-data

listen = /run/php/social.sock
listen.owner = www-data
listen.group = www-data
listen.allowed_clients = 127.0.0.1

pm = ondemand
pm.max_children = 35
pm.status_path = /status

chdir = /var/www/social

php_value[upload_max_filesize] = 64M
php_value[post_max_size] = 64M
php_value[memory_limit] = 512M
php_value[upload_tmp_dir] = "/tmp"

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/local/bin:/usr/bin:/bin
env[TMP] = /tmp
env[TMPDIR] = /tmp
env[TEMP] = /tmp

php_value[opcache.enable] = 1
php_value[opcache.enable_cli] = 1
php_value[opcache.file_cache] = "/var/www/opcache"
php_value[opcache.interned_strings_buffer] = 8
php_value[opcache.max_accelerated_files] = 10000
php_value[opcache.memory_consumption] = 128
php_value[opcache.save_comments] = 1
php_value[opcache.revalidate_freq] = 1
php_value[mysqli.allow_persistent] = On
php_value[mysqli.reconnect] = On
I am using commit 0bb35d7e7f2cc373de4c5eababc7546e1852e4e2. I enabled the access_log and error_log in my NGINX config and got this: ``` 2019-08-16 08:36:34 LOG_ERR: [herds.eu:13965.a144484a GET /file/thumb/thumb-...] Exception thrown: 'Page not found.' ``` The NGINX block is weel above the other blocks, I copied the DOCUMENTATION/SYSTEM_ADMINISTRATORS/webserver_conf/nginx.conf.sample and made this: ```nginx server { listen [::]:80; listen 80; server_name herds.eu; rewrite ^ https://$host$request_uri? permanent; } server { listen [::]:443 ssl http2; listen 443 ssl http2; root /var/www/social/public; server_name herds.eu; ssl_certificate /etc/letsencrypt/live/herds.eu/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/herds.eu/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/herds.eu/chain.pem; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; ssl_ecdh_curve secp384r1; ssl_session_tickets off; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers "TLS13+AESGCM+AES128:EECDH+AESGCM:EECDH+CHACHA20"; ssl_session_timeout 10m; ssl_session_cache shared:SSL:10m; ssl_stapling on; ssl_stapling_verify on; resolver 9.9.9.9 149.112.112.112 valid=300s; resolver_timeout 5s; # Index index index.php; # X-Accel/X-Sendfile. Still needs to be enabled in the config location /file { internal; # Moved the /file folder in /public and # changed the path in config root /var/www/social/public; } # PHP #location ~ ^/(index|install)\.php(/.*)?$ { location ^~ /index.php { include fastcgi_params; include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/social.sock; fastcgi_param SCRIPT_FILENAME $request_filename; } # Don't allow any PHP file other than index.php to be executed location ~ \.php$ { deny all; } # Location location / { try_files $uri $uri/ @index_handler; } # Fancy URLs error_page 404 @index_handler; location @index_handler { rewrite ^(.*)$ /index.php?p=$1 last; } # Restrict access that is unnecessary anyway location ~ /\.(ht|git) { deny all; } # Hardening (optional) add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload;"; add_header X-Content-Type-Options nosniff; add_header Referrer-Policy strict-origin-when-cross-origin; # add_header Content-Security-Policy "default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:;"; add_header X-Permitted-Cross-Domain-Policies none; add_header X-Robots-Tag all; # Not really hardening, just here for strictness purposes add_header X-XSS-Protection "1; mode=block"; add_header X-Frame-Options SAMEORIGIN; client_max_body_size 15M; client_body_buffer_size 128k; gzip_vary on; location ~* \.(?:css|js|woff|svg|gif|png|webp|ttf|ico|jpe?g)$ { gzip on; gzip_comp_level 4; add_header Cache-Control "public"; expires 30d; access_log off; log_not_found off; } location ~ /(keybase|pgpkey).txt { root /var/www/social/public; add_header Cache-Control "public"; add_header Content-Type text/plain; access_log off; log_not_found off; } } ``` Here's also my PHP-FPM block: ```php-fpm [social] user = www-data group = www-data listen = /run/php/social.sock listen.owner = www-data listen.group = www-data listen.allowed_clients = 127.0.0.1 pm = ondemand pm.max_children = 35 pm.status_path = /status chdir = /var/www/social php_value[upload_max_filesize] = 64M php_value[post_max_size] = 64M php_value[memory_limit] = 512M php_value[upload_tmp_dir] = "/tmp" env[HOSTNAME] = $HOSTNAME env[PATH] = /usr/local/bin:/usr/bin:/bin env[TMP] = /tmp env[TMPDIR] = /tmp env[TEMP] = /tmp php_value[opcache.enable] = 1 php_value[opcache.enable_cli] = 1 php_value[opcache.file_cache] = "/var/www/opcache" php_value[opcache.interned_strings_buffer] = 8 php_value[opcache.max_accelerated_files] = 10000 php_value[opcache.memory_consumption] = 128 php_value[opcache.save_comments] = 1 php_value[opcache.revalidate_freq] = 1 php_value[mysqli.allow_persistent] = On php_value[mysqli.reconnect] = On ```

Does the 404 appear when you post a notice with an attachment locally? Can you turn debugging on in the config and see if there's anything in the logs? When you post an attachment, you should get a link to it, with an ID in the end; could you check the database entries in the file and file_thumbnail tables for that ID?

The file folder is not supposed to be inside public, the point is that the webserver doesn't serve the files directly. In the nginx log you posted the error was when accessing the file directly, it seems. How did that request happen? Did the link appear somewhere on the page? Do you have extra plugins enabled?

Does the 404 appear when you post a notice with an attachment locally? Can you turn debugging on in the config and see if there's anything in the logs? When you post an attachment, you should get a link to it, with an ID in the end; could you check the database entries in the `file` and `file_thumbnail` tables for that ID? The `file` folder is not supposed to be inside `public`, the point is that the webserver doesn't serve the files directly. In the nginx log you posted the error was when accessing the file directly, it seems. How did that request happen? Did the link appear somewhere on the page? Do you have extra plugins enabled?
Diogo Cordeiro commented 4 years ago
Owner
The `file/` (should it better be in `public/`?) folder's location is
`/var/www/social/file/` and so is it configured in the `panel/paths`
 administration page.

The file directory should be under INSTALLDIR (/) and not in PUBLICDIR (public/).

In panel/paths you should have something like /file/ for Attachments->path.

I believe having this misconfigured might well be the reason for the 404s you are experiencing.

The `file/` (should it better be in `public/`?) folder's location is `/var/www/social/file/` and so is it configured in the `panel/paths` administration page. The `file` directory should be under INSTALLDIR (`/`) and not in PUBLICDIR (`public/`). In `panel/paths` you should have something like `/file/` for *Attachments->path*. I believe having this misconfigured might well be the reason for the 404s you are experiencing.
Guillaume commented 4 years ago
Poster

Here's my panel/paths settings. I moved back the file directory under INSTALLDIR following your advice. Then I made the changes needed (in config.php and NGINX block, then restarted NGINX) and I still got the error with the thumbnails. I'm on vacation, so I will try to debug the rest when I come back home, but it seems to be related to the Qvitter plugin and how it loads the thumbnails.

Here's my `panel/paths` settings. I moved back the `file` directory under INSTALLDIR following your advice. Then I made the changes needed (in config.php and NGINX block, then restarted NGINX) and I still got the error with the thumbnails. I'm on vacation, so I will try to debug the rest when I come back home, but it seems to be related to the Qvitter plugin and how it loads the thumbnails.

Any update?

Any update?
Guillaume commented 4 years ago
Poster

AFAIK, the issue I encountered was the way Qvitter was handling the thumbnails and so was I getting that many errors. With the default UI, I don't have any problems (just the attachment-wrapper's height that is fixed and giving an akward height to the previews, still need to see what's happening there).

As mentionned on this issue regarding Qvitter, I am aware that Qvitter is not maintained anymore, as for the instance it was created for in the first place (quitter.se), and a "mordern" UI like it is missing me.

AFAIK, the issue I encountered was the way Qvitter was handling the thumbnails and so was I getting that many errors. With the default UI, I don't have any problems (just the attachment-wrapper's height that is fixed and giving an akward height to the previews, still need to see what's happening there). As mentionned on [this issue regarding Qvitter](https://notabug.org/diogo/gnu-social/issues/57), I am aware that Qvitter is not maintained anymore, as for the instance it was created for in the first place (quitter.se), and a "mordern" UI like it is missing me.
aab commented 3 years ago

With the same scenario (nginx and php-fpm, similar config) with the exception of qvitter, i was having the same issue when enabling X-Accel-Redirect. I haven't tried it for a while; i've just enabled it again, and now it's working fine :)

With the same scenario (nginx and php-fpm, similar config) with the exception of qvitter, i was having the same issue when enabling X-Accel-Redirect. I haven't tried it for a while; i've just enabled it again, and now it's working fine :)
aab commented 3 years ago

Ops... disabled again, as it seems to interfere with cache. Examples follow.

1) X-Accel-Redirect enabled:

curl -I https://gnusocial.net/avatar/1-96-20200119102924.jpeg HTTP/2 200 server: nginx date: Wed, 08 Jul 2020 10:48:07 GMT content-type: text/html; charset=UTF-8 content-length: 2891 last-modified: Sat, 25 Apr 2020 18:24:33 GMT etag: "5ea48061-b4b" strict-transport-security: max-age=15768000; preload; x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin content-security-policy: default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:; x-permitted-cross-domain-policies: none x-robots-tag: all accept-ranges: bytes

2) X-Accel-Redirect disabled:

curl -I https://gnusocial.net/avatar/1-96-20200119102924.jpeg HTTP/2 200 server: nginx date: Wed, 08 Jul 2020 10:49:11 GMT content-type: image/jpeg content-length: 2891 vary: Accept-Encoding,Cookie content-description: File Transfer content-disposition: inline; filename="1-96-20200119102924.jpeg" expires: Fri, 07 Aug 2020 10:49:11 GMT content-transfer-encoding: binary cache-control: max-age=2592000 strict-transport-security: max-age=15768000; preload; x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin content-security-policy: default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:; x-permitted-cross-domain-policies: none x-robots-tag: all

(Note the "expires" line in the second one).

Ops... disabled again, as it seems to interfere with cache. Examples follow. 1) X-Accel-Redirect enabled: curl -I https://gnusocial.net/avatar/1-96-20200119102924.jpeg HTTP/2 200 server: nginx date: Wed, 08 Jul 2020 10:48:07 GMT content-type: text/html; charset=UTF-8 content-length: 2891 last-modified: Sat, 25 Apr 2020 18:24:33 GMT etag: "5ea48061-b4b" strict-transport-security: max-age=15768000; preload; x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin content-security-policy: default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:; x-permitted-cross-domain-policies: none x-robots-tag: all accept-ranges: bytes 2) X-Accel-Redirect disabled: curl -I https://gnusocial.net/avatar/1-96-20200119102924.jpeg HTTP/2 200 server: nginx date: Wed, 08 Jul 2020 10:49:11 GMT content-type: image/jpeg content-length: 2891 vary: Accept-Encoding,Cookie content-description: File Transfer content-disposition: inline; filename="1-96-20200119102924.jpeg" expires: Fri, 07 Aug 2020 10:49:11 GMT content-transfer-encoding: binary cache-control: max-age=2592000 strict-transport-security: max-age=15768000; preload; x-content-type-options: nosniff referrer-policy: strict-origin-when-cross-origin content-security-policy: default-src 'self' 'unsafe-inline'; frame-ancestors 'self'; form-action 'self'; style-src 'self' 'unsafe-inline'; img-src * blob: data:; x-permitted-cross-domain-policies: none x-robots-tag: all (Note the "expires" line in the second one).
Sign in to join this conversation.
No Milestone
No assignee
4 Participants
Loading...
Cancel
Save
There is no content yet.