linux_wiki:nginx_http_server

Nginx HTTP Server

General Information

Installation and configuration of Nginx web server.

Checklist

  • Distro(s): Enterprise Linux 6/7

Installation

Installation of Nginx can be completed via repo (Official Nginx, EPEL, or Software Collections) or compiling.

Nginx.org has pre-built packages. You can select mainline (newer) or stable.

Versions as of 04/13/2016:

  • Mainline: 1.9.14
  • Stable: 1.8.1
  • Legacy: 1.6.3 and below
  1. Import nginx gpg signing key
    rpm --import http://nginx.org/keys/nginx_signing.key
  2. Add a nginx repo file
    • Stable Repo:
      vim /etc/yum.repos.d/nginx.repo
      [nginx]
      name=nginx repo
      baseurl=http://nginx.org/packages/centos/7/$basearch/
      gpgcheck=0
      enabled=1
    • Mainline Repo:
      vim /etc/yum.repos.d/nginx.repo
      [nginx]
      name=nginx repo
      baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
      gpgcheck=0
      enabled=1
  3. Install
    yum install nginx

Versions as of 04/13/2016

  • CentOS 7.2: Nginx 1.6.3

Procedure

  • Install the EPEL repo
  • Install Nginx
    yum install nginx

Versions as of 04/13/2016:

  • nginx 1.4 (legacy)
  • nginx 1.6 (legacy)
  • nginx 1.8 (stable)
  1. Install
    yum install rh-nginx18
  2. Enable the software collection
    scl enable rh-nginx18 bash
    1. Run signal commands (nginx -s signal) as normal from the Operation section below

Building from source is usually done for specific functionality and is more time consuming.

  1. Install pre-reqs
    yum install gcc pcre-devel zlib-devel
  2. Download a tarball (Example: Stable)
    wget http://nginx.org/download/nginx-1.8.1.tar.gz
  3. Unarchive/unpack
    tar -zxvf nginx-1.8.1.tar.gz
  4. Change into directory
    cd nginx-1.8.1/
  5. Configure nginx
    ./configure --prefix=/usr/local/nginx
    1. Available configuration options: http://nginx.org/en/docs/configure.html
  6. Compile
    make
  7. Install
    make install

Configuration

  • Main Config: /etc/nginx/nginx.conf
    • Alt Main (Compiled): /usr/local/nginx/conf/nginx.conf
    • Alt Main (Software Collections): /etc/opt/rh/rh-nginx18/nginx/nginx.conf
  • Additional Config: /etc/nginx/conf.d/
    • Alt Additional Config (Compiled): No default
    • Alt Additional Config (Software Collections): /etc/opt/rh/rh-nginx18/nginx/conf.d/

  • Default repo installed file location: /etc/nginx/nginx.conf

Main nginx.conf config file, in the http context

## NGINX - Main Configuration ##
 
# Context: Main - General Server Configuration
 
# User that worker processes run as
user  nginx;
 
# Number of worker processes (auto = set to number of CPUs)
worker_processes  auto;
 
# Error Log and PID of main process
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
 
 
# Context: Events - Connection Processing
events {
  # Max number of connections per worker process
  worker_connections  1024;
}
 
