/ nginx

nginx

负载均衡

upstream cluster {
    server 192.168.1.100:8080;
    server 192.168.1.102:8080;
    server 192.168.1.103:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://cluster;
    }
}

fastcgi_pass 和 proxy_pass

客户端的 IP:

  • remote_addr:客户端IP
  • x_forwarded_for:客户端的IP

首先当你访问某个网站,假设你中间不经过任何代理,那么webserver就会把remote_addr当成你客户端的IP。

但是你使用代理了或者服务端有代理的情况下webserver获取的remote_addr就不准确了,这时候就需要另一个变量x_forwarded_for,他把客户端的IP加到http头里,这样就能获取到客户端的真是IP了。

fastcgi_pass

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    
    #fastcgi_pass unix:/var/run/php/php7.0-fpm.sock; # ubuntu14.04
    fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; # centos7
    
    # 如果启用了 https
    #fastcgi_param HTTPS on;
    
    try_files $uri =404;
}

fastcgi_params 的内容为:

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

我们需要向其中追加:

# 对应 PHP $_['X-Forwarded-For']
fastcgi_param HTTP_X_FORWARDED_FOR $http_x_forwarded_for;
fastcgi_param HTTP_X_REAL_IP       $http_x_real_ip;

使用CDN后,PHP如何获取用户的真是IP?

proxy_pass

location / {
    proxy_pass http://localhost:9000/;
    proxy_set_header   X-Real-IP $remote_addr;
    proxy_set_header   Host $http_host;
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
}

gzip 压缩

gzip on;
gzip_vary on;
gzip_types text/plain text/xml text/css text/javascript application/x-javascript;
gzip_com_level 4;

查看 Transferred 数值对比效果。

缓存静态文件、

# 缓存静态文件 7 天
Location ~*.(ico|jpg|jpeg|png|gif|css|js|woff)$ {
    Expires 7d;
}

安装稳定版本 1.4

查看系统安装的 nginx:

nginx -v

安装 nginx:

sudo apt-get update
sudo apt-get install nginx

升级 nginx:

sudo apt-get update
sudo apt-get upgrade nginx

卸载 nginx

sudo apt-get remove nginx nginx-full nginx-common nginx-core

多站点设置

