From Colettapedia
Jump to navigation Jump to search


Configuration File

  • Comments start with hash #

Log Levels

  1. debug
  2. info
  3. notice
  4. warn
  5. error (default)
  6. crit
  7. alert
  8. emerg


  • nginx modules controlled by directives
  • two types of directives: simple and block directives
    • simple directive - directive name, followed by params, ends with a semicolon
    • block directives ("context") - same as simple, but instead of semicolon ends with curly braces

Common directives

  • Regular expressions parameter arguments for location directives always start with a tilde ~ and usually are between ^ and $ opperators.


  • top-level "main" context, cannot be within another


  • top-level "main" context, cannot be within another


  • Within http context only
  • Can have multiple server names
  • Once nginx decides which server will process the request, it tests the URI specified in the request's header against the location directives defined in the server block.
  • Order of precedence is longest to shortest prefix, so location '/' will match last, THEN regular expressions terminating on the first match
  • listen on different ports
    • systemctl restart nginx
    • etstat -tlpn| grep nginx
    • semanage port -l
    • semanage port -a -t http_port_t -p tcp 3200
    • semanage port -m -t http_port_t -p tcp 3200


  • server context, plus nested inside another location directive is possible, i guess?
  • Performs mapping of URL to route to static files on server, or proxy, etc.
  • The matching is performed against a normalized URI, after decoding the text encoded in the “%XX” form, resolving references to relative path components “.” and “..”, and possible compression of two or more adjacent slashes into a single slash.
  • location can be prefix string or regular expression, e.g., location URIPREFIXARG { root /path/to/static/files;}
URI tokens
  • Prefacing URI with = token sets up exact match, with search terminating immediately, speeding up processing.
  • Prefacing URI with ~ token means case-sensitive matching
  • Prefacing URI with ~* token means case-INsensitive matching
  • Prefacing URI with ^~ token means TURN REGULAR EXPRESSION MATCHING OFF for the given prefix.
  • The “@” prefix defines a named location. Such a location is not used for a regular request processing, but instead used for request redirection.

location directives
  • root path;
    • Sets the root directory for requests.
    • SIMPLE mapping URI to filepath on server.
    • Path to the file is constructed by merely adding a URI to the value of the root directive.

  • alias path;
    • Has all the functionality of root directive, plus rewrite capabilities
    • If location URI has a regular expression in it, you can use the $1, $2, etc capture groups in the argument to the alias directive.

  • try_files file1, [file2, ...] uri|=code;
    • Checks the existence of files in the specified order and uses the first found file for request processing
    • The path to a file is constructed from the file parameter according to the root and alias directives.

  • proxy_pass
    • websocket proxying requires special configuration:
      • proxy_http_version 1.1;
      • proxy_set_header Upgrade $http_upgrade;
      • proxy_set_header Connection "upgrade";
FastCGI params
  • PHP FastCGI Example
  • Variables are exported via fastcgi_param directive; many boilerplate fvars defined in /etc/nginx/fastcgi_params which is included in the nginx.conf.
  • fastcgi_pass
    • Sets the address of a FastCGI server.
    • The address can be specified as a domain name or IP address and a port, or a UNIX-domain socket

  • fastcgi_index
    • If the user requests a URI with a blank slash, this provides the default script name.
    • Maps a blank slash to the script that should be run.
    • This parameter is ignored when the usr specifies a php script or whatever after the slash
    • Sets a file name that will be appended after a URI that ends with a slash, in the value of the $fastcgi_script_name variable.
  • fastcgi_param
    • Sets a parameter that should be passed to the FastCGI server.
    • The value can contain text, variables, and their combination.
    • The minimum required settings for PHP:
      • fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
      • fastcgi_param QUERY_STRING $query_string;
    • For scripts that process POST requests, the following three parameters are also required:
      • fastcgi_param REQUEST_METHOD $request_method;
      • fastcgi_param CONTENT_TYPE $content_type;
      • fastcgi_param CONTENT_LENGTH $content_length;


  1. yum install nginx
  2. systemctl start nginx
  3. systemctl enable nginx
  4. ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
  5. yum install mariadb-server mariadb
  6. systemctl start mariadb
  7. mysql_secure_installation
  8. systemctl enable mariadb
  9. yum install php php-mysql php-fpm
  10. vi /etc/php.ini
    1. cgi.fix_pathinfo=0
  11. vi /etc/php-fpm.d/www.conf
    1. listen = /var/run/php-fpm/php-fpm.sock
    2. listen.owner = nobody
    3. = nobody
    4. user = nginx
    5. group = nginx
  12. systemctl start php-fpm
  13. systemctl enable php-fpm
  14. Configure NGINX to to PHP with fpm
  15. make a <?php phpinfo(); ?> tag and check that it works
  16. You may also have to chown -R nginx /var/lib/php/session

Configuring HTTPS

The Dance

  1. TLS handshake is a shared secret that is negotiated at the start of a session. Client connects to port 443 and presents a list of supported ciphers/hash_functions to server
  2. Server pick a cipher suite and tells the client
  3. Server provides identification in the form of a digital certificate.
  4. Yadda yadda yadda...

ssl parameter

  • put ssl parameter after listing the listening sockets on the listen line.


  • The server certificate is a public entity. It is sent to every client that connects to the server.
  • In nginx this file contains a certificate bundle or chain - a concatenation of your certificate and the certification authority (CA) certificate


  • The private key is a secure entity and it should be stored in a file with restricted access.
  • HOWEVER, it must be accessible by nginx's master process


  • Used to limit connections to include only the strong versions and ciphers of SSL/TLS
  • SSL = Secure sockets layer is COMPLETELY DEPRECATED since 2015
  • TLS = Transport Layer Security 1.0 is deprecated as of March 2020, use only 1.1, 1.2, and 1.3
    • 1.3 is the best; don't use ETS or eTLS


ssl_session_cache & ssl_session_timeout

  • Reduces CPU load
  • Default is 5 minutes, make it 10.
  • ssl_session_cache shared:SSL:10m;
  • ssl_session_timeout 10m;


  • On command line
    • openssl genpkey -genparam -algorithm DH -out /etc/pki/nginx/dhparam4096.pem -pkeyopt dh_paramgen_prime_len:4096
  • In conf file
    • ssl_dhparam /etc/pki/nginx/dhparam4096.pem;

Other directives

  • ssl_prefer_server_ciphers on;
  • keepalive_timeout 75;



  • PHP FastCGI Process Manager



  • sestatus to check enforcement
  • semanage boolean -l | grep httpd to check webserver specific booleans
  • setsebool -P httpd_can_network_connect 1
  • cat /var/log/audit/audit.log | audit2why or audit2allow to figure out what's being blocked and how to fix it

type=AVC msg=audit(1595008856.710:4589): avc:  denied  { sys_admin } for  pid=11703 comm="nginx" capability=21  scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capability permissive=0
       Was caused by:
               Missing type enforcement (TE) allow rule.
               You can use audit2allow to generate a loadable module to allow this access.
type=AVC msg=audit(1595008856.710:4590): avc:  denied  { sys_resource } for  pid=11703 comm="nginx" capability=24  scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0 tclass=capability permissive=0
       Was caused by:
       One of the following booleans was set incorrectly.
       Allow httpd to run stickshift
       Allow access by executing:
       # setsebool -P httpd_run_stickshift 1
       Allow httpd to setrlimit
       Allow access by executing:
       # setsebool -P httpd_setrlimit 1