Closed LasersAreGreat closed 3 years ago
I found the problem, and it was not with Peertube but with the difference in how Digital Ocean handles their S3 competitors CORS setup compared to Amazon S3.
Anyone else having this problem can fix it by putting a * in the "Allowed Headers" field when setting up the CORS settings for digital ocean spaces.
Since this is fixed by my above comment, I'm closing this.
I've setup Peertube to serve content directly from S3 buckets. Peertube works fine when I have the feature of serving from S3 turned off (those 3 lines in the nginx file commented out), but when I have those lines enabled I get CORS errors. Since it works with CURL, I'm inclined to think there might be a bug here, but I also think that an error on my part is entirely possible despite my days of effort to troubleshoot this.
I've made sure that I have the appropriate lines in my nginx configuration as per the official nginx file. I've enable CORS on the CDN in front of the s3 bucket. I've test it with CURL, and it works fine. But within peertube, I get a CORS error.
Here is the output from CURL, where it seems to work fine.
curl -I -X OPTIONS -H 'Origin: http://peertube.newsocial.tech' -H 'Access-Control-Request-Method: GET' 'https://peertubecdn.newsocial.tech/streaming-playlists/hls/224658e5-4e70-4fc2-b2c3-ebc7e02fc744/224658e5-4e70-4fc2-b2c3-ebc7e02fc744-720-fragmented.mp4'
HTTP/2 200 date: Wed, 07 Apr 2021 19:40:21 GMT content-type: video/mp4 content-length: 0 set-cookie: __cfduid=daaf1fb4c5c2de22ec889a754d1f58df81617824420; expires=Fri, 07-May-21 19:40:20 GMT; path=/; domain=.newsocial.tech; HttpOnly; SameSite=Lax; Secure access-control-allow-origin: http://peertube.newsocial.tech vary: Origin access-control-allow-methods: GET access-control-max-age: 1728000 x-amz-request-id: tx000000000000021bb44b4-00606e0aa4-962f868-nyc3c strict-transport-security: max-age=31536000; includeSubDomains; preload vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method x-hw: 1617824420.dop209.ez1.t,1617824420.cds208.ez1.shn,1617824420.cds208.ez1.sc,1617824421.cds208.ez1.p cf-cache-status: DYNAMIC cf-request-id: 094f72a936000074d748969000000001 expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct" report-to: {"group":"cf-nel","endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report?s=rpP7MVJHpPHgF%2FLLsxOk1pGjlYN1vcMY07B9WyUFrF9jo0Vz4pJoQcP1hZRjMpDVryZSOWRYSMzg1XZLGIa3sVYAA6pfu7RBAAJXiN7D56cpK925p7hjpoNY7Q%3D%3D"}],"max_age":604800} nel: {"max_age":604800,"report_to":"cf-nel"} x-content-type-options: nosniff server: cloudflare cf-ray: 63c5ba21efe174d7-EZE alt-svc: h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
But, when peertube tries to load the video in the browser, I get CORS errors.
For example, loading this page: https://peertube.newsocial.tech/videos/watch/224658e5-4e70-4fc2-b2c3-ebc7e02fc744
Results in the following errors in the Chrome browser console:
224658e5-4e70-4fc2-b2c3-ebc7e02fc744:1 Access to XMLHttpRequest at 'https://peertubecdn.newsocial.tech/streaming-playlists/hls/224658e5-4e70-4fc2-b2c3-ebc7e02fc744/224658e5-4e70-4fc2-b2c3-ebc7e02fc744-720-fragmented.mp4' from origin 'https://peertube.newsocial.tech' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I'm running nginx 1.18.0 on Ubuntu 20.04, and here is the /etc/nginx/site-enabled/peertube file:
Minimum Nginx version required: 1.13.0 (released Apr 25, 2017)
Please check your Nginx installation features the following modules via 'nginx -V':
STANDARD HTTP MODULES: Core, Proxy, Rewrite, Access, Gzip, Headers, HTTP/2, Log, Real IP, SSL, Thread Pool, Upstream, AIO Multithreading.
THIRD PARTY MODULES: None.
server { listen 80; listen [::]:80; server_name peertube.newsocial.tech;
location /.well-known/acme-challenge/ { default_type "text/plain"; root /var/www/certbot; } location / { return 301 https://$host$request_uri; } }
upstream backend { server 127.0.0.1:9000; }
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name peertube.newsocial.tech;
access_log /var/log/nginx/peertube.access.log; # reduce I/0 with buffer=10m flush=5m error_log /var/log/nginx/peertube.error.log;
Certificates
you need a certificate to run in production. see https://letsencrypt.org/
ssl_certificate /etc/letsencrypt/live/peertube.newsocial.tech/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/peertube.newsocial.tech/privkey.pem;
location ^~ '/.well-known/acme-challenge' { default_type "text/plain"; root /var/www/certbot; }
Security hardening (as of Nov 15, 2020)
based on Mozilla Guideline v5.6
ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers on; ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256; # add ECDHE-RSA-AES256-SHA if you want compatibility with Android 4 ssl_session_timeout 1d; # defaults to 5m ssl_session_cache shared:SSL:40m; # estimated to 40k sessions ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on;
HSTS (https://hstspreload.org), requires to be copied in 'location' sections that have add_header directives
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains";
Application
Application
location @api { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr;
}
location / { try_files /dev/null @api; }
location = /api/v1/videos/upload { limit_except POST HEAD { deny all; }
}
location ~ ^/api/v1/(videos|video-playlists|video-channels|users/me) { client_max_body_size 3M; # default is 1M add_header X-File-Maximum-Size 2M always; # inform backend of the set value in bytes before mime-encoding (x * 1.4 >= client_max_body_size)
}
Websocket
location @api_websocket { proxy_http_version 1.1; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";
}
location /socket.io { try_files /dev/null @api_websocket; }
location /tracker/socket {
Peers send a message to the tracker every 15 minutes
}
Performance optimizations
For extra performance please refer to https://github.com/denji/nginx-tuning
root /var/www/peertube/s3fs;
Enable compression for JS/CSS/HTML, for improved client load times.
It might be nice to compress JSON/XML as returned by the API, but
leaving that out to protect against potential BREACH attack.
gzip on; gzip_vary on; gzip_types # text/html is always compressed by HttpGzipModule text/css application/javascript font/truetype font/opentype application/vnd.ms-fontobject image/svg+xml; gzip_min_length 1000; # default is 20 bytes gzip_buffers 16 8k; gzip_comp_level 2; # default is 1
client_body_timeout 30s; # default is 60 client_header_timeout 10s; # default is 60 send_timeout 10s; # default is 60 keepalive_timeout 10s; # default is 75 resolver_timeout 10s; # default is 30 reset_timedout_connection on; proxy_ignore_client_abort on;
tcp_nopush on; # send headers in one piece tcp_nodelay on; # don't buffer data sent, good for small data bursts in real time
If you have a small /var/lib partition, it could be interesting to store temp nginx uploads in a different place
See https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path
client_body_temp_path /var/www/peertube/storage/nginx/;
Bypass PeerTube for performance reasons. Optional.
Should be consistent with client-overrides assets list in /server/controllers/client.ts
location ~ ^/client/(assets/images/(icons/icon-36x36.png|icons/icon-48x48.png|icons/icon-72x72.png|icons/icon-96x96.png|icons/icon-144x144.png|icons/icon-192x192.png|icons/icon-512x512.png|logo.svg|favicon.png))$ { add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year
}
Bypass PeerTube for performance reasons. Optional.
location ~ ^/client/(.*.(js|css|png|svg|woff2|otf|ttf|woff|eot))$ { add_header Cache-Control "public, max-age=31536000, immutable"; # Cache 1 year
}
Bypass PeerTube for performance reasons. Optional.
location ~ ^/static/(thumbnails|avatars)/ { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin '*'; add_header Access-Control-Allow-Methods 'GET, OPTIONS'; add_header Access-Control-Allow-Headers 'Range,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; add_header Access-Control-Max-Age 1728000; # Preflight request can be cached 20 days add_header Content-Type 'text/plain charset=UTF-8'; add_header Content-Length 0; return 204; }
}
Bypass PeerTube for performance reasons. Optional.
location ~ ^/static/(webseed|redundancy|streaming-playlists)/ {
} }
finally, when I talk about the 3 lines that I can comment out to disable serving directly from s3 and make everything work, I mean these: set $cdn https://peertubecdn.newsocial.tech; rewrite ^/static/webseed/(.)$ $cdn/videos/$1 redirect; rewrite ^/static/(.)$ $cdn/$1 redirect;