nginx / unit

NGINX Unit - universal web app server - a lightweight and versatile open source server that simplifies the application stack by natively executing application code across eight different programming language runtimes.
https://unit.nginx.org
Apache License 2.0
5.4k stars 331 forks source link

"upstream" directive is not allowed here in /etc/nginx/conf.d/default.conf #446

Closed N1GHTR4NG3R closed 2 years ago

N1GHTR4NG3R commented 4 years ago

Apologies if this has been asked and answered prior.

I am following this guide to installing wordpress with nginx and unit, Everything is going well until I verify the configuration, where it outputs this in the console: nginx: [emerg] "upstream" directive is not allowed here in /etc/nginx/conf.d/default.conf nginx: configuration file /etc/nginx/nginx.conf test failed

I am running Ubuntu 18.04.4 LTS with latest updates.

curl localhost returns the html for the Nginx default page.

Unfortunately I am not sure how to troubleshoot this, so any help is appreciated if you need any more details please just let me know what you need

mar0x commented 4 years ago

Hello Richard,

Make sure the line:

include /etc/nginx/conf.d/*.conf;

in file /etc/nginx/nginx.conf is inside

http {
..
}

block.

Please have a look at the updated Unit WordPress Howto - you may run WordPress without using nginx.

miklb commented 4 years ago

Please have a look at the updated Unit WordPress Howto - you may run WordPress without using nginx.

That tutorial recommends using Nginx as a proxy for anything in production, but doesn't cover configuring Nginx as a proxy for Unit, which the OP uses. This page does have some generic PHP configuration for Nginx/Unit. It's been bit of a game of hide and seek to put it all together.

VBart commented 4 years ago

@miklb Actually it doesn't recommend using nginx (are we looking at the same tutorial?). The idea of Unit is to simplify setup, not to complicate it. Having to configure nginx as a proxy complicates everything.

miklb commented 4 years ago

@VBart the tutorial you link to is part of the Unit docs. The page I linked to is from the same set of documentation.

By default, Unit exposes its API via a Unix domain socket. For remote access, use NGINX as a reverse proxy.

Use NGINX for robust security, authentication, and access control in production scenarios. We strongly recommend against exposing an unsecured Unit API.

I also came across #254 which led me to some docs on configuration

For security reasons, avoid opening sockets on public interfaces in production.

Are you saying the official docs are wrong, and that I can safely run Unit on a public server without using Nginx in front?

miklb commented 4 years ago

I sat in on the webinar today and understand a little more about how Unit can be run without Nginx as a front end proxy. Still not sure how to force SSL with it and will revisit how to do TLS. I was the person that asked for docs on this. Thanks for your help. I'm excited to fully grasp using Unit beyond a local Docker.

VBart commented 4 years ago

Are you saying the official docs are wrong, and that I can safely run Unit on a public server without using Nginx in front?

It's about the control API socket, which is used to configure Unit. Sure, opening it on a public interface without any authorization gives everyone access to control your server (it's like giving anonymous SSH access to your nginx.conf file).

On the other hand, there's nothing wrong with opening sockets listening for client requests on a public interface.

anthonybudd commented 4 years ago

Make sure the line:

include /etc/nginx/conf.d/*.conf;

in file /etc/nginx/nginx.conf is inside

http {
..
}

Now /etc/nginx/nginx.conf looks like this and it still doesn't work?

http {
    include /etc/nginx/conf.d/*.conf;
}

upstream example {
    server 127.0.0.1:8080;
}

server {
    listen 127.0.0.1:80;
    location / {
        proxy_pass http://example;
    }
}

Could you go into more detail about how to solve this?

ghost commented 4 years ago

Hello,

Try this:

http {
    include /etc/nginx/conf.d/*.conf;

    upstream example {
        server 127.0.0.1:8080;
    }

    server {
        location / {
            proxy_pass http://example;
            proxy_set_header Host $host;
        }
    }
}

More info: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream

ghost commented 4 years ago

The idea is to have the upstream and the server inside the http context.

philbowers commented 4 years ago

It's not wordpress but, below is my nginx.conf setup that works for me.

My main nginx proxy redirect, this handles all of the redirects for anything I want to access from outside my house: nginx.conf

worker_processes  auto;

events {
    worker_connections  1024;
}

http {

  server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name domain.com;
    return 301 https://$server_name:$request_uri;
  }

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  reset_timedout_connection on;
  keepalive_timeout 65;
  keepalive_requests 1000;
  types_hash_max_size 2048;
  server_tokens off;
  send_timeout 30;
  server_names_hash_max_size 4096;

  client_max_body_size 16500M; 
  client_body_buffer_size 10m;
  client_header_timeout 10m;
  client_body_timeout 10m;
  client_body_temp_path /var/tmp/nginx/client_body_temp;

  proxy_connect_timeout 5;
  proxy_send_timeout 10;
  proxy_read_timeout 10;
  proxy_buffer_size 4k;
  proxy_buffers 8 16k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;
  proxy_temp_path /var/tmp/nginx/proxy_temp;

  include mime.types;
  default_type application/octet-stream;

  log_format main '$remote_addr - $host [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"'
                 'rt=$request_time ut=$upstream_response_time '
                  'cs=$upstream_cache_status';

  log_format cache '$remote_addr - $host [$time_local] "$request" $status '
                   '$body_bytes_sent "$http_referer" '
                   'rt=$request_time ut=$upstream_response_time '
                   'cs=$upstream_cache_status';

  access_log /var/log/nginx/access.log main;
  error_log /var/log/nginx/error.log warn;

  gzip on;
  gzip_static on;
  gzip_types text/plain text/css text/javascript text/xml application/x-javascript application/javascript application/xml application/json image/x-icon;
  gzip_comp_level 9;
  gzip_buffers 16 8k;
  gzip_proxied expired no-cache no-store private auth;
  gzip_min_length 1000;
  gzip_disable "msie6"
  gzip_vary on;

  proxy_cache_valid 1m;

  include "vdomains/*.conf";
}

The vdomains/cloud.conf redirect to my nextcloud instance.

server {
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name cloud.domain.com;

        access_log /var/log/nginx/cloud.access.log;
        error_log /var/log/nginx/cloud.error.log;

        # HSTS (ngx_http_headers_module is required) (15552000 seconds)
        add_header Strict-Transport-Security "max-age=15552000" always;

        include snippets/params.conf;

        location / {
                proxy_pass https://192.168.1.13;
        }
}

The snippets/params.conf file.

ssl_certificate /usr/local/etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /usr/local/etc/letsencrypt/live/domain.com/privkey.pem;
ssl_trusted_certificate /usr/local/etc/letsencrypt/live/domain.com/chain.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_dhparam /usr/local/etc/ssl/dhparam.pem;

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;

ssl_stapling off;
ssl_stapling_verify on;

# replace with the IP address of your resolver
resolver 217.70.177.40;

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;

My nextcloud server runs its own nginx instance and has its own certs to handle local https traffic.

nginx.conf

# /usr/local/etc/nginx/nginx.conf

load_module /usr/local/libexec/nginx/ngx_mail_module.so;
load_module /usr/local/libexec/nginx/ngx_stream_module.so;

user www;
worker_processes auto;

pid /var/run/nginx.pid;

events {
  use kqueue;
  worker_connections 1024;
  multi_accept on;
}
http {

  sendfile on;
  tcp_nopush on;
  tcp_nodelay on;
  reset_timedout_connection on;
  keepalive_timeout 65;
  keepalive_requests 1000;
  types_hash_max_size 2048;
  server_tokens off;
  send_timeout 30;
  server_names_hash_max_size 4096;

  client_max_body_size 100m; # upload size
  client_body_buffer_size 1m;
  client_header_timeout 3m;
  client_body_timeout 3m;             

  client_body_temp_path /var/tmp/nginx/client_body_temp;

  proxy_connect_timeout 5;
  proxy_send_timeout 10;
  proxy_read_timeout 10;

  proxy_buffer_size 4k;
  proxy_buffers 8 16k;
  proxy_busy_buffers_size 64k;
  proxy_temp_file_write_size 64k;

  proxy_temp_path /var/tmp/nginx/proxy_temp;

  include mime.types;
  default_type application/octet-stream;

  log_format main '$remote_addr - $host [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"'
                  'rt=$request_time ut=$upstream_response_time '
                  'cs=$upstream_cache_status';

  log_format cache '$remote_addr - $host [$time_local] "$request" $status '
                   '$body_bytes_sent "$http_referer" '
                   'rt=$request_time ut=$upstream_response_time '
                   'cs=$upstream_cache_status';

  access_log /var/log/nginx/access.log main;
  error_log /var/log/nginx/error.log warn;

  gzip on;
  gzip_static on;
  gzip_types text/plain text/css text/javascript text/xml application/x-javascript applicati>
  gzip_comp_level 9;
  gzip_buffers 16 8k;
  gzip_proxied expired no-cache no-store private auth;
  gzip_min_length 1000;
  gzip_disable "msie6"
  gzip_vary on;

  proxy_cache_valid 1m;

  # Virtual host config
  # ----------

  include /usr/local/etc/nginx/conf.d/*.conf;
}

The file in the conf.d/nextcloud.conf

#/usr/local/etc/nginx/conf.d/nextcloud.conf

upstream php-handler {
  server unix:/var/run/nextcloud-php-fpm.sock;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server;
  return 301 https://$request_uri:443;
}

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

  # Use Mozilla's guidelines for SSL/TLS settings
  # https://mozilla.github.io/server-side-tls/ssl-config-generator/
  # openssl req -x509 -nodes -days 3650 -newkey rsa:4096 -keyout nextcloud.key -out nextcloud.crt
  ssl_certificate /usr/local/etc/ssl/nextcloud.crt;
  ssl_certificate_key /usr/local/etc/ssl/nextcloud.key;
  ssl_dhparam /usr/local/etc/ssl/dhparam.pem;

  ssl_session_cache shared:MozSSL:10m;
  ssl_session_tickets off;
  ssl_session_timeout 1d;

  ssl_protocols TLSv1.2 TLSv1.3;
  ssl_ciphers TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
  ssl_prefer_server_ciphers on;

  # WARNING: Only add the preload option once you read about
  # the consequences in https://hstspreload.org/. This option
  # will add the domain to a hardcoded list that is shipped
  # in all major browsers and getting removed from this list
  # could take several months.
  # HSTS
  add_header Strict-Transport-Security "max-age=15768000; includeSubDomains;" always;

  ssl_stapling off;
  ssl_stapling_verify on;

  ssl_trusted_certificate /usr/local/etc/ssl/cert.pem;

  # replace with the IP address of your resolver
  resolver 127.0.0.1;

  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 "none" 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;

  # Path to the root of your installation                                                
  root /usr/local/www/nextcloud/;

  location = /robots.txt {
    allow all;
    log_not_found off;
    access_log off;
  }

  # The following 2 rules are only needed for the user_webfinger app.
  rewrite ^/.well-known/host-meta /public.php?service=host-meta last;
  rewrite ^/.well-known/host-meta.json /public.php?service=host-meta-json last;

  # The following rule is only needed for the Social app.
  rewrite ^/.well-known/webfinger /public.php?service=webfinger last;

  location = /.well-known/carddav {
    return 301 $scheme://$host:$server_port/remote.php/dav;
  }
  location = /.well-known/caldav {
    return 301 $scheme://$host:$server_port/remote.php/dav;
  }

  # set max upload size
  client_max_body_size 0;
  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/r>
application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+x>
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;

  # Uncomment if your server was built with the ngx_pagespeed module
  # This module is currently not supported.
  #pagespeed off;

  location / {
    rewrite ^ /index.php;
  }

  location ~ ^\/(?:build|tests|config|lib|3rdparty|templates|data)\/ {
    deny all;
  }
  location ~ ^\/(?:\.|autotest|occ|issue|indie|db_|console) {
    deny all;
  }

  location ~ ^\/(?:index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+)\.php(?:$|\/) {
    fastcgi_split_path_info ^(.+?\.php)(\/.*|)$;
    set $path_info $fastcgi_path_info;
    try_files $fastcgi_script_name =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $path_info;
    #This would not work yet because we dont create ssl
    #fastcgi_param HTTPS on;
    # Avoid sending the security headers twice
    fastcgi_param modHeadersAvailable true;
    # Enable pretty urls
    fastcgi_param front_controller_active true;
    fastcgi_pass php-handler;
    fastcgi_intercept_errors on;
    fastcgi_request_buffering off;
  }

  location ~ ^\/(?:updater|oc[ms]-provider)(?:$|\/) {
    try_files $uri/ =404;
    index index.php;
  }

  # Adding the cache control header for js, css and map files
  # Make sure it is BELOW the PHP block
  location ~ \.(?:css|js|woff2?|svg|gif|map)$ {
  try_files $uri /index.php$request_uri;
  add_header Cache-Control "public, max-age=15778463";

    # Optional: Don't log access to assets
    access_log off;
  }

  location ~ ^\/nextcloud\/.+[^\/]\.(?:png|html|ttf|ico|jpg|jpeg|bcmap|mp4|webm)$ {
    try_files $uri /index.php$request_uri;
    # Optional: Don't log access to other assets
    access_log off;
  }
}
Cally99 commented 4 years ago

Can someone close this off? I'm encountering this issue and the code in the example is too much to go through. What's the fix here? It's a stupid error. I had a config working before now I can't overwrite nginx's settings. This issue has been open since July.

VBart commented 4 years ago

Can someone close this off? I'm encountering this issue and the code in the example is too much to go through. What's the fix here? It's a stupid error. I had a config working before now I can't overwrite nginx's settings. This issue has been open since July.

Could you explain what the issue is? The original question was about following guide on configuring wordpress. Please, also note, that this is a bugtracker for Unit, not for nginx.

sergiycheck commented 2 years ago

Hello,

Try this:

http {
    include /etc/nginx/conf.d/*.conf;

    upstream example {
        server 127.0.0.1:8080;
    }

    server {
        location / {
            proxy_pass http://example;
            proxy_set_header Host $host;
        }
    }
}

More info: http://nginx.org/en/docs/http/ngx_http_upstream_module.html#upstream

worked for me without including conf.d/*.conf

tippexs commented 2 years ago

@sergiycheck this looks like a NGINX Proxy Configuration. This is a repository for NGINX Unit and not NGINX. If you are looking for help around NGINX check out http://nignx.org/.