We can use the $USER environmental variable to assign ownership to the account that we are currently signed in on (make sure you're not logged in as root). This will allow us to easily create or edit the content in this directory

sudo mkdir -p /var/www/example.com/html
sudo mkdir -p /var/www/test.com/html

sudo chown -R $USER:$USER /var/www/example.com/html
sudo chown -R $USER:$USER /var/www/test.com/html

Depending on your needs, you might need to adjust the permissions or ownership of the folders again to allow certain access to the www-data user. For instance, dynamic sites will often need this. The specific permissions and ownership requirements entirely depend on what your configuration. Follow the recommendations for the specific technology you're using.

The permissions of our web roots should be correct already if you have not modified your umask value, but we can make sure by typing:

sudo chmod -R 755 /var/www

nginx 1.10

没有了 sites-enabledsites-avaiable 。需要我们额外做些操作:

sudo mkdir sites-available
sudo mkdir sites-enabled

修改配置文件:

sudo vi /etc/nginx/nginx.conf

找到 http

  • 添加一行:include /etc/nginx/sites-enabled/*;
  • server 块剪切到 /etc/nginx/sites-available/default.conf
sudo ln -s /etc/nginx/sites-available/default.conf /etc/nginx/sites-enabled/default.conf

参考文档:nginx missing sites-available directory

升级 nginx 到1.12

如果之前安装了 nginx ,需要备份配置文件,然后卸载:

sudo apt-get purge nginx nginx-full nginx-common nginx-core
lsb_release -c 
sudo vi /etc/apt/sources.list.d/nginx.list
## Replace $release with your corresponding Ubuntu release.
deb http://nginx.org/packages/ubuntu/ trusty nginx
deb-src http://nginx.org/packages/ubuntu/ trusty nginx
sudo apt-get update

Reading package lists... Done
W: GPG error: http://nginx.org trusty InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ABF5BD827BD9BF62

## Replace $key with the corresponding $key from your GPG error.
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ABF5BD827BD9BF62
sudo apt-get update
sudo apt-get install nginx
nginx -v

1.12 的配置文件目录发生了改变,目录为:/etc/nginx/conf.d,将备份的配置文件复制到这里,确保需要生效的配置文件.conf 结尾。

sudo nginx -t
sudo nginx -s reload

Step 1: Install Nginx

sudo apt-get update
sudo apt-get install nginx

Step 2: Adjust the Firewall

Before we can test Nginx, we need to reconfigure our firewall software to allow access to the service. Nginx registers itself as a service with ufw, our firewall, upon installation. This makes it rather easy to allow Nginx access.

We can list the applications configurations that ufw knows how to work with by typing:

sudo ufw app list

You should get a listing of the application profiles:

Output

Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  SSH

As you can see, there are three profiles available for Nginx:

  • Nginx Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Nginx HTTP: This profile opens only port 80 (normal, unencrypted web traffic)
  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)

It is recommended that you enable the most restrictive profile that will still allow the traffic you've configured. Since we haven't configured SSL for our server yet, in this guide, we will only need to allow traffic on port 80.

You can enable this by typing:

sudo ufw allow 'Nginx HTTP'

You can verify the change by typing:

sudo ufw status

You should see HTTP traffic allowed in the displayed output:

Output

Status: active

To                         Action      From
--                         ------      ----
OpenSSH                    ALLOW       Anywhere                  
Nginx HTTP                 ALLOW       Anywhere                  
OpenSSH (v6)               ALLOW       Anywhere (v6)             
Nginx HTTP (v6)            ALLOW       Anywhere (v6)

Server Logs

  • /var/log/nginx/access.log: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.
  • /var/log/nginx/error.log: Any Nginx errors will be recorded in this log.

默认路径

/usr/share/nginx/html

On Ubuntu, both the Nginx and Apache web servers run as the www-data user.

/etc/nginx/nginx.conf 中 user www-data;

我们看到 nginx 服务器用户是 www-data 所以此时我们的做法是把网站根目录的权限改为 www-data:

sudo chown -R www-data:www-data /usr/share/nginx/html/*
sudo chmod -R 0755 /usr/share/nginx/html/*

初始化

# Disable the default vhost:
sudo rm /etc/nginx/sites-enabled/default

# Enable our example vhost:
sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/example

# Test the vhost configuration
sudo nginx -t

# If everything is looking good we can apply the changes to Nginx:
sudo nginx -s reload

查找进程

ps -ax | grep nginx

配置文件

  • /etc/nginx/sites-available 配置文件实体位置。
  • /etc/nginx/sites-enabled 虚拟链接,指向 available目录中的某个实体文件。

available 目录下有个 default 文件,我们可以参考它,在 available 目录下新建配置文件,然后到 enabled 目录下做一个软连接。

不要直接修改 enabled 目录下的配置文件。

基本配置

cd /etc/nginx/sites-enabled
vim mysite.conf

添加内容:

server {
  listen 80 default;
  server_name example.com www.example.com;
  gzip on;

  root /home/peter/mysite;
}

注意:上面有 default 字样,这个在一台服务器上只能出现一次,也就是只能有一个 server 是默认的,不然重启 nginx 的时候就会报错。需要 reload,上述配置才会生效

sudo service nginx reload

这样,到 example.com (或者直接输入 IP )就可以看到 mysite/index.html 中的内容了。当然,前提是 DNS 设置已经做好了。

另外的配置

hexo 配置

server {
  listen 80;
  server_name blog.example.com;

  location / {
    proxy_pass              http://127.0.0.1:3500/;
    proxy_redirect          off;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

meteor 配置

server {
    listen         80;
    server_name example.com www.example.com;

    location / {
      proxy_pass http://localhost:3000;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_x_forwarded_host;
      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_read_timeout 3m;
      proxy_send_timeout 3m;
    }
    location /blog {
      # 对应文件夹 /home/peter/blog
      root /home/peter;
    }
}

disable the default vhost:

rm /etc/nginx/sites-enabled/default

enable our Meteor vhost:

ln -s /etc/nginx/sites-available/todos /etc/nginx/sites-enabled/todos

配置示例

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

      root /var/www/example.com/html;
      index index.html index.htm index.nginx-debian.html;

      server_name example.com www.example.com;

      location / {
            try_files $uri $uri/ =404;
      }
}
server {
    listen       443 ssl http2;
    server_name  example.com;
    ssl_certificate /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
}
server {
     listen         80;
     server_name    example.com;
     return         301 https://$server_name$request_uri;
}
upstream backend_hosts {
    server host1.example.com;
    server host2.example.com;
    server host3.example.com;
}

server {
    listen 80;
    server_name example.com;

    location /proxy-me {
        proxy_pass http://backend_hosts;
    }
}

secure nginx

屏蔽 nginx 版本号

➜  ~ curl -I http://localhost
HTTP/1.1 301 Moved Permanently
Server: nginx/1.4.6 (Ubuntu)
Date: Mon, 17 Oct 2016 08:56:53 GMT
Content-Type: text/html
Content-Length: 193
Connection: keep-alive
Location: https://localhost/

➜  ~ sudo vi /etc/nginx/nginx.conf

修改 server_tokens off; > #server_tokens off;

➜  ~ sudo service nginx reload
➜  ~ curl -I http://localhost
HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Mon, 17 Oct 2016 08:59:10 GMT
Content-Type: text/html
Content-Length: 178
Connection: keep-alive
Location: https://localhost/

安装 nginx

Ubuntu 16.04 安装 nginx

如果系统安装了 Apache 需要先卸载:

sudo systemctl status apache2
sudo systemctl stop apache2
sudo apt-get remove --purge apache2
sudo apt install nginx
sudo systemctl start nginx
sudo systemctl status nginx
sudo systemctl enable nginx

查看 nginx 运行的用户名:

more /etc/nginx/nginx.conf

userwww-data,修改下网站文件的根目录权限:

sudo chown -R 你的用户名:www-data /var/www/html

如果之后文件夹中又新增了文件,需要锁定下文件权限:

sudo chown -R 你的用户名 /var/www/html

常见问题

nginx 无法重启

➜  nginx sudo nginx -c /etc/nginx/nginx.conf
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Address already in use)

Then it means nginx or some other process is already using port 80.

You can kill it using:

sudo fuser -k 80/tcp

And then try restarting nginx again:

sudo systemctl start nginx

屏蔽爬虫

屏蔽前测试:

curl -I -A "Scrapy" haobing.wang
curl -I -A "YisouSpider" haobing.wang
vi agent_deny.conf
# 禁止指定 ua 访问
if ($http_user_agent ~* "YisouSpider|Scrapy") {
  return 403;
}

然后,在网站相关配置中的 server段插入如下代码:include agent_deny.conf;

sudo nginx -t
sudo nginx -s reload

屏蔽后测试:

curl -I -A "Scrapy" haobing.wang
curl -I -A "YisouSpider" haobing.wang

404

root@a8cbfa1e38d9:/# cat /var/log/nginx/error.log

2014/07/30 11:23:23 [crit] 370#0: *1 stat() "/usr/share/nginx/html/" failed (13: Permission denied), client: ::1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"

root@a8cbfa1e38d9:/# ps -ef

nginx      953   951  0 Apr26 ?        00:00:11 php-fpm: pool www
nginx      954   951  0 Apr26 ?        00:00:13 php-fpm: pool www
nginx      955   951  0 Apr26 ?        00:00:13 php-fpm: pool www
nginx      956   951  0 Apr26 ?        00:00:13 php-fpm: pool www
nginx      963   951  0 Apr26 ?        00:00:13 php-fpm: pool www
root@a8cbfa1e38d9:/# which setfacl
root@a8cbfa1e38d9:/# getfacl apps/
# file: apps/
# owner: deploy
# group: deploy
user::rwx
group::rwx
other::r-x