LE contacts the server by hostname and not by IP. This means that when installing and reconfiguring the app it hits the default_server route since nginx configs for the app are not generated at. When doing in the daily cert renew, the nginx configs exist and we are unable to renew the certs.
205 lines
6.9 KiB
Plaintext
205 lines
6.9 KiB
Plaintext
# http://nginx.org/en/docs/http/websocket.html
|
|
map $http_upgrade $connection_upgrade {
|
|
default upgrade;
|
|
'' close;
|
|
}
|
|
|
|
# http server
|
|
server {
|
|
listen 80;
|
|
<% if (hasIPv6) { -%>
|
|
listen [::]:80;
|
|
<% } -%>
|
|
|
|
<% if (vhost) { -%>
|
|
server_name <%= vhost %>;
|
|
<% } else { -%>
|
|
# IP based access from collectd or initial cloudron setup. TODO: match the IPv6 address
|
|
server_name "~^\d+\.\d+\.\d+\.\d+$";
|
|
|
|
# collectd
|
|
location /nginx_status {
|
|
stub_status on;
|
|
access_log off;
|
|
allow 127.0.0.1;
|
|
deny all;
|
|
}
|
|
<% } -%>
|
|
|
|
# acme challenges (for cert renewal where the vhost config exists)
|
|
location /.well-known/acme-challenge/ {
|
|
default_type text/plain;
|
|
alias /home/yellowtent/platformdata/acme/;
|
|
}
|
|
|
|
location / {
|
|
# redirect everything to HTTPS
|
|
return 301 https://$host$request_uri;
|
|
}
|
|
}
|
|
|
|
# https server
|
|
server {
|
|
<% if (vhost) { -%>
|
|
server_name <%= vhost %>;
|
|
listen 443 http2;
|
|
<% if (hasIPv6) { -%>
|
|
listen [::]:443 http2;
|
|
<% } -%>
|
|
<% } else { -%>
|
|
listen 443 http2 default_server;
|
|
<% if (hasIPv6) { -%>
|
|
listen [::]:443 http2 default_server;
|
|
<% } -%>
|
|
<% } -%>
|
|
|
|
ssl on;
|
|
# paths are relative to prefix and not to this file
|
|
ssl_certificate <%= certFilePath %>;
|
|
ssl_certificate_key <%= keyFilePath %>;
|
|
ssl_session_timeout 5m;
|
|
ssl_session_cache shared:SSL:50m;
|
|
|
|
# https://bettercrypto.org/static/applied-crypto-hardening.pdf
|
|
# https://mozilla.github.io/server-side-tls/ssl-config-generator/
|
|
# https://cipherli.st/
|
|
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
|
|
ssl_prefer_server_ciphers on;
|
|
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # don't use SSLv3 ref: POODLE
|
|
# ciphers according to https://weakdh.org/sysadmin.html
|
|
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
|
|
ssl_dhparam /home/yellowtent/boxdata/dhparams.pem;
|
|
add_header Strict-Transport-Security "max-age=15768000";
|
|
|
|
# https://developer.mozilla.org/en-US/docs/Web/HTTP/X-Frame-Options
|
|
add_header X-Frame-Options "<%= xFrameOptions %>";
|
|
proxy_hide_header X-Frame-Options;
|
|
|
|
# https://github.com/twitter/secureheaders
|
|
# https://www.owasp.org/index.php/OWASP_Secure_Headers_Project#tab=Compatibility_Matrix
|
|
# https://wiki.mozilla.org/Security/Guidelines/Web_Security
|
|
add_header X-XSS-Protection "1; mode=block";
|
|
proxy_hide_header X-XSS-Protection;
|
|
add_header X-Download-Options "noopen";
|
|
proxy_hide_header X-Download-Options;
|
|
add_header X-Content-Type-Options "nosniff";
|
|
proxy_hide_header X-Content-Type-Options;
|
|
add_header X-Permitted-Cross-Domain-Policies "none";
|
|
proxy_hide_header X-Permitted-Cross-Domain-Policies;
|
|
add_header Referrer-Policy "no-referrer-when-downgrade";
|
|
proxy_hide_header Referrer-Policy;
|
|
|
|
proxy_http_version 1.1;
|
|
proxy_intercept_errors on;
|
|
proxy_read_timeout 3500;
|
|
proxy_connect_timeout 3250;
|
|
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header X-Forwarded-Port $server_port;
|
|
proxy_set_header X-Forwarded-Proto https;
|
|
proxy_set_header X-Forwarded-Ssl on;
|
|
|
|
# upgrade is a hop-by-hop header (http://nginx.org/en/docs/http/websocket.html)
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
|
|
# only serve up the status page if we get proxy gateway errors
|
|
root <%= sourceDir %>/webadmin/dist;
|
|
error_page 502 503 504 /appstatus.html;
|
|
location /appstatus.html {
|
|
internal;
|
|
}
|
|
|
|
location / {
|
|
# increase the proxy buffer sizes to not run into buffer issues (http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffers)
|
|
proxy_buffer_size 128k;
|
|
proxy_buffers 4 256k;
|
|
proxy_busy_buffers_size 256k;
|
|
|
|
# No buffering to temp files, it fails for large downloads
|
|
proxy_max_temp_file_size 0;
|
|
|
|
# Disable check to allow unlimited body sizes. this allows apps to accept whatever size they want
|
|
client_max_body_size 0;
|
|
|
|
<% if (robotsTxtQuoted) { %>
|
|
location = /robots.txt {
|
|
return 200 <%- robotsTxtQuoted %>;
|
|
}
|
|
<% } %>
|
|
|
|
<% if ( endpoint === 'admin' ) { %>
|
|
location /api/ {
|
|
proxy_pass http://127.0.0.1:3000;
|
|
client_max_body_size 1m;
|
|
}
|
|
|
|
location ~ ^/api/v1/(developer|session)/login$ {
|
|
proxy_pass http://127.0.0.1:3000;
|
|
client_max_body_size 1m;
|
|
limit_req zone=admin_login burst=5;
|
|
}
|
|
|
|
# the read timeout is between successive reads and not the whole connection
|
|
location ~ ^/api/v1/apps/.*/exec$ {
|
|
proxy_pass http://127.0.0.1:3000;
|
|
proxy_read_timeout 30m;
|
|
}
|
|
|
|
location ~ ^/api/v1/apps/.*/upload$ {
|
|
proxy_pass http://127.0.0.1:3000;
|
|
client_max_body_size 0;
|
|
}
|
|
|
|
# graphite paths (uncomment block below and visit /graphite/index.html)
|
|
# location ~ ^/(graphite|content|metrics|dashboard|render|browser|composer)/ {
|
|
# proxy_pass http://127.0.0.1:8000;
|
|
# client_max_body_size 1m;
|
|
# }
|
|
|
|
location / {
|
|
root <%= sourceDir %>/webadmin/dist;
|
|
index index.html index.htm;
|
|
}
|
|
<% } else if ( endpoint === 'app' ) { %>
|
|
proxy_pass http://127.0.0.1:<%= port %>;
|
|
<% } else if ( endpoint === 'splash' ) { %>
|
|
root <%= sourceDir %>;
|
|
|
|
error_page 503 /update.html;
|
|
|
|
location /update.html {
|
|
add_header Cache-Control no-cache;
|
|
}
|
|
|
|
location /theme.css {
|
|
add_header Cache-Control no-cache;
|
|
}
|
|
|
|
location /3rdparty/ {
|
|
add_header Cache-Control no-cache;
|
|
}
|
|
|
|
location /js/ {
|
|
add_header Cache-Control no-cache;
|
|
}
|
|
|
|
location /progress.json {
|
|
add_header Cache-Control no-cache;
|
|
}
|
|
|
|
location /api/v1/cloudron/progress {
|
|
add_header Cache-Control no-cache;
|
|
default_type application/json;
|
|
alias <%= sourceDir %>/progress.json;
|
|
}
|
|
|
|
location / {
|
|
return 503;
|
|
}
|
|
<% } %>
|
|
}
|
|
}
|