listen 443 ssl http2; include /etc/nginx/conf.d/include/ssl-settings; include /etc/nginx/conf.d/include/init-optional-variables; # ddos protection: closing slow connections client_body_timeout 1h; client_header_timeout 1h; send_timeout 1h; proxy_connect_timeout 1h; proxy_read_timeout 1h; proxy_send_timeout 1h; # Increase the body buffer size, to ensure the internal POSTs can always # parse the full POST contents into memory. client_body_buffer_size 128k; client_max_body_size 128k; # legacy endpoint rewrite rewrite ^/portals /skynet/portals permanent; rewrite ^/stats /skynet/stats permanent; rewrite ^/skynet/blacklist /skynet/blocklist permanent; location / { include /etc/nginx/conf.d/include/cors; set $skylink "0404dsjvti046fsua4ktor9grrpe76erq9jot9cvopbhsvsu76r4r30"; set $path $uri; set $internal_no_limits "true"; include /etc/nginx/conf.d/include/location-skylink; proxy_intercept_errors on; error_page 400 404 490 500 502 503 504 =200 @fallback; } location @fallback { proxy_pass http://website:9000; } location /docs { proxy_pass https://skynetlabs.github.io/skynet-docs; } location /skynet/blocklist { include /etc/nginx/conf.d/include/cors; proxy_cache skynet; proxy_cache_valid any 1m; # cache blocklist for 1 minute proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980/skynet/blocklist; } location /skynet/portals { include /etc/nginx/conf.d/include/cors; proxy_cache skynet; proxy_cache_valid any 1m; # cache portals for 1 minute proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980/skynet/portals; } location /skynet/stats { include /etc/nginx/conf.d/include/cors; proxy_cache skynet; proxy_cache_valid any 1m; # cache stats for 1 minute proxy_set_header User-Agent: Sia-Agent; proxy_read_timeout 5m; # extend the read timeout proxy_pass http://sia:9980/skynet/stats; } location /nginx/stats { include /etc/nginx/conf.d/include/cors; charset utf-8; charset_types application/json; default_type application/json; content_by_lua_block { local json = require('cjson') ngx.say(json.encode{ -- current number of active client connections including waiting connections connections_active = tonumber(ngx.var.connections_active), -- current number of connections where nginx is reading the request header connections_reading = tonumber(ngx.var.connections_reading), -- current number of connections where nginx is writing the response back to the client connections_writing = tonumber(ngx.var.connections_writing), -- current number of idle client connections waiting for a request connections_waiting = tonumber(ngx.var.connections_waiting), }) return ngx.exit(ngx.HTTP_OK) } } # Define path for server load endpoint location /serverload { # Define root directory in the nginx container to load file from root /usr/local/share; # including this because of peer pressure from the other routes include /etc/nginx/conf.d/include/cors; # tell nginx to expect json default_type 'application/json'; # Allow for /serverload to load /serverload.json file try_files $uri $uri.json =404; } location /skynet/health { include /etc/nginx/conf.d/include/cors; proxy_cache skynet; proxy_cache_key $request_uri; # use whole request uri (uri + args) as cache key proxy_cache_valid any 1m; # cache responses for 1 minute proxy_set_header User-Agent: Sia-Agent; proxy_read_timeout 5m; # extend the read timeout proxy_pass http://sia:9980; } location /health-check { include /etc/nginx/conf.d/include/cors; access_log off; # do not log traffic to health-check endpoint proxy_pass http://10.10.10.60:3100; # hardcoded ip because health-check waits for nginx } location /abuse { return 308 /0404guluqu38oaqapku91ed11kbhkge55smh9lhjukmlrj37lfpm8no/; } location /abuse/report { include /etc/nginx/conf.d/include/cors; # 10.10.10.110 points to blocker service proxy_pass http://10.10.10.110:4000/powblock; } location /hns { include /etc/nginx/conf.d/include/cors; # match the request_uri and extract the hns domain and anything that is passed in the uri after it # example: /hns/something/foo/bar matches: # > hns_domain: something # > path: /foo/bar/ set_by_lua_block $hns_domain { return string.match(ngx.var.uri, "/hns/([^/?]+)") } set_by_lua_block $path { return string.match(ngx.var.uri, "/hns/[^/?]+(.*)") } proxy_set_header Host $host; include /etc/nginx/conf.d/include/location-hns; } location /hnsres { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/portal-access-check; proxy_pass http://handshake-api:3100; } location /skynet/registry { include /etc/nginx/conf.d/include/location-skynet-registry; } location /skynet/restore { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/sia-auth; include /etc/nginx/conf.d/include/portal-access-check; client_max_body_size 5M; # increase request timeouts proxy_read_timeout 600; proxy_send_timeout 600; proxy_request_buffering off; # stream uploaded files through the proxy as it comes in proxy_set_header Expect $http_expect; proxy_set_header User-Agent: Sia-Agent; # proxy this call to siad endpoint (make sure the ip is correct) proxy_pass http://sia:9980; } location /skynet/registry/subscription { include /etc/nginx/conf.d/include/cors; # default to unlimited bandwidth and no delay set $bandwidthlimit "0"; set $notificationdelay "0"; rewrite_by_lua_block { -- this block runs only when accounts are enabled if os.getenv("PORTAL_MODULES"):match("a") then local httpc = require("resty.http").new() -- fetch account limits and set download bandwidth and registry delays accordingly local res, err = httpc:request_uri("http://10.10.10.70:3000/user/limits", { headers = { ["Cookie"] = "skynet-jwt=" .. ngx.var.skynet_jwt } }) -- fail gracefully in case /user/limits failed if err or (res and res.status ~= ngx.HTTP_OK) then ngx.log(ngx.ERR, "Failed accounts service request /user/limits: ", err or ("[HTTP " .. res.status .. "] " .. res.body)) elseif res and res.status == ngx.HTTP_OK then local json = require('cjson') local limits = json.decode(res.body) ngx.var.bandwidthlimit = limits.download ngx.var.notificationdelay = limits.registry end end } proxy_set_header User-Agent: Sia-Agent; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_pass http://sia:9980/skynet/registry/subscription?bandwidthlimit=$bandwidthlimit¬ificationdelay=$notificationdelay; } location /skynet/skyfile { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/sia-auth; include /etc/nginx/conf.d/include/track-upload; include /etc/nginx/conf.d/include/generate-siapath; include /etc/nginx/conf.d/include/portal-access-check; limit_req zone=uploads_by_ip burst=10 nodelay; limit_req zone=uploads_by_ip_throttled; limit_conn upload_conn 5; limit_conn upload_conn_rl 1; client_max_body_size 5000M; # make sure to limit the size of upload to a sane value # increase request timeouts proxy_read_timeout 600; proxy_send_timeout 600; proxy_request_buffering off; # stream uploaded files through the proxy as it comes in proxy_set_header Expect $http_expect; proxy_set_header User-Agent: Sia-Agent; # proxy this call to siad endpoint (make sure the ip is correct) proxy_pass http://sia:9980/skynet/skyfile/$dir1/$dir2/$dir3$is_args$args; } # endpoint implementing resumable file uploads open protocol https://tus.io location /skynet/tus { include /etc/nginx/conf.d/include/cors-headers; # include cors headers but do not overwrite OPTIONS response include /etc/nginx/conf.d/include/track-upload; limit_req zone=uploads_by_ip burst=10 nodelay; limit_req zone=uploads_by_ip_throttled; limit_conn upload_conn 5; limit_conn upload_conn_rl 1; # TUS chunks size is 40M + leaving 10M of breathing room client_max_body_size 50M; # Those timeouts need to be elevated since skyd can stall reading # data for a while when overloaded which would terminate connection client_body_timeout 1h; proxy_send_timeout 1h; # Add X-Forwarded-* headers proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto $scheme; # rewrite proxy request to use correct host uri from env variable (required to return correct location header) set_by_lua_block $server_domain { return os.getenv("SERVER_DOMAIN") } proxy_redirect $scheme://$host $scheme://$server_domain; # proxy /skynet/tus requests to siad endpoint with all arguments proxy_pass http://sia:9980; access_by_lua_block { if require("skynet.account").accounts_enabled() then -- check if portal is in authenticated only mode if require("skynet.account").is_access_unauthorized() then return require("skynet.account").exit_access_unauthorized() end -- check if portal is in subscription only mode if require("skynet.account").is_access_forbidden() then return require("skynet.account").exit_access_forbidden() end -- get account limits of currently authenticated user local limits = require("skynet.account").get_account_limits() -- apply upload size limits ngx.req.set_header("SkynetMaxUploadSize", limits.maxUploadSize) end } # extract skylink from base64 encoded upload metadata and assign to a proper header header_filter_by_lua_block { ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. os.getenv("PORTAL_DOMAIN") ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. os.getenv("SERVER_DOMAIN") if ngx.header["Upload-Metadata"] then local encodedSkylink = string.match(ngx.header["Upload-Metadata"], "Skylink ([^,?]+)") if encodedSkylink then ngx.header["Skynet-Skylink"] = ngx.decode_base64(encodedSkylink) end end } } location /skynet/pin { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/sia-auth; include /etc/nginx/conf.d/include/track-upload; include /etc/nginx/conf.d/include/generate-siapath; include /etc/nginx/conf.d/include/portal-access-check; limit_req zone=uploads_by_ip burst=10 nodelay; limit_req zone=uploads_by_ip_throttled; limit_conn upload_conn 5; limit_conn upload_conn_rl 1; proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980$uri?siapath=$dir1/$dir2/$dir3&$args; } location /skynet/metadata { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/portal-access-check; header_filter_by_lua_block { ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. os.getenv("PORTAL_DOMAIN") ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. os.getenv("SERVER_DOMAIN") } proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980; } location /skynet/resolve { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/portal-access-check; header_filter_by_lua_block { ngx.header["Skynet-Portal-Api"] = ngx.var.scheme .. "://" .. os.getenv("PORTAL_DOMAIN") ngx.header["Skynet-Server-Api"] = ngx.var.scheme .. "://" .. os.getenv("SERVER_DOMAIN") } proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980; } location ~ "^/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" { set $skylink $2; set $path $3; include /etc/nginx/conf.d/include/location-skylink; } location ~ "^/file/(([a-zA-Z0-9-_]{46}|[a-z0-9]{55})(/.*)?)$" { set $skylink $2; set $path $3; set $args attachment=true&$args; #set $is_args ?; include /etc/nginx/conf.d/include/location-skylink; } location /skynet/trustless/basesector { include /etc/nginx/conf.d/include/cors; include /etc/nginx/conf.d/include/proxy-buffer; include /etc/nginx/conf.d/include/track-download; limit_conn downloads_by_ip 100; # ddos protection: max 100 downloads at a time # default download rate to unlimited set $limit_rate 0; access_by_lua_block { if require("skynet.account").accounts_enabled() then -- check if portal is in authenticated only mode if require("skynet.account").is_access_unauthorized() then return require("skynet.account").exit_access_unauthorized() end -- check if portal is in subscription only mode if require("skynet.account").is_access_forbidden() then return require("skynet.account").exit_access_forbidden() end -- get account limits of currently authenticated user local limits = require("skynet.account").get_account_limits() -- apply download speed limit ngx.var.limit_rate = limits.download end } limit_rate_after 512k; limit_rate $limit_rate; proxy_set_header User-Agent: Sia-Agent; proxy_pass http://sia:9980; } location /__internal/do/not/use/accounts { include /etc/nginx/conf.d/include/cors; charset utf-8; charset_types application/json; default_type application/json; content_by_lua_block { local json = require('cjson') local accounts_enabled = require("skynet.account").accounts_enabled() local is_auth_required = require("skynet.account").is_auth_required() local is_authenticated = accounts_enabled and require("skynet.account").is_authenticated() ngx.say(json.encode{ enabled = accounts_enabled, auth_required = is_auth_required, authenticated = is_authenticated, }) return ngx.exit(ngx.HTTP_OK) } } include /etc/nginx/conf.d/server-override/*;