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。

Ubuntu

# 导入 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 常用配置

日志相关

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

配置静态网站

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>;
    }
}

配置 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
    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.0-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: 2019/08/23