# Context: HTTP - HTTP Server Directives
http {
  # MIME - Include file and default type
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
 
  # Logging: Format and Main Access Log
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
 
  # server_tokens off - Disable nginx version on error pages and response headers
  server_tokens off;
 
  ## Headers - Add additional headers ##
  # X-Frame-Options SAMEORIGIN -> Page can only be displayed in a frame on same origin
  add_header X-Frame-Options SAMEORIGIN;
 
  # X-Content-Type-Options nosniff -> Prevent MIME Type Attacks
  add_header X-Content-Type-Options nosniff;
 
  # X-XSS-Protection "1; mode=block" -> Prevent Some Cross Site Scripting
  #   1;mode=block -> XSS filter enabled, prevent rendering the page if attack detected
  add_header X-XSS-Protection "1; mode=block" always;
 
  # Content-Security-Policy -> Prevent XSS, clickjacking, code injection
  add_header Content-Security-Policy "default-src 'self';" always;
 
  # Combined directives: sendfile, tcp_nopush, tcp_nodelay all on
  # sendfile+tcp_nopush = use kernel dma to fill packets up to MSS, then send
  # tcp_nodelay = once the last packet is reached, tcp_nopush auto turned off,
  #               then tcp_nodelay forces the fast sending of the last data
 
  # Sendfile - Send files directly in kernel space
  # on -> keep on for locally stored files
  # off -> turn off for files served over network mounted storage
  sendfile        on;
 
  # tcp_nopush - Do not send data until packet reaches MSS
  # Dependency: sendfile MUST be on for this to work
  #tcp_nopush     on;
 
  # tcp_nodelay -  Send packets in buffer as soon as they are available
  #tcp_nodelay on;
 
  # Server side keepalive timeout in seconds (default: 75)
  keepalive_timeout  65;
 
  # Gzip - Compress responses using gzip
  #gzip  on;
 
  # Include enabled configurations
  include /etc/nginx/conf.d/enabled/*.conf;
}

  • Create the available/enabled directories
    mkdir /etc/nginx/conf.d/{available,enabled}
  • Remove default installed config
    rm /etc/nginx/conf.d/default.conf
  • Create new default site/catch all config file
    vim /etc/nginx/conf.d/available/default.conf
     
    ## Default Config - Catch All Matches ##
     
    # HTTP (Port 80)
    server {
        listen 80 default_server;
        server_name  _;
     
        # Redirect everything to HTTPS
        return 301 https://$http_host$request_uri;
    }
     
    # HTTPS (Port 443)
    server {
        listen 443 ssl default_server;
        listen [::]:443 ssl default_server;
        server_name _;
     
        # HSTS (HTTPS Strict Transport Security)
        # 63072000 seconds = 2 years
        add_header Strict-Transport-Security "max-age=63072000; includeSubdomains" always;
     
        # SSL - Certificate Config
        ssl on;
        ssl_certificate /etc/pki/tls/mycert.crt;
        ssl_certificate_key /etc/pki/tls/mykey.key;
        ssl_client_certificate /etc/pki/tls/myca.crt;
     
        # SSL - Session Config
        ssl_session_timeout 5m;
        ssl_session_cache shared:SSL:50m;
     
        # SSL - Protocols and Ciphers
        ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "HIGH:!AECDH:!DHE:!EDH:!RC4:!ADH:!3DES:!MEDIUM";
     
        # Location: Webserver root
        location / {
          # autoindex off - Disable directory listing output
          autoindex off;
          root /usr/share/nginx/html;
          index index.html index.htm;
        }
    }
  • Create symlink in enabled directory to default config
    ln -s /etc/nginx/conf.d/available/default.conf /etc/nginx/conf.d/enabled/default.conf
  • Deploy your SSL certificates.

Once the base config is in place, site specific config can be added.

  • Copy the default config to a new file
    cp /etc/nginx/conf.d/available/default.conf /etc/nginx/conf.d/available/mysite.org.conf
  • Edit the new file
    /etc/nginx/conf.d/available/mysite.org.conf
    • Replace server_name directives with system's fully qualified hostname. Example:
      server_name  mywebserver.org;
    • Remove “default_server” from the listen directives
      listen 80;
      listen 443 ssl;
    • Make any other additional site specific config changes.
  • Create symlink to enable the new site
    ln -s /etc/nginx/conf.d/available/mysite.org.conf /etc/nginx/conf.d/enabled/mysite.org.conf
  • Disable the default.conf catch all config if you don't want it to function on a non-match to your site specific config
    unlink /etc/nginx/conf.d/enabled/default.conf
  • Restart nginx for changes to take affect
    • CentOS 6
      /etc/init.d/nginx restart
    • CentOS 7
      systemctl restart nginx

Nginx can function as a reverse proxy. This is particularly useful for:

  • Accepting connections on secure standard ports and forwarding them to non-secure/standard ports for applications
  • Sitting in front of an application server (that might be listening on localhost)
  • Load balancing

This example accepts connections on standard port 443/tcp and forwards the request to a Java application listening on localhost, port 8080/tcp.

server {
....
# Location: Reverse Proxy to Java App
    location /myapp/ {
      # Forward /myapp/ requests to correct port
      proxy_pass http://127.0.0.1:8080/myapp/;
 
      # Additional headers to pass
      proxy_set_header        Host            $host;
      proxy_set_header        X-Real-IP       $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

  • Default file location: /etc/nginx/nginx.conf OR an included file

All in one copy/paste most secure SSL settings.

ssl_protocols TLSv1.2;
ssl_ciphers "HIGH:!MEDIUM:!3DES:!ADH:!AECDH:!DHE:!EDH:!RC4";
ssl_prefer_server_ciphers on;

Protocols - Use only TLS (1.2 only if possible)

  • TLSv1.2 only (Preferred)
    ssl_protocols TLSv1.2;
  • TLS
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;

Ciphers - Config

ssl_ciphers "HIGH:!MEDIUM:!3DES:!ADH:!AECDH:!DHE:!EDH:!RC4";


Ciphers - Server picks compatible cipher

ssl_prefer_server_ciphers on;

Other secure settings.

Redirect all HTTP to HTTPS

server {
    listen 80 default_server;
    server_name  _;
 
    # Redirect everything to HTTPS
    return 301 https://$http_host$request_uri;
}

Enabling HTTPS Strict Transport Security (HSTS).

Add the strict transport security header to the listening HTTPS server section

server {
  listen 443 ssl;
  listen [::]:443 ssl;
  server_name HOSTNAME-HERE;
 
  # HSTS (HTTPS Strict Transport Security)
  # 63072000 seconds = 2 years
  add_header Strict-Transport-Security "max-age=63072000; includeSubdomains" always;
....
}
  • max-age=63072000 → Tell web browsers to connect to the site using HTTPS only for two years. Countdown is reset each time the site is visited.

Operation

Controlling the nginx web server.

Nginx can be controlled via the system's service commands or nginx executable signals.

  • Main nginx executable: /usr/sbin/nginx
    • Alt main nginx executable (Compiled): /usr/local/nginx/sbin/nginx
    • Alt main nginx executable (Software Collections): /opt/rh/rh-nginx18/root/sbin/nginx

Note: If using the software collections method, that environment must be enabled before you attempt to operate the web server.

scl enable rh-nginx18 bash
  • This could be put in a user's .bashrc for easier use if needed.

  • Autostart the nginx web server upon system startup
systemctl enable nginx

  • Evaluate config files; if syntax is ok, start
systemctl start nginx

or

nginx

  • Stop the nginx processes now
  • Kills current sessions
systemctl stop nginx

or

nginx -s stop

  • Equivalent to Apache httpd's “graceful” restart
  • Check syntax
    • if ok, then spawn new workers with new config and signal old workers to shutdown after current requests are complete
    • if NOT ok, continue using old configuration
systemctl reload nginx

or

nginx -s reload

  • Kill worker processes immediately
systemctl restart nginx

or

nginx -s stop && nginx -s start

  • Equivalent to Apache httpd's “graceful-stop”
  • Wait for worker processes to finish serving current requests, then stop.
  • Do not accept new requests
nginx -s quit

  • linux_wiki/nginx_http_server.txt
  • Last modified: 2019/05/25 23:50
  • (external edit)