NGINX User Guide

NGINX 用户指引

安装

CentOS

vim /etc/yum.repos.d/nginx.repo # 配置 nginx 官方 Yum 源,打开文件后,添加以下内容。
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
yum install nginx   # 安装 nginx。
systemctl enable nginx.service # 配置 nginx 为系统服务。
systemctl start nginx.service  # 启动 nginx。

macOS 

Docroot is: /usr/local/var/www

The default port has been set in /usr/local/etc/nginx/nginx.conf to 8080 so that
nginx can run without sudo.

nginx will load all files in /usr/local/etc/nginx/servers/.

To restart nginx after an upgrade:
  brew services restart nginx
Or, if you don't want/need a background service you can just run:
  /usr/local/opt/nginx/bin/nginx -g daemon off;

Ubuntu

通过第三方库安装最新的 Ubuntu 配置风格的 nginx:

sudo add-apt-repository ppa:ondrej/nginx           # Stable

通过官方库安装最新的 nginx: 

# 导入 nginx 官方库签名密钥
sudo apt-key adv --fetch-keys https://nginx.org/keys/nginx_signing.key
sudo apt-key adv --fetch-keys http://nginx.org/packages/keys/nginx_signing.key

# Ubuntu 16.04
vim /etc/apt/sources.list.d/nginx.list # 导入官方库地址

deb http://nginx.org/packages/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/ubuntu/ xenial nginx

# Ubuntu 18.04 的官方库配置
deb http://nginx.org/packages/ubuntu/ bionic nginx
deb-src http://nginx.org/packages/ubuntu/ bionic nginx

sudo apt update
sudo apt install nginx
http://nginx.org/packages/keys/nginx_signing.key

sudo sh -c "echo 'deb http://nginx.org/packages/mainline/ubuntu/ '$(lsb_release -cs)' nginx' > /etc/apt/sources.list.d/nginx.list"

动态模块

nginx 1.11.5 起支持动态模块。借助 pkg-oss 工具可把第三方扩展编译为动态扩展库安装包。注意 pkg-oss 编译的安装包需要和官方库提供的 nginx 配套使用,和 Linux 发行版自带的 nginx 并不兼容。

# Ubuntu 16.04
# 下载、解压、进入 nginx 模块编译环境
apt-get install devscripts build-essential lintian mercurial git wget apt install libssl-dev libpcre3-dev zlib1g-dev autoconf automake autopoint autotools-dev debhelper dh-autoreconf dh-strip-nondeterminism libarchive-cpio-perl libfile-stripnondeterminism-perl libltdl-dev libmail-sendmail-perl libsigsegv2 libsys-hostname-long-perl libtool m4 po-debconf quilt

export NGINX_MODULE_PATH=$(pwd)

wget https://hg.nginx.org/pkg-oss/archive/tip.tar.gz
tar zxf tip.tar.gz
cd pkg-oss<Tab 键>

# 编译模块 ./build_module.sh -v <version> <第三方模块 Git URL>
# 编译后的安装包在 -o 参数指定的目录下
mkdir -p $NGINX_MODULE_PATH/nginx-http-shibboleth
./build_module.sh -y -v 1.14.0 -o $NGINX_MODULE_PATH/nginx-http-shibboleth https://github.com/nginx-shib/nginx-http-shibboleth.git
mkdir -p $NGINX_MODULE_PATH/headers-more-nginx-module
./build_module.sh -y -v 1.14.0 -o $NGINX_MODULE_PATH/headers-more-nginx-module https://github.com/openresty/headers-more-nginx-module.git

cd $NGINX_MODULE_PATH/nginx-http-shibboleth
# dpkg -x <.deb 文件名> ./ 在当前目录解压安装包

cd $NGINX_MODULE_PATH/headers-more-nginx-module
# dpkg -x <.deb 文件名> ./ 在当前目录解压安装包

常用命令

命令 作用
nginx -t 检查配置文件是否错误。修改配置文件后务必执行,避免重启 nginx 失败

NGINX 常用配置

日志相关

Ubuntu 默认使用预定日志格式 combind:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

用户可以自定义日志格式配合 access_log 显式引用。

# 日志带相关域名
log_format main '[$time_local] $host $status | "$request" '
                '$body_bytes_sent "$http_referer" "$hostname" "$remote_addr" "$remote_user" '
                '"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

配置静态网站

server {
       listen 80;
       listen [::]:80;

       server_name <域名,如:www.moha.online>;

       root  <网站根目录,如:/var/www/html>;
       index index.htm index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

反向代理

upstream <upstream name, eg: reverse_http> {
    server localhost:3080 weight=999;
    server localhost:13080;
    server localhost:4080;
}

server {
    listen 80;
    listen [::]:80;

    server_name <域名>;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://<upstream name>;

        # WebSocks
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
    }
}

重写 favicon.ico

浏览器默认请求根目录的 favicon.ico,可在 location / 中可用 rewrite 重写到框架默认位置:

rewrite ^/favicon\.ico$ /sites/PATH/favicon.ico last;

配置 SSL

  • 准备 SSL 证书。Let's Encrypt 提供免费的 SSL 证书服务,免注册,开箱即用。访问 Certbot 选择服务器和操作系统,按照提示安装 Certbot 命令。执行 sudo certbot --nginx certonly 选择需要获取证书的域名就会自动获取 SSL 证书。
# Ubuntu
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository universe
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx 
  • 修改 server 相关的配置添加 SSL 相关配置:
server {
        listen 80;
        listen [::]:80;

        root <Path of web application root>;

        # SSL 配置
        listen 443 ssl;
        ssl_certificate /etc/letsencrypt/live/<domain name>/fullchain.pem; 
        ssl_certificate_key /etc/letsencrypt/live/<domain name>/privkey.pem;
        include /etc/letsencrypt/options-ssl-nginx.conf;
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
        ###

        index index.php index.html;

        server_name <domain name>;
}

证书格式转换

# pfx 提取 Key 及 crt 文件
openssl pkcs12 -clcerts -nokeys -out d-its.logon.ds.ge.com.crt -in d-its.logon.ds.ge.com.pfx
openssl pkcs12 -nocerts -nodes -out d-its.logon.ds.ge.com.key -in  d-its.logon.ds.ge.com.pfx 

http 的访问重定向到 https

在 server 相关的配置中加入以下逻辑即可:

    if ($scheme = http) {
        return 301 https://$server_name$request_uri;
    }

PHP-FPM 集成

安装指定版本 PHP

# Ubuntu 16.04 
sudo vim /etc/apt/sources.list.d/php.list
deb http://ppa.launchpad.net/ondrej/php/ubuntu xenial main 
deb-src http://ppa.launchpad.net/ondrej/php/ubuntu xenial main 

sudo apt-get install php7.1 php7.1-cli php7.1-common php7.1-json php7.1-opcache php7.1-mysql php7.1-mbstring php7.1-mcrypt php7.1-zip php7.1-fpm php7.1-gd php7.1-readline php7.1-xml php7.1-pgsql php7.1-bcmath php7.1-curl php7.1-gmp php7.1-bcmath
server {
    listen      80;
    listen      443 ssl;

    ssl_certificate        PATH.crt;
    ssl_certificate_key    PATH.key; 

    server_name  HOSTNAME.com;

    root ROOT_PATH/docs;

    index   index.php index.html index.htm;

    location / {
        try_files $uri /index.php?$query_string;
    }

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }

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

    # Very rarely should these ever be accessed outside of your lan
    location ~* \.(txt|log)$ {
        allow 192.168.0.0/16;
        deny all;
    }

    location ~ \..*/.*\.php$ {
        return 403;
    }

    location ~ ^/sites/.*/private/ {
        return 403;
    }

    # Allow "Well-Known URIs" as per RFC 5785
    location ~* ^/.well-known/ {
        allow all;
    }

    # Block access to "hidden" files and directories whose names begin with a
    # period. This includes directories used by version control systems such
    # as Subversion or Git to store control files.
    location ~ (^|/)\. {
        return 403;
    }

    location @rewrite {
        rewrite ^/(.*)$ /index.php?q=$1;
    }

    # Don't allow direct access to PHP files in the vendor directory.
    location ~ /vendor/.*\.php$ {
        deny all;
        return 404;
    }

    # In Drupal 8, we must also match new paths where the '.php' appears in
    # the middle, such as update.php/selection. The rule we use is strict,
    # and only allows this pattern with the update.php front controller.
    # This allows legacy path aliases in the form of
    # blog/index.php/legacy-path to continue to route to Drupal nodes. If
    # you do not have any paths like that, then you might prefer to use a
    # laxer rule, such as:
    #   location ~ \.php(/|$) {
    # The laxer rule will continue to work if Drupal uses this new URL
    # pattern with front controllers other than update.php in a future
    # release.
    location ~ '\.php$|^/update.php' {
        fastcgi_split_path_info ^(.+?\.php)(|/.*)$;
        # Security note: If you're running a version of PHP older than the
        # latest 5.3, you should have "cgi.fix_pathinfo = 0;" in php.ini.
        # See http://serverfault.com/q/627903/94922 for details.
        include fastcgi_params;
        # Block httpoxy attacks. See https://httpoxy.org/.
        fastcgi_param HTTP_PROXY "";
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param QUERY_STRING $query_string;
        fastcgi_intercept_errors on;
        # PHP 5 socket location.
        #fastcgi_pass unix:/var/run/php5-fpm.sock;
        # PHP 7 socket location.
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
    }

    # Fighting with Styles? This little gem is amazing.
    # location ~ ^/sites/.*/files/imagecache/ { # For Drupal <= 6
    location ~ ^/sites/.*/files/styles/ { # For Drupal >= 7
        try_files $uri @rewrite;
    }

    # Handle private files through Drupal. Private file's path can come
    # with a language prefix.
    location ~ ^(/[a-z\-]+)?/system/files/ { # For Drupal >= 7
        try_files $uri /index.php?$query_string;
    }

    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires max;
        log_not_found off;
    }

    fastcgi_read_timeout 6000s;
    client_max_body_size 128m;
}

配置基本认证 HTTP Basic Auth

  • 准备密钥文件,格式如下。密码可以 openssl passwd 命令生成,也可以用 htpasswd 直接处理密钥文件。
# comment
name1:password1
name2:password2:comment
name3:password3
  • 在 NGINX 配置中引用密钥文件。如以下配置保护全站资源,可以放在 server 相关设置中。
        location / {
                # 配置使用 PHP 框架的应用,比如 Drupal、WordPress、等。
                try_files $uri /index.php?$query_string;

                auth_basic "Under building...";
                auth_basic_user_file <密钥文件路径,如:/etc/.htpasswd>;
        }

隐藏服务器及 nginx 版本

server_tokens off;

常见错误

413 Request Entity Too Large

nginx 默认允许上传文件大小仅有 1MB,在 http 或 server 配置中添加以下指令扩大限制后重启 nginx 服务。

client_max_body_size 64m;

常用资料

参考链接

Author: njun
njun's picture
Updated: 2023/03/01