├── .gitignore ├── 2z ├── nginx.repo └── nginx.service ├── 3z ├── events.md ├── example.md ├── global.md ├── http.md └── server.md ├── 4z ├── IO.md ├── event.md ├── event2.png ├── jg.md ├── module.md ├── nginx_event.png ├── nginx_jg.png ├── nginx_m.jpg ├── nginx_module.jpg ├── nginx_phase.png └── request_process.md ├── LICENSE ├── Nginx_dg.png ├── README.md ├── access ├── auth.md ├── deny_allow.md ├── document_uri.md ├── limit.md ├── location.md ├── referer.md ├── request_uri.md └── user_agent.md ├── http ├── http.md ├── http_request.jpg └── version.md ├── java └── nginx_tomcat.md ├── lnmp └── nginx_php.md ├── location ├── priority.md └── ruler.md ├── log ├── acclog.md ├── error.md ├── filter.md ├── format.md └── rotate.md ├── mon └── stat.md ├── optimize ├── linux_kernel.md └── nginx_opt.md ├── proxy ├── bu_ca.md ├── f_proxy.md ├── f_proxy.png ├── fp2.png ├── lb.md ├── nginx_cache_levels.png ├── pic.md ├── stream.md ├── z_proxy.md ├── z_proxy.png └── zp2.png ├── rewrite ├── break.md ├── example.md ├── if.md ├── return.md ├── rewrite_ruler.md └── variable.md └── ssl ├── ca.md ├── ca_tree.png ├── key.md ├── nginx.md ├── ssl.jpg ├── ssl.md ├── ssl_auth.jpg └── ssl_ca.png /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/.gitignore -------------------------------------------------------------------------------- /2z/nginx.repo: -------------------------------------------------------------------------------- 1 | [nginx] 2 | name=nginx repo 3 | baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ 4 | gpgcheck=0 5 | enabled=1 -------------------------------------------------------------------------------- /2z/nginx.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=nginx - high performance web server 3 | Documentation=http://nginx.org/en/docs/ 4 | After=network-online.target remote-fs.target nss-lookup.target 5 | Wants=network-online.target 6 | 7 | [Service] 8 | Type=forking 9 | PIDFile=/usr/local/nginx/logs/nginx.pid 10 | ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf 11 | ExecReload=/bin/kill -s HUP $MAINPID 12 | ExecStop=/bin/kill -s TERM $MAINPID 13 | 14 | [Install] 15 | WantedBy=multi-user.target 16 | -------------------------------------------------------------------------------- /3z/events.md: -------------------------------------------------------------------------------- 1 | ### events配置部分 2 | 3 | #### worker_connections 1024; 4 | 5 | 定义每个work_process同时开启的最大连接数,即允许最多只能有这么多连接。 6 | 7 | #### accept_mutex on; 8 | 9 | 当某一个时刻只有一个网络连接请求服务器时,服务器上有多个睡眠的进程会被同时叫醒,这样会损耗一定的服务器性能。 10 | Nginx中的accept_mutex设置为on,将会对多个Nginx进程(worker processer)接收连接时进行序列化,防止多个进程争抢资源。 11 | 默认就是on。 12 | 13 | #### multi_accept on; 14 | 15 | nginx worker processer可以做到同时接收多个新到达的网络连接,前提是把该参数设置为on。 16 | 默认为off,即每个worker process一次只能接收一个新到达的网络连接。 17 | 18 | #### use epoll; 19 | 20 | Nginx服务器提供了多个事件驱动器模型来处理网络消息。 21 | 其支持的类型有:select、poll、kqueue、epoll、rtsing、/dev/poll以及eventport。 22 | 23 | * select:只能在Windows下使用,这个事件模型不建议在高负载的系统使用 24 | 25 | * poll:Nginx默认首选,但不是在所有系统下都可用 26 | 27 | * kqueue:这种方式在FreeBSD 4.1+, OpenBSD2.9+, NetBSD 2.0, 和 MacOS X系统中是最高效的 28 | 29 | * epoll: 这种方式是在Linux 2.6+内核中最高效的方式 30 | 31 | * rtsig:实时信号,可用在Linux 2.2.19的内核中,但不适用在高流量的系统中 32 | 33 | * /dev/poll: Solaris 7 11/99+,HP/UX 11.22+, IRIX 6.5.15+, and Tru64 UNIX 5.1A+操作系统最高效的方式 34 | 35 | * eventport: Solaris 10最高效的方式 36 | -------------------------------------------------------------------------------- /3z/example.md: -------------------------------------------------------------------------------- 1 | ``` 2 | user nobody; # 定义运行nginx服务的用户,还可以加上组,如 user nobody nobody 3 | 4 | worker_processes 8; #开启8个工作进程 5 | worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000; #将8个工作进程固定在8个cpu上 6 | 7 | #以下为4核CPU的范例 8 | #worker_processes 4; 9 | #worker_cpu_affinity 0001 0010 0100 1000; 10 | 11 | error_log logs/error.log crit; #定义错误日志的路径和级别。错误日志级别:常见的错误日志级别有[debug|info|notice|warn|error|crit|alert|emerg],级别越高记录的信息越少。 12 | 13 | pid logs/nginx.pid; #定义nginx进程pid文件所在路径,可以是相对路径,也可以是绝对路径。 14 | 15 | worker_rlimit_nofile 1024000; #定义nginx最多打开文件数限制。如果没设置的话,这个值为操作系统(ulimit -n)的限制保持一致。 16 | 17 | events { 18 | 19 | use epoll; #Nginx服务器提供了多个事件驱动器模型来处理网络消息。epol这种方式是在Linux 2.6+内核中最高效的方式 20 | worker_connections 65535; #定义每个work_process同时开启的最大连接数,即允许最多只能有这么多连接。 21 | accept_mutex on; #当某一个时刻只有一个网络连接请求服务器时,服务器上有多个睡眠的进程会被同时叫醒,这样会损耗一定的服务器性能。Nginx中的accept_mutex设置为on,将会对多个Nginx进程(worker processer)接收连接时进行序列化,防止多个进程争抢资源。 22 | multi_accept on; #nginx worker processer可以做到同时接收多个新到达的网络连接,前提是把该参数设置为on。默认为off,即每个worker process一次只能接收一个新到达的网络连接。 23 | } 24 | 25 | http { 26 | include /etc/nginx/mime.types; # 定义nginx能识别的网络资源媒体类型(如,文本、html、js、css、流媒体等 27 | default_type application/octet-stream; #定义默认的type,如果不定义该项,默认为text/plain. 28 | client_max_body_size 1024M; #定义允许最大可以上传多大的文件,超过该值就会报413 29 | log_format main '$remote_addr $http_x_forwarded_for [$time_local]' 30 | '$host "$request_uri" $status' 31 | '"$http_referer" "$http_user_agent"'; 32 | #这里定义日志的格式,其中main为日志格式的名字,后面的为nginx的内部变量组成的一串字符串。 33 | sendfile on; #使用内核的FD文件传输功能,可以减少user mode和kernel mode的切换,从而提升服务器性能。 34 | sendfile_max_chunk 128k; #该参数限定Nginx worker process每次调用sendfile()函数传输数据的最大值,默认值为0,如果设置为0则无限制。 35 | tcp_nopush on; #设置为on时,会调用tcp_cork方法进行数据传输。当应用程序产生数据时,内核不会立马封装包,而是当数据量积累到一定量时才会封装,然后传输。 36 | tcp_nodelay on; #不缓存data-sends(关闭 Nagle 算法),这个能够提高高频发送小数据报文的实时性。 37 | server_tokens off;#将Nginx版本信息关闭,提升安全性。 38 | keepalive_timeout 65 60; #该参数有两个值,第一个值设置nginx服务器与客户端会话结束后仍旧保持连接的最长时间,单位是秒,默认为75s。第二个值可以省略,它是针对客户端的浏览器来设置的,可以通过curl -I看到header信息中有一项Keep-Alive: timeout=60,如果不设置就没有这一项。第二个数值设置后,浏览器就会根据这个数值决定何时主动关闭连接,Nginx服务器就不操心了。但有的浏览器并不认可该参数。 39 | send_timeout 10; #这个超时时间是发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。如果某个连接超过send_timeout定义的超时时间,那么Nginx将会关闭这个连接。 40 | client_header_timeout 15; #客户端如果在该指定时间内没有加载完头部数据,则断开连接,单位是秒,默认60,可以设置为15。 41 | client_body_timeout 120; #客户端如果在该指定时间内没有加载完body数据,则断开连接,单位是秒,默认60,建议大一点,因为有时候下载大文件时间会比较久。 42 | client_body_buffer_size 128k; #当客户端以POST方法提交一些数据到服务端时,会先写入到client_body_buffer中,如果buffer写满会写到临时文件里。 43 | client_header_buffer_size 4k; #客户端请求头部的缓冲区大小,这个可以根据你的系统分页大小来设置,一般一个请求头的大小不会超过1k,不过由于一般系统分页都要大于1k,所以还是要大一些。 44 | large_client_header_buffers 4 8k; #对于比较大的header(超过client_header_buffer_size)将会使用该部分buffer,两个数值,第一个是个数,第二个是每个buffer的大小。 45 | open_file_cache max=204800 inactive=20s; #max设定缓存文件的数量,inactive设定经过多长时间文件没被请求后删除缓存。 46 | open_file_cache_min_uses 1; #open_file_cache指令中的inactive参数时间内文件的最少使用次数,如,将该参数设置为1,则表示,如果文件在inactive时间内一次都没被使用,它将被移除。 47 | open_file_cache_valid 30s; #指多长时间检查一次缓存的有效信息。建议设置为30s。 48 | 49 | gzip on; #开启gzip功能 50 | gzip_min_length 1024; #设置请求资源超过该数值才进行压缩,单位字节 51 | gzip_buffers 16 8k; #设置压缩使用的buffer大小,第一个数字为数量,第二个为每个buffer的大小 52 | gzip_comp_level 6; #设置压缩级别,范围1-9,9压缩级别最高,也最耗费CPU资源 53 | gzip_types text/plain text/xhtml text/css text/js text/csv application/javascript application/x-javascript application/json application/xml text/xml application/atom+xml application/rss+xml application/vnd.android.package-archive application/vnd.iphone; #指定哪些类型的文件需要压缩 54 | gzip_disable "MSIE 6\."; #IE6浏览器不启用压缩 55 | gzip_proxied any; #Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。 56 | 57 | include conf.d/*.conf; #要加载conf.d/下的所有.conf配置文件 58 | } 59 | 60 | 61 | ##以下为conf.d/example.conf的内容 62 | server { 63 | 64 | listen 443; #监听端口为443,可以自定义其他端口,也可以加上IP地址,如,listen 127.0.0.1:8080; 65 | server_name aaa.com aaa.net; #定义网站域名,可以写多个,用空格分隔。 66 | #以下配置为开启ssl认证 67 | ssl_certificate sslkey/www.crt; #指定crt文件路径 68 | ssl_certificate_key sslkey/www.key; #指定私钥文件路径 69 | ssl_session_cache shared:SSL:10m; #设置ssl会话使用的缓存为10M 70 | ssl_session_timeout 10m; #ssl会话超时时间为10分钟 71 | ssl_protocols TLSv1.1 TLSv1.2; #ssl版本,不要加1.0了,1.0不安全 72 | ssl_ciphers AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:!aNULL:!eNULL:!MD5:!DH:!ECDH:!DHE:!ECDHE:!RC4:!EXPORT; #开启或者关闭指定算法,这些是安全漏洞工具建议的配置 73 | ssl_prefer_server_ciphers on; #如果不指定默认为off,当为on时,服务器加密算法将优于客户端加密算法。 74 | 75 | access_log logs/host.access.log main; #定义访问日志,可以针对每一个server(即每一个站点)设置它们自己的访问日志。 76 | 77 | ##在server{}里有很多location配置段 78 | location / { 79 | root html; #定义网站根目录,目录可以是相对路径也可以是绝对路径。 80 | index index.html index.htm; #定义站点的默认页。 81 | } 82 | 83 | error_page 404 /404.html; #定义404页面 84 | error_page 500 502 503 504 /50x.html; #当状态码为500、502、503、504时,则访问50x.html 85 | location = /50x.html { 86 | root html; #定义50x.html所在路径 87 | } 88 | 89 | #定义哪些目录下的php不能访问,一般要限制所有可写的目录下的php 90 | location ~ .*(data|config|template|attachments|forumdata|attachment|images|log|conf|cache)/.*\.php$ { 91 | deny all; 92 | } 93 | 94 | #设置防盗链,不记录日志,缓存过期时间为7天 95 | location ~* ^.+\.(swf|jpg|gif|bmp|png|jpeg|zip|rar)$ { 96 | expires 7d; 97 | access_log /dev/null; 98 | valid_referers none blocked server_names *.aaa.net *.aaa.com; 99 | if ($invalid_referer) { 100 | return 403; 101 | } 102 | } 103 | #js、css不记录日志,缓存过期时间为7天 104 | location ~ .*\.(js|css)$ 105 | { 106 | expires 7d; 107 | access_log off; 108 | } 109 | 110 | #针对php的配置 111 | location ~ \.php$ { 112 | #fastcgi_pass unix:/tmp/55188_71-fpm.sock; 113 | fastcgi_pass 127.0.0.1:9005; #这个是php-fpm的监听端口,nginx会把php的请求转发给php-fpm处理 114 | fastcgi_index index.php; 115 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 116 | fastcgi_param X-Real-IP $remote_addr; 117 | include fastcgi_params; 118 | } 119 | 120 | #针对admin.php做限制 121 | location /admin.php 122 | { 123 | allow 12.13.12.12; #允许的ip 124 | allow 22.22.22.0/24; #允许的ip段 125 | deny all; 126 | } 127 | 128 | } 129 | 130 | ## 反向代理示例 131 | server { 132 | listen 80; 133 | server_name bbb.com; 134 | proxy_buffering on; #该参数设置是否开启proxy的buffer功能, 如果这个设置为off,那么proxy_buffers和proxy_busy_buffers_size这两个指令将会失效 135 | proxy_buffer_size 4k; #该参数用来设置header缓存的大小,不能低于4k 136 | proxy_buffers 8 4k; #这个参数设置存储被代理服务器上的数据所占用的buffer的个数和每个buffer的大小。 137 | proxy_busy_buffers_size 16k; #在所有的buffer里,我们需要规定一部分buffer把自己存的数据传给A,这部分buffer就叫做busy_buffer,该参数用来设置处于busy状态的buffer有多大。 138 | proxy_temp_path /tmp/nginx_proxy_tmp 1 2; #定义proxy的临时文件存在目录以及目录的层级,1表示层级1的目录名为一个数字(0-9),2表示层级2目录名为2个数字(00-99) 139 | proxy_max_temp_file_size 100M; #设置临时文件的总大小 140 | proxy_temp_file_write_size 16k; #设置同时写入临时文件的数据量的总大小 141 | 142 | location / 143 | { 144 | proxy_pass http://123.23.13.11/; #后端服务器的ip地址 145 | proxy_set_header Host $host; #访问后端服务器时,用哪个域名访问呢,这里的$host就是server_name。 146 | proxy_set_header X-Real-IP $remote_addr; # 用来设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。 147 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #同上 148 | } 149 | } 150 | ``` 151 | -------------------------------------------------------------------------------- /3z/global.md: -------------------------------------------------------------------------------- 1 | ### nginx.conf全局配置 2 | 3 | #### user nobody; 4 | 5 | 定义运行nginx服务的用户,还可以加上组,如 user nobody nobody; 6 | 7 | #### worker_processes 1; 8 | 9 | 定义nginx子进程数量,即提供服务的进程数量,该数值建议和服务cpu核数保持一致。 10 | 除了可以定义数字外,还可以定义为auto,表示让系统自动调整。 11 | 12 | #### error_log logs/error.log; 13 | 14 | 定义错误日志的路径,可以是相对路径(相对prefix路径的),也可以是绝对路径。 15 | 该配置可以在此处定义,也可以定义到http、server、location里 16 | 17 | #### error_log logs/error.log notice; 18 | 19 | 定义错误日志路径以及日志级别. 20 | 错误日志级别:常见的错误日志级别有[debug|info|notice|warn|error|crit|alert|emerg],级别越高记录的信息越少。 21 | 如果不定义默认是error 22 | 23 | 24 | #### pid logs/nginx.pid; 25 | 26 | 定义nginx进程pid文件所在路径,可以是相对路径,也可以是绝对路径。 27 | 28 | #### worker_rlimit_nofile 100000; 29 | 30 | 定义nginx最多打开文件数限制。如果没设置的话,这个值为操作系统(ulimit -n)的限制保持一致。 31 | 把这个值设高,nginx就不会有“too many open files”问题了。 32 | -------------------------------------------------------------------------------- /3z/http.md: -------------------------------------------------------------------------------- 1 | ### http配置部分 2 | 3 | ##### 官方文档 http://nginx.org/en/docs/ 4 | 5 | ##### 参考链接: https://segmentfault.com/a/1190000012672431 6 | 7 | ##### 参考链接: https://segmentfault.com/a/1190000002797601 8 | 9 | ##### 参考链接:http的header https://kb.cnblogs.com/page/92320/ 10 | 11 | 12 | #### MIME-Type 13 | include mime.types; //cat conf/mime.types 14 | 定义nginx能识别的网络资源媒体类型(如,文本、html、js、css、流媒体等) 15 | 16 | default_type application/octet-stream; 17 | 定义默认的type,如果不定义该项,默认为text/plain. 18 | 19 | #### log_format 20 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 21 | '$status $body_bytes_sent "$http_referer" ' 22 | '"$http_user_agent" "$http_x_forwarded_for"'; 23 | 24 | 其中main为日志格式的名字,后面的为nginx的内部变量组成的一串字符串。 25 | 26 | #### access_log logs/access.log main; 27 | 28 | 定义日志的路径以及采用的日志格式,该参数可以在server配置块中定义。 29 | 30 | 31 | #### sendfile on; 32 | 33 | 是否调用sendfile函数传输文件,默认为off,使用sendfile函数传输,可以减少user mode和kernel mode的切换,从而提升服务器性能。 34 | 对于普通应用设为 on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。 35 | 36 | #### sendfile_max_chunk 128k; 37 | 38 | 该参数限定Nginx worker process每次调用sendfile()函数传输数据的最大值,默认值为0,如果设置为0则无限制。 39 | 40 | #### tcp_nopush on; 41 | 42 | 当tcp_nopush设置为on时,会调用tcp_cork方法进行数据传输。 43 | 使用该方法会产生这样的效果:当应用程序产生数据时,内核不会立马封装包,而是当数据量积累到一定量时才会封装,然后传输。这样有助于解决网络堵塞问题。 44 | 默认值为on。举例:快递员收快递、发快递,包裹累积到一定量才会发,节省运输成本。 45 | 46 | #### keepalive_timeout 65 60; 47 | 48 | 该参数有两个值,第一个值设置nginx服务器与客户端会话结束后仍旧保持连接的最长时间,单位是秒,默认为75s。 49 | 第二个值可以省略,它是针对客户端的浏览器来设置的,可以通过curl -I看到header信息中有一项Keep-Alive: timeout=60,如果不设置就没有这一项。 50 | 第二个数值设置后,浏览器就会根据这个数值决定何时主动关闭连接,Nginx服务器就不操心了。但有的浏览器并不认可该参数。 51 | 52 | #### send_timeout 53 | 54 | 这个超时时间是发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。 55 | 如果某个连接超过send_timeout定义的超时时间,那么Nginx将会关闭这个连接。 56 | 57 | #### client_max_body_size 10m; 58 | 59 | 浏览器在发送含有较大HTTP包体的请求时,其头部会有一个Content-Length字段,client_max_body_size是用来限制Content-Length所示值的大小的。 60 | 这个限制包体的配置不用等Nginx接收完所有的HTTP包体,就可以告诉用户请求过大不被接受。会返回413状态码。 61 | 例如,用户试图上传一个1GB的文件,Nginx在收完包头后,发现Content-Length超过client_max_body_size定义的值, 62 | 就直接发送413(Request Entity Too Large)响应给客户端。 63 | 64 | #### gzip on; 65 | 66 | 是否开启gzip压缩。 67 | 68 | #### gzip_min_length 1k; 69 | 70 | 设置允许压缩的页面最小字节数,页面字节数从header头得content-length中进行获取。默认值是20。建议设置成大于1k的字节数,小于1k可能会越压越大。 71 | 72 | #### gzip_buffers 4 16k; 73 | 74 | 设置系统获取几个单位的buffer用于存储gzip的压缩结果数据流。4 16k代表分配4个16k的buffer。 75 | 76 | #### gzip_http_version 1.1; 77 | 78 | 用于识别 http 协议的版本,早期的浏览器不支持 Gzip 压缩,用户会看到乱码,所以为了支持前期版本加上了这个选项。 79 | 如果你用了Nginx反向代理并期望也启用Gzip压缩的话,由于末端通信是http/1.1,故请设置为 1.1。 80 | 81 | #### gzip_comp_level 6; 82 | 83 | gzip压缩比,1压缩比最小处理速度最快,9压缩比最大但处理速度最慢(传输快但比较消耗cpu) 84 | 85 | #### gzip_types mime-type ... ; 86 | 87 | 匹配mime类型进行压缩,无论是否指定,”text/html”类型总是会被压缩的。 88 | 在conf/mime.conf里查看对应的type。 89 | 90 | 示例:gzip_types text/plain application/x-javascript text/css text/html application/xml; 91 | 92 | #### gzip_proxied any; 93 | 94 | Nginx作为反向代理的时候启用,决定开启或者关闭后端服务器返回的结果是否压缩,匹配的前提是后端服务器必须要返回包含”Via”的 header头。 95 | 96 | 以下为可用的值: 97 | off - 关闭所有的代理结果数据的压缩 98 | expired - 启用压缩,如果header头中包含 "Expires" 头信息 99 | no-cache - 启用压缩,如果header头中包含 "Cache-Control:no-cache" 头信息 100 | no-store - 启用压缩,如果header头中包含 "Cache-Control:no-store" 头信息 101 | private - 启用压缩,如果header头中包含 "Cache-Control:private" 头信息 102 | no_last_modified - 启用压缩,如果header头中不包含 "Last-Modified" 头信息 103 | no_etag - 启用压缩 ,如果header头中不包含 "ETag" 头信息 104 | auth - 启用压缩 , 如果header头中包含 "Authorization" 头信息 105 | any - 无条件启用压缩 106 | 107 | #### gzip_vary on; 108 | 109 | 和http头有关系,会在响应头加个 Vary: Accept-Encoding ,可以让前端的缓存服务器缓存经过gzip压缩的页面,例如,用Squid缓存经过Nginx压缩的数据。 110 | 111 | 112 | -------------------------------------------------------------------------------- /3z/server.md: -------------------------------------------------------------------------------- 1 | ### nginx.conf server部分配置 2 | 3 | server{} 包含在http{}内部,每一个server{}都是一个虚拟主机(站点)。 4 | 5 | #### 以下为nginx.conf配置文件中server{}部分的内容。 6 | 7 | server { 8 | listen 80; //监听端口为80,可以自定义其他端口,也可以加上IP地址,如,listen 127.0.0.1:8080; 9 | server_name localhost; //定义网站域名,可以写多个,用空格分隔。 10 | #charset koi8-r; //定义网站的字符集,一般不设置,而是在网页代码中设置。 11 | #access_log logs/host.access.log main; //定义访问日志,可以针对每一个server(即每一个站点)设置它们自己的访问日志。 12 | 13 | ##在server{}里有很多location配置段 14 | location / { 15 | root html; //定义网站根目录,目录可以是相对路径也可以是绝对路径。 16 | index index.html index.htm; //定义站点的默认页。 17 | } 18 | 19 | #error_page 404 /404.html; //定义404页面 20 | 21 | # redirect server error pages to the static page /50x.html 22 | # 23 | error_page 500 502 503 504 /50x.html; //当状态码为500、502、503、504时,则访问50x.html 24 | location = /50x.html { 25 | root html; //定义50x.html所在路径 26 | } 27 | 28 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80 29 | # 30 | #定义访问php脚本时,将会执行本location{}部分指令 31 | #location ~ \.php$ { 32 | # proxy_pass http://127.0.0.1; //proxy_pass后面指定要访问的url链接,用proxy_pass实现代理。 33 | #} 34 | 35 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 36 | # 37 | #location ~ \.php$ { 38 | # root html; 39 | # fastcgi_pass 127.0.0.1:9000; //定义FastCGI服务器监听端口与地址,支持两种形式,1 IP:Port, 2 unix:/path/to/sockt 40 | # fastcgi_index index.php; 41 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; //定义SCRIPT_FILENAME变量,后面的路径/scripts为上面的root指定的目录 42 | # include fastcgi_params; //引用prefix/conf/fastcgi_params文件,该文件定义了fastcgi相关的变量 43 | #} 44 | 45 | # deny access to .htaccess files, if Apache's document root 46 | # concurs with nginx's one 47 | # 48 | #location ~ /\.ht { //访问的url中,以/.ht开头的,如,www.example.com/.htaccess,会被拒绝,返回403状态码。 49 | # deny all; //这里的all指的是所有的请求。 50 | #} 51 | } 52 | 53 | 54 | # another virtual host using mix of IP-, name-, and port-based configuration 55 | # 56 | #server { 57 | # listen 8000; //监听8000端口 58 | # listen somename:8080; //指定ip:port 59 | # server_name somename alias another.alias; //指定多个server_name 60 | 61 | # location / { 62 | # root html; 63 | # index index.html index.htm; 64 | # } 65 | #} 66 | 67 | 68 | # HTTPS server 69 | # 70 | #server { 71 | # listen 443 ssl; //监听443端口,即ssl 72 | # server_name localhost; 73 | 74 | ### 以下为ssl相关配置 75 | # ssl_certificate cert.pem; //指定pem文件路径 76 | # ssl_certificate_key cert.key; //指定key文件路径 77 | 78 | # ssl_session_cache shared:SSL:1m; //指定session cache大小 79 | # ssl_session_timeout 5m; //指定session超时时间 80 | # ssl_protocols TLSv1 TLSv1.1 TLSv1.2; //指定ssl协议 81 | # ssl_ciphers HIGH:!aNULL:!MD5; //指定ssl算法 82 | # ssl_prefer_server_ciphers on; //优先采取服务器算法 83 | # location / { 84 | # root html; 85 | # index index.html index.htm; 86 | # } 87 | #} 88 | -------------------------------------------------------------------------------- /4z/IO.md: -------------------------------------------------------------------------------- 1 | ![img](http://ask.apelearn.com/uploads/nginx/event2.png) 2 | 3 | ##### 同步机制 4 | 5 | 同步、异步发生在当客户端发起请求后,服务端处理客户端的请求时。 6 | 同步机制,是指客户端发送请求后,需要等待服务端(内核)返回信息后,再继续发送下一个请求。 7 | 在同步机制中,所有的请求在服务器端得到同步,即发送方和接收方对请求的处理步调是一致的。 8 | 9 | 10 | ##### 异步机制 11 | 12 | 异步机制,是指客户端发出一个请求后,不等待服务端(内核)返回信息,就继续发送下一个请求。 13 | 在异步机制中,所有来自发送方的请求形成一个队列,接收方处理完后再通知发送方。 14 | 15 | 16 | 举例:一家酒店前台,在旺季的高峰时间段会接很多预定酒席的电话。 17 | 如果是同步机制情况下,前台每接一个电话后先不挂掉电话,而是去查询有无剩余酒席,查到结果后,告诉客户。 18 | 如果是异步机制情况下,前台每接一个预定电话直接回复客户,一会回复,此时前台把查询这件事情交给了另外的同事, 19 | 该前台挂掉电话后,继续处理其他客户的事情,当另外的同事查询到结果后再通知给前台,前台再通知客户。 20 | 21 | 22 | ##### 阻塞 23 | 24 | 阻塞与非阻塞发生在IO调度中,比如内核到磁盘IO。 25 | 阻塞方式下,进程/线程在获取最终结果之前,被系统挂起了,也就是所谓的阻塞了,在阻塞过程中该进程什么都干不了, 26 | 直到最终结果反馈给它时,它才恢复运行状态。 27 | 28 | 29 | 30 | ##### 非阻塞 31 | 32 | 非阻塞方式和阻塞相反,进程/线程在获取最终结果之前,并没有进入被挂起的状态,而是该进程可以继续执行新的任务。 33 | 当有最终结果反馈给该进程时,它再把结果交给客户端。 34 | 35 | 举例:依然是酒店前台接待预定酒席电话的案例。 36 | 此时角色不再是前台,而是她的查询有无剩余酒席的同事。如果是阻塞方式,该同事在查询有无剩余酒席的过程中,需要傻傻地 37 | 等待酒店管理系统给他返回结果,在此期间不能做其他事情。 38 | 如果是非阻塞,该同事在等待酒店管理系统给他返回结果这段时间,可以做其他事情,比如可以通知前台剩余酒席的情况。 39 | 40 | ##### Nginx的请求机制 41 | 42 | Nginx之所以可以支持高并发,是因为Nginx用的是异步非阻塞的机制,而Nginx是靠事件驱动模型来实现这种机制的。 43 | 44 | 在Nginx的事件驱动模型下,客户端发起的所有请求在服务端都会被标记为一个事件,Nginx会把这些事件收集到“事件收集器”里, 45 | 然后再把这些事件交给内核去处理。 46 | -------------------------------------------------------------------------------- /4z/event.md: -------------------------------------------------------------------------------- 1 | #### 事件驱动模型 2 | 3 | 事件驱动模型是实现异步非阻塞的一个手段。事件驱动模型中,一个进程(线程)就可以了。 4 | 5 | 对于web服务器来说,客户端A的请求连接到服务端时,服务端的某个进程(Nginx worker process)会处理该请求, 6 | 此进程在没有返回给客户端A结果时,它又去处理了客户端B的请求。 7 | 服务端把客户端A以及客户端B发来的请求作为事件交给了“事件收集器”, 8 | 而“事件收集器”再把收集到的事件交由“事件发送器”发送给“事件处理器”进行处理。 9 | 最后“事件处理器”处理完该事件后,通知服务端进程,服务端进程再把结果返回给客户端A、客户端B。 10 | 11 | 在这个过程中,服务端进程做的事情属于用户级别的,而事件处理这部分工作属于内核级别的。 12 | 也就是说这个事件驱动模型是需要操作系统内核来作为支撑的。 13 | 14 | #### Nginx的事件驱动模型 15 | 16 | ![image](http://ask.apelearn.com/uploads/nginx/nginx_event.png) 17 | 18 | Nginx的事件驱动模型,支持select、poll、epoll、rtsig、kqueue、/dev/poll、eventport等。 19 | 最常用的是前三种,其中kqueue模型用于支持BSD系列平台的事件驱动模型。kqueue是poll模型的一个变种,本质上和epoll一样。 20 | /dev/poll是Unix平台的事件驱动模型,其主要在Solaris7及以上版本、HP/UX11.22及以上版本、IRIX6.5.15及以上版本、 21 | Tru64 Unix 5.1A及以上版本的平台使用。 22 | eventport是用于支持Solaris10及以上版本的事件驱动模型。 23 | 24 | 25 | ##### select模型 26 | 27 | Linux和Windows都支持,使用select模型的步骤是: 28 | 29 | 1. 创建所关注事件的描述符集合,对于一个描述符,可以关注其上面的读(Read)事件、写(Write)事件以及异常发生(Exception)事件。 30 | 在select模型中,要创建这3类事件描述符集合。 31 | 32 | 2. 调用底层提供的select()函数,等待事件发生。 33 | 34 | 3. 轮询所有事件描述符集合中的每一个事件描述符,检查是否有相应的事件发生,如果有就进行处理。 35 | 36 | ##### poll模型 37 | 38 | poll模型是Linux平台上的事件驱动模型,在Linux2.1.23中引入的,Windows平台不支持该模型。 39 | 40 | poll模型和select模型工作方式基本相同,区别在于,select模型创建了3个描述符集合,而poll模型只创建一个描述符集合。 41 | 42 | ##### epoll模型 43 | 44 | epoll模型属于poll模型的变种,在Linux2.5.44中引入。epoll比poll更加高效,原因在于它不需要轮询整个描述符集合, 45 | 而是Linux内核会关注事件集合,当有变动时,内核会发来通知。 46 | -------------------------------------------------------------------------------- /4z/event2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/event2.png -------------------------------------------------------------------------------- /4z/jg.md: -------------------------------------------------------------------------------- 1 | #### Nginx架构 2 | 3 | Nginx服务器使用 master/worker 多进程模式。 4 | 主进程(Master process)启动后,会接收和处理外部信号; 5 | 主进程启动后通过fork() 函数产生一个或多个子进程(work process),每个子进程会进行进程初始化、 6 | 模块调用以及对事件的接收和处理等工作。 7 | 8 | ![image](http://ask.apelearn.com/uploads/nginx/nginx_jg.png) 9 | 10 | ##### 主进程 11 | 12 | 主要功能是和外界通信和对内部其他进程进行管理,具体来说有以下几点: 13 | 14 | * 读取Nginx配置文件并验证其有效性和正确性 15 | 16 | * 建立、绑定和关闭socket 17 | 18 | * 按照配置生成、管理工作进程 19 | 20 | * 接收外界指令,比如重启、关闭、重载服务等指令 21 | 22 | * 日志文件管理 23 | 24 | ##### 子进程(worker process) 25 | 26 | 是由主进程生成,生成数量可以在配置文件中定义。该进程主要工作有: 27 | 28 | * 接收客户端请求 29 | 30 | * 将请求依次送入各个功能模块进行过滤处理 31 | 32 | * IO调用,获取响应数据 33 | 34 | * 与后端服务器通信,接收后端服务器处理结果 35 | 36 | * 数据缓存,访问缓存索引,查询和调用缓存数据 37 | 38 | * 发送请求结果,响应客户端请求 39 | 40 | * 接收主进程指令,如重启、重载、退出等 41 | 42 | ![img](http://ask.apelearn.com/uploads/nginx/nginx_m.jpg) 43 | -------------------------------------------------------------------------------- /4z/module.md: -------------------------------------------------------------------------------- 1 | ### Nginx模块化结构 2 | 3 | Nginx涉及到的模块分为核心模块、标准HTTP模块、可选HTTP模块、邮件服务模块以及第三方模块等五大类。 4 | 5 | ![image](http://ask.apelearn.com/uploads/nginx/nginx_module.jpg) 6 | 7 | #### 核心模块 8 | 9 | 核心模块是指Nginx服务器正常运行时必不可少的模块,它们提供了Nginx最基本最核心的服务,如进程管理、权限控制、错误日志记录等。 10 | 主要包含对两类功能的支持,一类是主体功能,包括进程管理、权限控制、错误日志记录、配置解析等, 11 | 另一类是用于响应请求事件必需的功能,包括事件驱动机制、正则表达式解析等。 12 | 13 | ngx_core_module 14 | ngx_errlog_module 15 | ngx_conf_module 16 | ngx_regex_module 17 | ngx_events_module 18 | ngx_event_core_module 19 | ngx_epoll_module 20 | 21 | 22 | #### 标准HTTP模块 23 | 24 | 标准HTTP模块是编译Nginx后包含的模块,其支持Nginx服务器的标准HTTP功能。 25 | 26 | | 模块 | 功能 | 27 | | :-------- | :----- | 28 | | ngx_http_core | 配置端口,URI分析,服务器响应错误处理,别名控制以及其他HTTP核心事务 | 29 | | ngx_http_access_module | 基于IP地址的访问控制(允许/拒绝) | 30 | | ngx_http_auth_basic_module | 基于HTTP的身份认证 | 31 | |ngx_http_autoindex_module| 处理以“/”结尾的请求并自动生成目录列表| 32 | |ngx_http_browser_module|解析HTTP请求头中的“User-Agent”域的值| 33 | |ngx_http_charset_module|指定网页编码| 34 | |ngx_http_empty_gif_module|从内存创建一个1 x 1的透明gif图片,可以快速调用| 35 | |ngx_http_fastcgi_module|对FastCGI的支持| 36 | |ngx_http_geo_module|将客户端的IP转化为键值对变量,该模块主要用来针对客户的的IP来定义变量| 37 | |ngx_http_gzip_module| 压缩请求响应,可以减少数据传输| 38 | |ngx_http_headers_filter_module|设置HTTP响应头| 39 | |ngx_http_index_module|处理以“/”结尾的请求,如果没有找到该目录下的index页,就将请求转给ngx_http_autoindex_module模块处理| 40 | |ngx_http_limit_req_module|限制来自客户端的请求的响应和处理速率| 41 | |ngx_http_limit_conn_module|限制来自客户端的连接的响应和处理速率| 42 | |ngx_http_log_module|自定义access日志| 43 | |ngx_http_map_module|创建任意键值对变量| 44 | |ngx_http_memcached_module|对Memcached的支持| 45 | |ngx_http_proxy_module| 支持代理事务| 46 | |ngx_http_referer_module|对HTTP头中的"referer"进行过滤处理,比如,实现防盗链功能| 47 | |ngx_http_rewrite_module|实现nginx的rewrite功能| 48 | |ngx_http_scgi_module|对SCGI的支持| 49 | |ngx_http_upstream_module|定义一组服务器,可以接收来自代理、Fastcgi、Memcached的中重定向,主要用于负载均衡| 50 | 51 | 52 | #### 可选HTTP模块 53 | 54 | 可选HTTP模块主要用于扩展标准的HTTP功能,使其能够处理一些特殊的HTTP请求。在编译Nginx时,如果不指定这些模块,默认是不会安装的。 55 | 56 | | 模块 | 功能 | 57 | | :-------- | :----- | 58 | |ngx_http_addition_module|在响应请求的页面开始或者结尾添加文本信息| 59 | |ngx_http_degradation_module|在低内存的情形下允许Nginx服务器返回444错误或204错误| 60 | |ngx_http_perl_module|在Nginx的配置文件中可以使用Perl脚本| 61 | |ngx_http_flv_module|支持将Flash多媒体信息按照流文件传输,可以根据客户端指定的开始位置返回Flash| 62 | |ngx_http_geoip_module|支持解析基于GeoIP数据库的客户端请求| 63 | |ngx_google_perflools_module|支持Google Performance Tools的一套用于C++Profile的工具集| 64 | |ngx_http_image_filter_module|支持将H.264/AAC编码的多媒体信息(后缀名通常为mp4、m4v或m4a)按照流文件传输,常与ngx_http_flv_module模块一起使用| 65 | |ngx_http_random_index_module|Nginx接收到以“/”结尾的请求时,在对应的目录下随机选择一个文件作为index文件| 66 | |ngx_http_secure_link_module|支持对请求链接的有效性检查| 67 | |ngx_http_ssl_module|对HTTPS/SSL支持| 68 | |ngx_http_stub_status_module|支持返回Nginx服务器的统计信息,一般包括处理连接的数量、连接成功的数量、处理的请求数、读取和返回的Header信息数等信息| 69 | |ngx_http_sub_module|使用指定的字符串替换响应信息中的信息| 70 | |ngx_http_dav_module|支持HTTP协议和WebDAV协议中PUT、DELETE、MKCOL、COPY和MOVE方法| 71 | |ngx_http_xslt_module|将XML响应信息使用XSLT(拓展样式表转换语言)进行转换| 72 | 73 | 74 | #### 邮件服务模块 75 | 76 | 主要用于支持Ningx的邮件服务。 77 | 78 | #### 第三方模块 79 | 80 | 并非有Nginx官方提供,而是由第三方机构或者个人开发的模块,用于实现某种特殊功能。 81 | echo-nginx-module 支持在Nginx配置文件中使用echo、sleep、time以及exec等类shell命令 82 | lua-nginx-module 使Nginx支持lua脚本语言 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /4z/nginx_event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/nginx_event.png -------------------------------------------------------------------------------- /4z/nginx_jg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/nginx_jg.png -------------------------------------------------------------------------------- /4z/nginx_m.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/nginx_m.jpg -------------------------------------------------------------------------------- /4z/nginx_module.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/nginx_module.jpg -------------------------------------------------------------------------------- /4z/nginx_phase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/4z/nginx_phase.png -------------------------------------------------------------------------------- /4z/request_process.md: -------------------------------------------------------------------------------- 1 | #### Nginx请求流程 2 | ![image](http://ask.apelearn.com/uploads/nginx/nginx_phase.png) 3 | 4 | #### Nginx各phase对应的模块 5 | | phase | 对应模块 | 6 | | :-------- | :----- | 7 | | NGX_HTTP_POST_READ_PHASE | ngx_http_realip_module | 8 | | NGX_HTTP_SERVER_REWRITE_PHASE | ngx_http_rewrite_module | 9 | |NGX_HTTP_FIND_CONFIG_PHASE|ngx_http_core_module| 10 | |NGX_HTTP_REWRITE_PHASE |ngx_http_rewrite_module、ngx_http_core_module| 11 | |NGX_HTTP_POST_REWRITE_PHASE|无对应模块| 12 | |NGX_HTTP_PREACCESS_PHASE|ngx_http_limit_conn_module、ngx_http_limit_req_module| 13 | |NGX_HTTP_ACCESS_PHASE|ngx_http_access_module| 14 | |NGX_HTTP_POST_ACCESS_PHASE|无对应模块| 15 | |NGX_HTTP_TRY_FILES_PHASE|ngx_http_core_module| 16 | |NGX_HTTP_CONTENT_PHASE|ngx_http_autoindex_module、ngx_http_core_module、ngx_http_index_module、ngx_http_proxy_module、ngx_http_stub_status_module等| 17 | |NGX_HTTP_LOG_PHASE|ngx_http_log_module| 18 | 19 | #### 各phase说明 20 | ##### NGX_HTTP_POST_READ_PHASE 21 | ``` 22 | nginx读取并解析完请求头之后就进入了post_read 阶段,它位于uri被重写之前,这个阶段允许nginx改变请求头中ip地址的值 23 | ``` 24 | ##### NGX_HTTP_SERVER_REWRITE_PHASE 25 | ``` 26 | 这个阶段主要进行初始化全局变量,或者server级别的重写。如果把重写指令放到 server 中,那么就进入了server rewrite 阶段。 27 | ``` 28 | 29 | ##### NGX_HTTP_FIND_CONFIG_PHASE 30 | ``` 31 | 这个阶段使用重写之后的uri来查找对应的location,值得注意的是该阶段可能会被执行多次,因为也可能有location级别的重写指令。 32 | ``` 33 | ##### NGX_HTTP_REWRITE_PHASE 34 | ``` 35 | 如果把重写指令放到 location中,那么就进入了rewrite phase,这个阶段是location级别的uri重写阶段,重写指令也可能会被执行多次 36 | ``` 37 | ##### NGX_HTTP_POST_REWRITE_PHASE 38 | ``` 39 | location级别重写的下一阶段,用来检查上阶段是否有uri重写,并根据结果跳转到合适的阶段 40 | ``` 41 | ##### NGX_HTTP_PREACCESS_PHASE 42 | ``` 43 | 访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般也用于访问控制,比如限制访问频率,链接数等 44 | ``` 45 | ##### NGX_HTTP_ACCESS_PHASE 46 | ``` 47 | 访问权限控制阶段,比如基于ip黑白名单的权限控制,基于用户名密码的认证控制等 48 | ``` 49 | ##### NGX_HTTP_POST_ACCESS_PHASE 50 | ``` 51 | 访问权限控制的后一阶段,该阶段根据权限控制阶段的执行结果进行相应处理 52 | ``` 53 | ##### NGX_HTTP_TRY_FILES_PHASE 54 | ``` 55 | ngx_http_core_module的try_files指令的处理阶段,如果没有配置try_files指令,则该阶段被跳过。 56 | 当try_files用于server配置段时一般是初始化作用,用来加载一些文件。 57 | ``` 58 | ##### NGX_HTTP_CONTENT_PHASE 59 | ``` 60 | 内容生成阶段,该阶段产生响应,并发送到客户端 61 | ``` 62 | ##### NGX_HTTP_LOG_PHASE 63 | ``` 64 | 日志记录阶段,该阶段记录访问日志 65 | ``` 66 | 67 | ##### 参考内容: 68 | ``` 69 | http://tengine.taobao.org/book/chapter_02.html#id12 70 | https://blog.csdn.net/qinyushuang/article/details/44567885 71 | ``` 72 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and 10 | distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by the copyright 13 | owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all other entities 16 | that control, are controlled by, or are under common control with that entity. 17 | For the purposes of this definition, "control" means (i) the power, direct or 18 | indirect, to cause the direction or management of such entity, whether by 19 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 20 | outstanding shares, or (iii) beneficial ownership of such entity. 21 | 22 | "You" (or "Your") shall mean an individual or Legal Entity exercising 23 | permissions granted by this License. 24 | 25 | "Source" form shall mean the preferred form for making modifications, including 26 | but not limited to software source code, documentation source, and configuration 27 | files. 28 | 29 | "Object" form shall mean any form resulting from mechanical transformation or 30 | translation of a Source form, including but not limited to compiled object code, 31 | generated documentation, and conversions to other media types. 32 | 33 | "Work" shall mean the work of authorship, whether in Source or Object form, made 34 | available under the License, as indicated by a copyright notice that is included 35 | in or attached to the work (an example is provided in the Appendix below). 36 | 37 | "Derivative Works" shall mean any work, whether in Source or Object form, that 38 | is based on (or derived from) the Work and for which the editorial revisions, 39 | annotations, elaborations, or other modifications represent, as a whole, an 40 | original work of authorship. For the purposes of this License, Derivative Works 41 | shall not include works that remain separable from, or merely link (or bind by 42 | name) to the interfaces of, the Work and Derivative Works thereof. 43 | 44 | "Contribution" shall mean any work of authorship, including the original version 45 | of the Work and any modifications or additions to that Work or Derivative Works 46 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 47 | by the copyright owner or by an individual or Legal Entity authorized to submit 48 | on behalf of the copyright owner. For the purposes of this definition, 49 | "submitted" means any form of electronic, verbal, or written communication sent 50 | to the Licensor or its representatives, including but not limited to 51 | communication on electronic mailing lists, source code control systems, and 52 | issue tracking systems that are managed by, or on behalf of, the Licensor for 53 | the purpose of discussing and improving the Work, but excluding communication 54 | that is conspicuously marked or otherwise designated in writing by the copyright 55 | owner as "Not a Contribution." 56 | 57 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf 58 | of whom a Contribution has been received by Licensor and subsequently 59 | incorporated within the Work. 60 | 61 | 2. Grant of Copyright License. 62 | 63 | Subject to the terms and conditions of this License, each Contributor hereby 64 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 65 | irrevocable copyright license to reproduce, prepare Derivative Works of, 66 | publicly display, publicly perform, sublicense, and distribute the Work and such 67 | Derivative Works in Source or Object form. 68 | 69 | 3. Grant of Patent License. 70 | 71 | Subject to the terms and conditions of this License, each Contributor hereby 72 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 73 | irrevocable (except as stated in this section) patent license to make, have 74 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 75 | such license applies only to those patent claims licensable by such Contributor 76 | that are necessarily infringed by their Contribution(s) alone or by combination 77 | of their Contribution(s) with the Work to which such Contribution(s) was 78 | submitted. If You institute patent litigation against any entity (including a 79 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 80 | Contribution incorporated within the Work constitutes direct or contributory 81 | patent infringement, then any patent licenses granted to You under this License 82 | for that Work shall terminate as of the date such litigation is filed. 83 | 84 | 4. Redistribution. 85 | 86 | You may reproduce and distribute copies of the Work or Derivative Works thereof 87 | in any medium, with or without modifications, and in Source or Object form, 88 | provided that You meet the following conditions: 89 | 90 | You must give any other recipients of the Work or Derivative Works a copy of 91 | this License; and 92 | You must cause any modified files to carry prominent notices stating that You 93 | changed the files; and 94 | You must retain, in the Source form of any Derivative Works that You distribute, 95 | all copyright, patent, trademark, and attribution notices from the Source form 96 | of the Work, excluding those notices that do not pertain to any part of the 97 | Derivative Works; and 98 | If the Work includes a "NOTICE" text file as part of its distribution, then any 99 | Derivative Works that You distribute must include a readable copy of the 100 | attribution notices contained within such NOTICE file, excluding those notices 101 | that do not pertain to any part of the Derivative Works, in at least one of the 102 | following places: within a NOTICE text file distributed as part of the 103 | Derivative Works; within the Source form or documentation, if provided along 104 | with the Derivative Works; or, within a display generated by the Derivative 105 | Works, if and wherever such third-party notices normally appear. The contents of 106 | the NOTICE file are for informational purposes only and do not modify the 107 | License. You may add Your own attribution notices within Derivative Works that 108 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 109 | provided that such additional attribution notices cannot be construed as 110 | modifying the License. 111 | You may add Your own copyright statement to Your modifications and may provide 112 | additional or different license terms and conditions for use, reproduction, or 113 | distribution of Your modifications, or for any such Derivative Works as a whole, 114 | provided Your use, reproduction, and distribution of the Work otherwise complies 115 | with the conditions stated in this License. 116 | 117 | 5. Submission of Contributions. 118 | 119 | Unless You explicitly state otherwise, any Contribution intentionally submitted 120 | for inclusion in the Work by You to the Licensor shall be under the terms and 121 | conditions of this License, without any additional terms or conditions. 122 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 123 | any separate license agreement you may have executed with Licensor regarding 124 | such Contributions. 125 | 126 | 6. Trademarks. 127 | 128 | This License does not grant permission to use the trade names, trademarks, 129 | service marks, or product names of the Licensor, except as required for 130 | reasonable and customary use in describing the origin of the Work and 131 | reproducing the content of the NOTICE file. 132 | 133 | 7. Disclaimer of Warranty. 134 | 135 | Unless required by applicable law or agreed to in writing, Licensor provides the 136 | Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, 137 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 138 | including, without limitation, any warranties or conditions of TITLE, 139 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 140 | solely responsible for determining the appropriateness of using or 141 | redistributing the Work and assume any risks associated with Your exercise of 142 | permissions under this License. 143 | 144 | 8. Limitation of Liability. 145 | 146 | In no event and under no legal theory, whether in tort (including negligence), 147 | contract, or otherwise, unless required by applicable law (such as deliberate 148 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 149 | liable to You for damages, including any direct, indirect, special, incidental, 150 | or consequential damages of any character arising as a result of this License or 151 | out of the use or inability to use the Work (including but not limited to 152 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 153 | any and all other commercial damages or losses), even if such Contributor has 154 | been advised of the possibility of such damages. 155 | 156 | 9. Accepting Warranty or Additional Liability. 157 | 158 | While redistributing the Work or Derivative Works thereof, You may choose to 159 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 160 | other liability obligations and/or rights consistent with this License. However, 161 | in accepting such obligations, You may act only on Your own behalf and on Your 162 | sole responsibility, not on behalf of any other Contributor, and only if You 163 | agree to indemnify, defend, and hold each Contributor harmless for any liability 164 | incurred by, or claims asserted against, such Contributor by reason of your 165 | accepting any such warranty or additional liability. 166 | 167 | END OF TERMS AND CONDITIONS 168 | 169 | APPENDIX: How to apply the Apache License to your work 170 | 171 | To apply the Apache License to your work, attach the following boilerplate 172 | notice, with the fields enclosed by brackets "{}" replaced with your own 173 | identifying information. (Don't include the brackets!) The text should be 174 | enclosed in the appropriate comment syntax for the file format. We also 175 | recommend that a file or class name and description of purpose be included on 176 | the same "printed page" as the copyright notice for easier identification within 177 | third-party archives. 178 | 179 | Copyright 2018 aminglinux 180 | 181 | Licensed under the Apache License, Version 2.0 (the "License"); 182 | you may not use this file except in compliance with the License. 183 | You may obtain a copy of the License at 184 | 185 | http://www.apache.org/licenses/LICENSE-2.0 186 | 187 | Unless required by applicable law or agreed to in writing, software 188 | distributed under the License is distributed on an "AS IS" BASIS, 189 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 190 | See the License for the specific language governing permissions and 191 | limitations under the License. 192 | -------------------------------------------------------------------------------- /Nginx_dg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/Nginx_dg.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://coding.net/u/aminglinux/p/nginx/git/raw/master/Nginx_dg.png) -------------------------------------------------------------------------------- /access/auth.md: -------------------------------------------------------------------------------- 1 | #### Nginx的用户认证 2 | ``` 3 | 当访问一些私密资源时,最好配置用户认证,增加安全性。 4 | ``` 5 | ##### 步骤和示例 6 | * 安装httpd 7 | ``` 8 | yum install -y httpd 9 | ``` 10 | 11 | * 使用htpasswd生产密码文件 12 | ``` 13 | htpasswd -c /usr/local/nginx/conf/htpasswd aming 14 | ``` 15 | 16 | * 配置nginx用户认证 17 | ``` 18 | location /admin/ 19 | { 20 | auth_basic "Auth"; 21 | auth_basic_user_file /usr/local/nginx/conf/htpasswd; 22 | } 23 | ``` 24 | 25 | * 测试 26 | ``` 27 | curl -uaming:passwd www.aminglinux.com/admin/1.html 28 | ``` -------------------------------------------------------------------------------- /access/deny_allow.md: -------------------------------------------------------------------------------- 1 | #### Nginx访问控制 —— deny_allow 2 | ``` 3 | Nginx的deny和allow指令是由ngx_http_access_module模块提供,Nginx安装默认内置了该模块。 4 | 除非在安装时有指定 --without-http_access_module。 5 | ``` 6 | 7 | ##### 语法 8 | ``` 9 | 语法:allow/deny address | CIDR | unix: | all 10 | 11 | 它表示,允许/拒绝某个ip或者一个ip段访问.如果指定unix:,那将允许socket的访问。 12 | 注意:unix在1.5.1中新加入的功能。 13 | 14 | 在nginx中,allow和deny的规则是按顺序执行的。 15 | 16 | ``` 17 | 18 | ##### 示例 19 | ``` 20 | 示例1: 21 | location / 22 | { 23 | allow 192.168.0.0/24; 24 | allow 127.0.0.1; 25 | deny all; 26 | } 27 | 28 | 说明:这段配置值允许192.168.0.0/24网段和127.0.0.1的请求,其他来源IP全部拒绝。 29 | 30 | 示例2: 31 | location ~ "admin" 32 | { 33 | allow 110.21.33.121; 34 | deny all 35 | } 36 | 说明:访问的uri中包含admin的请求,只允许110.21.33.121这个IP的请求。 37 | 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /access/document_uri.md: -------------------------------------------------------------------------------- 1 | #### Nginx基于$document_uri的访问控制 2 | ``` 3 | 这就用到了变量$document_uri,根据前面所学内容,该变量等价于$uri,其实也等价于location匹配。 4 | ``` 5 | 6 | ##### 示例1 7 | ``` 8 | if ($document_uri ~ "/admin/") 9 | { 10 | return 403; 11 | } 12 | 13 | 说明:当请求的uri中包含/admin/时,直接返回403. 14 | 15 | if结构中不支持使用allow和deny。 16 | 17 | 测试链接: 18 | 1. www.aminglinux.com/123/admin/1.html 匹配 19 | 2. www.aminglinux.com/admin123/1.html 不匹配 20 | 3. www.aminglinux.com/admin.php 不匹配 21 | ``` 22 | 23 | ##### 示例2 24 | ``` 25 | if ($document_uri = /admin.php) 26 | { 27 | return 403; 28 | } 29 | 30 | 说明:请求的uri为/admin.php时返回403状态码。 31 | 32 | 测试链接: 33 | 1. www.aminglinux.com/admin.php 匹配 34 | 2. www.aminglinux.com/123/admin.php 不匹配 35 | ``` 36 | 37 | ##### 示例3 38 | ``` 39 | if ($document_uri ~ '/data/|/cache/.*\.php$') 40 | { 41 | return 403; 42 | } 43 | 44 | 说明:请求的uri包含data或者cache目录,并且是php时,返回403状态码。 45 | 46 | 测试链接: 47 | 1. www.aminglinux.com/data/123.php 匹配 48 | 2. www.aminglinux.com/cache1/123.php 不匹配 49 | ``` -------------------------------------------------------------------------------- /access/limit.md: -------------------------------------------------------------------------------- 1 | #### Nginx的限速 2 | ``` 3 | 可以通过ngx_http_limit_conn_module和ngx_http_limit_req_module模块来实现限速的功能。 4 | ``` 5 | 6 | ##### ngx_http_limit_conn_module 7 | ``` 8 | 该模块主要限制下载速度。 9 | ``` 10 | ##### #1. 并发限制 11 | ``` 12 | 配置示例 13 | http 14 | { 15 | ... 16 | limit_conn_zone $binary_remote_addr zone=aming:10m; 17 | ... 18 | server 19 | { 20 | ... 21 | limit_conn aming 10; 22 | ... 23 | } 24 | } 25 | 说明:首先用limit_conn_zone定义了一个内存区块索引aming,大小为10m,它以$binary_remote_addr作为key。 26 | 该配置只能在http里面配置,不支持在server里配置。 27 | 28 | limit_conn 定义针对aming这个zone,并发连接为10个。在这需要注意一下,这个10指的是单个IP的并发最多为10个。 29 | ``` 30 | ##### #2. 速度限制 31 | ``` 32 | location ~ /download/ { 33 | ... 34 | limit_rate_after 512k; 35 | limit_rate 150k; 36 | ... 37 | } 38 | 说明:limit_rate_after定义当一个文件下载到指定大小(本例中为512k)之后开始限速; 39 | limit_rate 定义下载速度为150k/s。 40 | 41 | 注意:这两个参数针对每个请求限速。 42 | ``` 43 | 44 | ##### ngx_http_limit_req_module 45 | 46 | ``` 47 | 该模块主要用来限制请求数。 48 | ``` 49 | ##### #1. limit_req_zone 50 | ``` 51 | 语法: limit_req_zone $variable zone=name:size rate=rate; 52 | 默认值: none 53 | 配置段: http 54 | 55 | 设置一块共享内存限制域用来保存键值的状态参数。 特别是保存了当前超出请求的数量。 56 | 键的值就是指定的变量(空值不会被计算)。 57 | 如limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 58 | 59 | 说明:区域名称为one,大小为10m,平均处理的请求频率不能超过每秒一次,键值是客户端IP。 60 | 使用$binary_remote_addr变量, 可以将每条状态记录的大小减少到64个字节,这样1M的内存可以保存大约1万6千个64字节的记录。 61 | 如果限制域的存储空间耗尽了,对于后续所有请求,服务器都会返回 503 (Service Temporarily Unavailable)错误。 62 | 速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数, 63 | 所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用 “30r/m”。 64 | 65 | ``` 66 | ##### #2. limit_req 67 | ``` 68 | 语法: limit_req zone=name [burst=number] [nodelay]; 69 | 默认值: — 70 | 配置段: http, server, location 71 | 72 | 设置对应的共享内存限制域和允许被处理的最大请求数阈值。 73 | 如果请求的频率超过了限制域配置的值,请求处理会被延迟,所以所有的请求都是以定义的频率被处理的。 74 | 超过频率限制的请求会被延迟,直到被延迟的请求数超过了定义的阈值, 75 | 这时,这个请求会被终止,并返回503 (Service Temporarily Unavailable) 错误。 76 | 77 | 这个阈值的默认值为0。如: 78 | limit_req_zone $binary_remote_addr zone=aming:10m rate=1r/s; 79 | server { 80 | location /upload/ { 81 | limit_req zone=aming burst=5; 82 | } 83 | } 84 | 85 | 限制平均每秒不超过一个请求,同时允许超过频率限制的请求数不多于5个。 86 | 87 | 如果不希望超过的请求被延迟,可以用nodelay参数,如: 88 | 89 | limit_req zone=aming burst=5 nodelay; 90 | ``` 91 | 92 | ##### 示例 93 | 94 | ``` 95 | http { 96 | limit_req_zone $binary_remote_addr zone=aming:10m rate=1r/s; 97 | 98 | server { 99 | location ^~ /download/ { 100 | limit_req zone=aming burst=5; 101 | } 102 | } 103 | } 104 | ``` 105 | 106 | ##### 设定白名单IP 107 | ``` 108 | 如果是针对公司内部IP或者lo(127.0.0.1)不进行限速,如何做呢?这就要用到geo模块了。 109 | 110 | 假如,预把127.0.0.1和192.168.100.0/24网段设置为白名单,需要这样做。 111 | 在http { }里面增加: 112 | geo $limited { 113 | default 1; 114 | 127.0.0.1/32 0; 115 | 192.168.100.0/24 0; 116 | } 117 | 118 | map $limited $limit { 119 | 1 $binary_remote_addr; 120 | 0 ""; 121 | } 122 | 123 | 原来的 “limit_req_zone $binary_remote_addr ” 改为“limit_req_zone $limit” 124 | 125 | 完整示例: 126 | 127 | http { 128 | geo $limited { 129 | default 1; 130 | 127.0.0.1/32 0; 131 | 192.168.100.0/24 0; 132 | } 133 | 134 | map $limited $limit { 135 | 1 $binary_remote_addr; 136 | 0 ""; 137 | } 138 | 139 | limit_req_zone $limit zone=aming:10m rate=1r/s; 140 | 141 | server { 142 | location ^~ /download/ { 143 | limit_req zone=aming burst=5; 144 | } 145 | } 146 | } 147 | ``` -------------------------------------------------------------------------------- /access/location.md: -------------------------------------------------------------------------------- 1 | #### 基于location的访问控制 2 | ``` 3 | 在生产环境中,我们会对某些特殊的请求进行限制,比如对网站的后台进行限制访问。 4 | 这就用到了location配置。 5 | ``` 6 | 7 | ##### 示例1 8 | ``` 9 | location /aming/ 10 | { 11 | deny all; 12 | } 13 | 14 | 说明:针对/aming/目录,全部禁止访问,这里的deny all可以改为return 403. 15 | ``` 16 | 17 | ##### 示例2 18 | ``` 19 | location ~ ".bak|\.ht" 20 | { 21 | return 403; 22 | } 23 | 说明:访问的uri中包含.bak字样的或者包含.ht的直接返回403状态码。 24 | 25 | 测试链接举例: 26 | 1. www.aminglinux.com/123.bak 27 | 2. www.aminglinux.com/aming/123/.htalskdjf 28 | ``` 29 | 30 | ##### 示例3 31 | ``` 32 | location ~ (data|cache|tmp|image|attachment).*\.php$ 33 | { 34 | deny all; 35 | } 36 | 37 | 说明:请求的uri中包含data、cache、tmp、image、attachment并且以.php结尾的,全部禁止访问。 38 | 39 | 测试链接举例: 40 | 1. www.aminglinux.com/aming/cache/1.php 41 | 2. www.aminglinux.com/image/123.phps 42 | 3. www.aminglinux.com/aming/datas/1.php 43 | 44 | ``` -------------------------------------------------------------------------------- /access/referer.md: -------------------------------------------------------------------------------- 1 | #### Nginx基于$http_referer的访问控制 2 | ``` 3 | 在前面讲解rewrite时,曾经用过该变量,当时实现了防盗链功能。 4 | 其实基于该变量,我们也可以做一些特殊的需求。 5 | 6 | ``` 7 | 8 | ##### 示例 9 | ``` 10 | 背景:网站被黑挂马,搜索引擎收录的网页是有问题的,当通过搜索引擎点击到网站时,却显示一个博彩网站。 11 | 由于查找木马需要时间,不能马上解决,为了不影响用户体验,可以针对此类请求做一个特殊操作。 12 | 比如,可以把从百度访问的链接直接返回404状态码,或者返回一段html代码。 13 | 14 | if ($http_referer ~ 'baidu.com') 15 | { 16 | return 404; 17 | } 18 | 19 | 或者 20 | 21 | if ($http_referer ~ 'baidu.com') 22 | { 23 | return 200 ""; 24 | } 25 | ``` -------------------------------------------------------------------------------- /access/request_uri.md: -------------------------------------------------------------------------------- 1 | #### nginx基于$request_uri访问控制 2 | ``` 3 | $request_uri比$docuemnt_uri多了请求的参数。 4 | 主要是针对请求的uri中的参数进行控制。 5 | ``` 6 | 7 | ##### 示例 8 | ``` 9 | if ($request_uri ~ "gid=\d{9,12}") 10 | { 11 | return 403; 12 | } 13 | 14 | 说明:\d{9,12}是正则表达式,表示9到12个数字,例如gid=1234567890就符号要求。 15 | 16 | 测试链接: 17 | 1. www.aminglinux.com/index.php?gid=1234567890&pid=111 匹配 18 | 2. www.aminglinux.com/gid=123 不匹配 19 | 20 | 背景知识: 21 | 曾经有一个客户的网站cc攻击,对方发起太多类似这样的请求:/read-123405150-1-1.html 22 | 实际上,这样的请求并不是正常的请求,网站会抛出一个页面,提示帖子不存在。 23 | 所以,可以直接针对这样的请求,return 403状态码。 24 | 25 | ``` -------------------------------------------------------------------------------- /access/user_agent.md: -------------------------------------------------------------------------------- 1 | #### Nginx基于$user_agent的访问控制 2 | ``` 3 | user_agent大家并不陌生,可以简单理解成浏览器标识,包括一些蜘蛛爬虫都可以通过user_agent来辨识。 4 | 通过观察访问日志,可以发现一些搜索引擎的蜘蛛对网站访问特别频繁,它们并不友好。 5 | 为了减少服务器的压力,其实可以把除主流搜索引擎蜘蛛外的其他蜘蛛爬虫全部封掉。 6 | 另外,一些cc攻击,我们也可以通过观察它们的user_agent找到规律。 7 | 8 | ``` 9 | ##### 示例 10 | ``` 11 | if ($user_agent ~ 'YisouSpider|MJ12bot/v1.4.2|YoudaoBot|Tomato') 12 | { 13 | return 403; 14 | } 15 | 说明:user_agent包含以上关键词的请求,全部返回403状态码。 16 | 17 | 测试: 18 | 1. curl -A "123YisouSpider1.0" 19 | 2. curl -A "MJ12bot/v1.4.1" 20 | 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /http/http.md: -------------------------------------------------------------------------------- 1 | #### HTTP协议相关概念 2 | HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 3 | HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。 4 | 5 | ##### 请求方法 6 | 这个方法指的是,客户端向服务端发起请求时的动作。 7 | 常见方法如下: 8 | 9 | | HTTP方法 | 说明 | 10 | | :-------- | :----- | 11 | |GET |最常见的方法,客户端向服务端请求某个资源,并返回实际主体,例如请求图片、html等 | 12 | |POST| 客户端向服务端提交指定数据,例如提交表单| 13 | |HEAD| 类似于get请求,只不过返回的响应中没有具体的内容,只有头部信息| 14 | |PUT| 类似于POST,也是向服务端提交数据,不过PUT有指定数据存储位置| 15 | |DELETE|请求服务器删除指定的页面| 16 | |OPTIONS|获取服务端支持的方法,它还可以查看服务端的性能| 17 | |TRACE|回显服务器收到的请求,主要用于测试或诊断| 18 | |CONNECT|把请求连接转换到透明的TCP/IP通道| 19 | 20 | ##### HTTP状态码 21 | 客户端发送请求到服务端,然后服务端会回应结果给客户端,回应的数据会包含一个三位数字的状态码,用来标识该请求是否成功,比如是正常还是错误等。 22 | HTTP/1.1中状态码可以分为五大类。 23 | | 状态码 | 说明 | 24 | | :-------- | :----- | 25 | |1**| 信息,服务器收到请求,需要请求者继续执行操作| 26 | |2**| 成功,操作被成功接收并处理| 27 | |3**| 重定向,需要进一步的操作以完成请求| 28 | |4**| 客户端错误,请求包含语法错误或无法完成请求| 29 | |5**| 服务器错误,服务器在处理请求的过程中发生了错误| 30 | 31 | 以下是几个常见的状态码 32 | | 状态码 | 英文名称|说明 | 33 | | :-------- | :----- | :----- | 34 | |200| OK|表示成功客户端成功接收到了服务端返回的数据,这是最常见的状态码| 35 | |206|Partial Content|客户端发完请求后,服务端只是返回了部分数据,就会出现该状态码,例如当下载一个很大的文件时,在没有下载完成前就会出现该状态码| 36 | |301|moved permanently|永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。用作域名重定向| 37 | |302|Moved Temporarily|临时移动。与301类似,URI被移动到了一个新的地址,但资源只是临时被移动,无论是301还是302对于客户端来说结果是一样的,这两个状态码针对搜索引擎来说是有差异的,考虑SEO的话,要使用301| 38 | |400|Bad Request|客户端请求语法错误,服务端无法理解| 39 | |401|Unauthorized|服务端如果开启了用户认证,而客户端没有提供正确的验证信息就会返回该状态码| 40 | |403|Forbidden|服务端不允许客户端访问| 41 | |404|Not Found|客户端请求的资源不存在| 42 | |413|Request Entity Too Large|客户端向服务端上传一个比较大的文件时,如果文件大小超过了服务端的限制就会出现该状态码| 43 | |500|Internal Server Error|服务端出现了内部错误| 44 | |502|Bad Gateway|服务器充当代理角色时,后端被代理的服务器不可用或者没有正常回应,如,在nginx+php-fpm的环境中,如果php-fpm服务出现故障,nginx就会出现该状态码| 45 | |503|Service Unavailable|服务当前不可用,由于超载或系统维护,服务器暂时的无法处理客户端的请求,如,当nginx限速后,客户端请求超过限制就会收到该状态码| 46 | |504|Gateway Time-out|和502类似,充当代理角色时,后端的服务期没有按时返回数据,超时了| 47 | 48 | ##### HTTP Request 49 | 从客户端发往服务端的HTTP报文叫做HTTP Request Message。 50 | HTTP请求报文由请求行、请求头部(header)、空行、请求数据几个部分组成, 51 | 如下所示: 52 | 53 | ![img](http://ask.apelearn.com/uploads/answer/20200523/http_request.jpg) 54 | 55 | 使用curl命令可以获取Request头信息 curl -v 56 | 57 | 示例: 58 | ``` 59 | GET /123.jpg HTTP/1.1 请求行 60 | Host img.123.com 请求头部 61 | User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 请求头部 62 | Accept image/webp,image/*,*/*;q=0.8 请求头部 63 | Referer http://www.aminglinux.com/ 请求头部 64 | Accept-Encoding gzip, deflate, sdch 请求头部 65 | Accept-Language zh-CN,zh;q=0.8 请求头部 66 | 空行 67 | 请求数据 68 | ``` 69 | 70 | ##### HTTP Response 71 | 从服务端回应的HTTP报文叫做HTTP Response Message。 72 | HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。 73 | 示例: 74 | ``` 75 | HTTP/1.1 200 OK 状态行 76 | Server: nginx/1.12.2 消息报头 77 | Date: Tue, 03 Jul 2018 07:28:58 GMT 消息报头 78 | Content-Type: text/html; charset=UTF-8 消息报头 79 | Connection: keep-alive 消息报头 80 | X-Powered-By: PHP/5.6.10 消息报头 81 | 空行 82 | 响应正文 83 | ``` 84 | 85 | ##### HTTP工作原理 86 | * 客户端连接到Web服务器,一个HTTP客户端,通常是浏览器,与Web服务器的HTTP端口(默认为80)建立一个TCP套接字连接。 87 | 88 | * 通过TCP套接字,客户端向Web服务器发送一个文本的请求报文。 89 | 90 | * Web服务器解析请求,定位请求资源。服务器将资源复本写到TCP套接字,由客户端读取。 91 | 92 | * 若connection模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则该连接会保持一段时间,在该时间内可以继续接收请求。 93 | 94 | * 客户端浏览器首先解析状态行,查看表明请求是否成功的状态代码。然后解析每一个响应头,响应头告知以下为若干字节的HTML文档和文档的字符集。客户端浏览器读取响应数据HTML,根据HTML的语法对其进行格式化,并在浏览器窗口中显示。 95 | 96 | 例如:在浏览器地址栏键入URL,按下回车之后会经历以下流程: 97 | 98 | * 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址; 99 | 100 | * 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器建立TCP连接; 101 | 102 | * 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文作为 TCP 三次握手的第三个报文的数据发送给服务器; 103 | 104 | * 服务器对浏览器请求作出响应,并把对应的 html 文本发送给浏览器; 105 | 106 | * 释放 TCP连接; 107 | 108 | * 浏览器将该 html 文本并显示内容; 109 | 110 | ##### URI和URL 111 | URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。 112 | Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是用一个URI来定位的。 113 | URI一般由三部组成: 114 | * 访问资源的命名机制,如http://, ftp://, rsync://等 115 | * 存放资源的主机名,如www.aminglinux.com 116 | * 资源自身的名称,由路径表示,着重强调于资源,如html/01/2018/0701.html 117 | * 一个完整的URI示例:http://www.aminglinux.com/html/01/2018/0701.html 118 | 119 | URL是uniform resource locator,统一资源定位器,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何定位这个资源。 120 | URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上。 121 | 采用URL可以用一种统一的格式来描述各种信息资源。 122 | URL一般由三部组成: 123 | * 协议(或称为服务方式) 124 | * 存有该资源的主机IP地址(有时也包括端口号) 125 | * 主机资源的具体地址。如目录和文件名等 126 | 127 | -------------------------------------------------------------------------------- /http/http_request.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/http/http_request.jpg -------------------------------------------------------------------------------- /http/version.md: -------------------------------------------------------------------------------- 1 | #### HTTP发展简史 2 | HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 3 | HTTP 是基于 TCP/IP 协议的应用层协议。它不涉及数据包(packet)传输,主要规定了客户端和服务器之间的通信格式,默认使用80端口。 4 | 5 | ##### HTTP/0.9版本 6 | * 1991年发布0.9版本,该版本只有一个GET命令。 7 | * 仅支持html格式。 8 | * 服务器不支持长连接,当客户端和服务端通信完后就会关闭连接,一次连接一个请求。 9 | 10 | ##### HTTP/1.0版本 11 | * 1996年5月发布1.0版本,有很大改进。 12 | * 支持了更多文件格式,比如图片、视频、二进制文件,使得网页内容更加丰富。 13 | * 支持了更多的方法:GET、POST、HEAD。 14 | * 增加了包头信息(HTTP header)、状态码、缓存、权限等功能。 15 | * 和0.9版本一样,服务器不支持长连接,当客户端和服务端通信完后就会关闭连接,一次连接一个请求。 16 | 17 | ##### HTTP/1.1版本 18 | * 1997年1月发布1.1版本,目前主流依然是1.1 19 | * 支持了持久连接,一个连接可以发送多个请求,并且支持一个连接同时发送多个请求(服务器端需要按顺序返回结果) 20 | * 支持了更多的方法:PUT、PATCH、DELETE、OPTIONS 21 | * 客户端请求头信息增加Host字段,指定服务器的域名,这样服务器上支持了虚拟主机,即一台机器多个站点 22 | 23 | ##### HTTP/2 版本 24 | * 2015年发布,目前还未正式大规模使用,但大多浏览器已经支持HTTP/2 25 | * 在之前版本HTTP header必须是文本(ASCII编码)格式,body部分可以是文本也可以是二进制,但在HTTP/2,无论是header还是body都是二进制数据 26 | * HTTP/2支持了在一个连接里,客户端和服务端同时发送多个请求 27 | * 因为支持了在一个连接里同时发送多个请求和多个回应,为了区分它们就需要对数据做标记,每个请求或回应的所有数据包为一个数据流(stream),每个数据流都有一个唯一的ID,客户端发送的请求ID为奇数,服务端返回的为偶数 28 | * HTTP/2支持header压缩,并且支持header信息索引(客户端和服务端有一张相同的索引表,不同的header对应不同的索引号,发送请求时不会再发header,而是发索引号) 29 | * HTTP/2支持服务端主动推送功能,如果一个网页中含有大量的静态资源(js、css、图片等),之前版本是当该网页传输完成后解析所有html代码,然后再去传输网页中包含的资源,HTTP/2版本可以在网页没有传输完之前就主动把该网页中包含的静态资源推送到客户端,这样省去了客户端再次发请求的过程。 30 | 31 | ##### HTTP/3版本 32 | * 2018年发布,基于谷歌的QUIC,底层使用udp代码tcp协议。 33 | * 使用stream进一步扩展HTTP2.0 的多路复用,传输多少文件就可以产生多少stream,若发生丢包,只需要传输丢失的stream 34 | * 基于UDP,提高了传输效率,降低延迟 35 | * 通过引入 Connection ID,使得 HTTP/3 支持连接迁移以及 NAT 的重绑定 36 | * HTTP/3 含有一个包括验证、加密、数据及负载的 built-in 的 TLS 安全机制 37 | -------------------------------------------------------------------------------- /java/nginx_tomcat.md: -------------------------------------------------------------------------------- 1 | #### Nginx+Tomcat架构 2 | ``` 3 | 配置文件示例 4 | server 5 | { 6 | listen 80; 7 | server_name www.aminglinux.com; 8 | 9 | location ~* "\.(jpg|png|jepg|js|css|xml|bmp|swf|gif|html)$" 10 | { 11 | root /data/wwwroot/aminglinux/; 12 | access_log off; 13 | expire 7d; 14 | } 15 | 16 | location / 17 | { 18 | proxy_pass http://127.0.0.1:8080/; 19 | proxy_set_header Host $host; 20 | proxy_set_header X-Real-IP $remote_addr; 21 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 22 | } 23 | } 24 | 25 | 说明: 26 | 1 首先,把各种静态文件的请求分离出来,单独由nginx处理。 27 | 2 其他请求直接代理8080端口,即tomcat服务。 28 | ``` -------------------------------------------------------------------------------- /lnmp/nginx_php.md: -------------------------------------------------------------------------------- 1 | #### 配置Nginx和php 2 | ``` 3 | 配置如下(在server部分添加): 4 | location ~ \.php$ { 5 | include fastcgi_params; 6 | fastcgi_pass unix:/tmp/php-fcgi.sock; 7 | fastcgi_index index.php; 8 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 9 | } 10 | 11 | 配置说明: 12 | 1 fastcgi_params文件在/usr/local/nginx/conf/下面,其内容为fastcgi相关的变量 13 | 2 fastcgi_pass后面跟的是php-fpm服务监听地址,可以是IP:PORT,也可以是unix socket地址,也支持upstream的地址 14 | 3 fastcgi_index定义索引页,如果在server内其他部分有定义index参数,该配置可以忽略 15 | 4 fastcgi_param这行其实可以在fastcgi_params文件里面定义SCRIPT_FILENAME变量,这个变量如果不定义,php的请求是没办法访问的。 16 | ``` 17 | -------------------------------------------------------------------------------- /location/priority.md: -------------------------------------------------------------------------------- 1 | #### nginx location优先级 2 | 3 | = 高于 ^~ 高于 ~* 等于 ~ 高于 / 4 | 5 | ##### 对比/ 和 ~ 6 | 7 | 示例1: 8 | server{ 9 | listen 80; 10 | server_name www.aminglinux.com; 11 | root /tmp/123.com; 12 | 13 | location /abc/ 14 | { 15 | echo "/"; 16 | } 17 | location ~ 'abc' 18 | { 19 | echo "~"; 20 | } 21 | } 22 | 23 | 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/1.png' 24 | 结果是:~ 25 | 26 | ##### 对比~ 和 ~* 27 | 28 | 示例2: 29 | server 30 | { 31 | listen 80; 32 | server_name www.aminglinux.com; 33 | root /tmp/123.com; 34 | 35 | location ~ 'abc' 36 | { 37 | echo '~'; 38 | } 39 | location ~* 'abc' 40 | { 41 | echo '~*'; 42 | } 43 | } 44 | 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html' 45 | 结果是:~ 46 | 47 | 示例3: 48 | server 49 | { 50 | listen 80; 51 | server_name www.aminglinux.com; 52 | root /tmp/123.com; 53 | 54 | location ~* 'abc' 55 | { 56 | echo '~*'; 57 | } 58 | location ~ 'abc' 59 | { 60 | echo '~'; 61 | } 62 | } 63 | 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html' 64 | 结果是:~* 65 | 66 | 结论:~和~*优先级其实是一样的,如果两个同时出现,配置文件中哪个location靠前,哪个生效。 67 | 68 | ##### 对比 ^~ 和 ~ 69 | 70 | 示例4: 71 | server 72 | { 73 | listen 80; 74 | server_name www.aminglinux.com; 75 | root /tmp/123.com; 76 | 77 | location ~ '/abc' 78 | { 79 | echo '~'; 80 | } 81 | location ^~ '/abc' 82 | { 83 | echo '^~'; 84 | } 85 | } 86 | 87 | 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc/123.html 88 | 结果是:^~ 89 | 90 | ##### 对比= 和 ^~ 91 | 92 | 示例5: 93 | server 94 | { 95 | listen 80; 96 | server_name www.aminglinux.com; 97 | root /tmp/123.com; 98 | 99 | location ^~ '/abc.html' 100 | { 101 | echo '^~'; 102 | } 103 | location = '/abc.html' 104 | { 105 | echo '='; 106 | } 107 | } 108 | 109 | 测试命令:curl -x127.0.0.1:80 'www.aminglinux.com/abc.html 110 | 结果是:= 111 | -------------------------------------------------------------------------------- /location/ruler.md: -------------------------------------------------------------------------------- 1 | #### nginx的location配置 2 | 3 | nginx location语法规则:location [=|~|~*|^~] /uri/ { … } 4 | nginx的location匹配的变量是$uri 5 | 6 | | 符号 | 说明 | 7 | | :-------- | :----- | 8 | | = | 表示精确匹配| 9 | | ^~| 表示uri以指定字符或字符串开头| 10 | | ~ | 表示区分大小写的正则匹配| 11 | | ~*| 表示不区分大小写的正则匹配| 12 | |/| 通用匹配,任何请求都会匹配到| 13 | 14 | ##### 规则优先级 15 | 16 | = 高于 ^~ 高于 ~* 等于 ~ 高于 / 17 | 18 | ##### 规则示例 19 | 20 | location = "/12.jpg" { ... } 21 | 如: 22 | www.aminglinux.com/12.jpg 匹配 23 | www.aminglinux.com/abc/12.jpg 不匹配 24 | 25 | location ^~ "/abc/" { ... } 26 | 如: 27 | www.aminglinux.com/abc/123.html 匹配 28 | www.aminglinux.com/a/abc/123.jpg 不匹配 29 | 30 | location ~ "png" { ... } 31 | 如: 32 | www.aminglinux.com/aaa/bbb/ccc/123.png 匹配 33 | www.aminglinux.com/aaa/png/123.html 匹配 34 | 35 | location ~* "png" { ... } 36 | 如: 37 | www.aminglinux.com/aaa/bbb/ccc/123.PNG 匹配 38 | www.aminglinux.com/aaa/png/123.html 匹配 39 | 40 | 41 | location /admin/ { ... } 42 | 如: 43 | www.aminglinux.com/admin/aaa/1.php 匹配 44 | www.aminglinux.com/123/admin/1.php 不匹配 45 | 46 | ##### 小常识 47 | 48 | 有些资料上介绍location支持不匹配 !~, 49 | 如: location !~ 'png'{ ... } 50 | 这是错误的,location不支持 !~ 51 | 52 | 如果有这样的需求,可以通过if来实现, 53 | 如: if ($uri !~ 'png') { ... } 54 | 55 | 注意:location优先级小于if 56 | 57 | -------------------------------------------------------------------------------- /log/acclog.md: -------------------------------------------------------------------------------- 1 | #### Nginx访问日志配置 2 | ``` 3 | web服务器的访问日志是非常重要的,我们可以通过访问日志来分析用户的访问情况, 4 | 也可以通过访问日志发现一些异常访问,比如cc攻击。 5 | 6 | 格式: access_log /path/to/logfile format; 7 | 8 | access_log可以配置到http, server, location配置段中。 9 | 10 | ``` 11 | ##### 配置示例 12 | ``` 13 | server 14 | { 15 | listen 80; 16 | server_name www.aminglinux.com; 17 | root /data/wwwroot/www.aminglinux.com; 18 | index index.html index.php; 19 | access_log /data/logs/www.aminglinux.com_access.log main; 20 | } 21 | 说明:若不指定log_format,则按照默认的格式写日志。 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /log/error.md: -------------------------------------------------------------------------------- 1 | #### Nginx的错误日志 2 | ``` 3 | Nginx错误日志平时不用太关注,但是一旦出了问题,就需要借助错误日志来判断问题所在。 4 | 5 | 配置参数格式:error_log /path/to/log level; 6 | ``` 7 | 8 | ##### Nginx错误日志级别 9 | ``` 10 | 常见的错误日志级别有debug | info | notice | warn | error | crit | alert | emerg 11 | 级别越高记录的信息越少,如果不定义,默认级别为error. 12 | 13 | 它可以配置在main、http、server、location段里。 14 | 15 | 如果在配置文件中定义了两个error_log,在同一个配置段里的话会产生冲突,所以同一个段里只允许配置一个error_log。 16 | 但是,在不同的配置段中出现是没问题的。 17 | ``` 18 | 19 | ##### Nginx错误日志示例 20 | ``` 21 | error_log /var/log/nginx/error.log crit; 22 | 23 | 如果要想彻底关闭error_log,需要这样配置 24 | error_log /dev/null; 25 | ``` 26 | -------------------------------------------------------------------------------- /log/filter.md: -------------------------------------------------------------------------------- 1 | #### Nginx访问日志过滤 2 | ``` 3 | 一个网站,会包含很多元素,尤其是有大量的图片、js、css等静态元素。 4 | 这样的请求其实可以不用记录日志。 5 | ``` 6 | ##### 配置示例 7 | ``` 8 | location ~* ^.+\.(gif|jpg|png|css|js)$ 9 | { 10 | access_log off; 11 | } 12 | 13 | 或 14 | location ~* ^.+\.(gif|jpg|png|css|js)$ 15 | { 16 | access_log /dev/null; 17 | } 18 | ``` 19 | -------------------------------------------------------------------------------- /log/format.md: -------------------------------------------------------------------------------- 1 | #### Nginx访问日志格式 2 | ``` 3 | Nginx访问日志可以设置自定义的格式,来满足特定的需求。 4 | ``` 5 | 6 | ##### 访问日志格式示例 7 | ``` 8 | 示例1 9 | log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]' 10 | '$host "$request_uri" $status' 11 | '"$http_referer" "$http_user_agent"'; 12 | 13 | 示例2 14 | log_format main '$remote_addr [$time_local] ' 15 | '$host "$request_uri" $status "$request"' 16 | '"$http_referer" "$http_user_agent" "$request_time"'; 17 | 18 | 若不配置log_format或者不在access_log配置中指定log_format,则默认格式为: 19 | '$remote_addr - $remote_user [$time_local] "$request" ' 20 | '$status $body_bytes_sent "$http_referer" ' 21 | '"$http_user_agent"; 22 | 23 | ``` 24 | ##### 常见变量 25 | | 变量 | 说明 | 26 | | :-------- | :----- | 27 | |$time_local| 通用日志格式下的本地时间;(服务器时间)| 28 | |$remote_addr|客户端(用户)IP地址| 29 | |$status| 请求状态码,如200,404,301,302等| 30 | |$body_bytes_sent |发送给客户端的字节数,不包括响应头的大小| 31 | |$bytes_sent|发送给客户端的总字节数| 32 | |$request_length|请求的长度(包括请求行,请求头和请求正文)| 33 | |$request_time |请求处理时间,单位为秒,小数的形式| 34 | |$upstream_addr|集群轮询地址| 35 | |$upstream_response_time|指从Nginx向后端(php-cgi)建立连接开始到接受完数据然后关闭连接为止的时间| 36 | |$remote_user|用来记录客户端用户名称| 37 | |$request |请求方式(GET或者POST等)+URL(包含$request_method,$host,$request_uri)| 38 | |$http_user_agent|用户浏览器标识| 39 | |$http_host |请求的url地址(目标url地址)的host| 40 | |$host|等同于$http_host| 41 | |$http_referer|来源页面,即从哪个页面转到本页,如果直接在浏览器输入网址来访问,则referer为空| 42 | |$uri |请求中的当前URI(不带请求参数,参数位于$args),不同于浏览器传递的$request_uri的值,它可以通过内部重定向,或者使用index指令进行修改。| 43 | |$document_uri|等同于$uri| 44 | |$request_uri|比$uri多了参数,即$uri+$args| 45 | |$http_x_forwarded_for|如果使用了代理,这个参数会记录代理服务器的ip和客户端的ip| 46 | 47 | 48 | -------------------------------------------------------------------------------- /log/rotate.md: -------------------------------------------------------------------------------- 1 | #### Nginx访问日志切割 2 | ``` 3 | 如果任由访问日志写下去,日志文件会变得越来越大,甚至是写满磁盘。 4 | 所以,我们需要想办法把日志做切割,比如每天生成一个新的日志,旧的日志按规定时间删除即可。 5 | 6 | 实现日志切割可以通过写shell脚本或者系统的日志切割机制实现。 7 | ``` 8 | ##### shell脚本切割Nginx日志 9 | ``` 10 | 切割脚本内容: 11 | #!/bin/bash 12 | logdir=/var/log/nginx //定义日志路径 13 | prefix=`date -d "-1 day" +%y%m%d` //定义切割后的日志前缀 14 | cd $logdir 15 | for f in `ls *.log` 16 | do 17 | mv $f $f-$prefix //把日志改名 18 | done 19 | /bin/kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid 2>/dev/null) 2>/dev/null //生成新的日志 20 | bzip2 *$prefix //压缩日志 21 | find . -type f -mtime +180 |xargs /bin/rm -f //删除超过180天的老日志 22 | 23 | ``` 24 | ##### 系统日志切割机制 25 | ``` 26 | 在/etc/logrotate.d/下创建nginx文件,内容为: 27 | /data/logs/*log { 28 | daily 29 | rotate 30 30 | missingok 31 | notifempty 32 | compress 33 | sharedscripts 34 | postrotate 35 | /bin/kill -USR1 $(cat /usr/local/nginx/logs/nginx.pid 2>/dev/null) 2>/dev/null 36 | endscript 37 | } 38 | 39 | 说明: 40 | 1 nginx日志在/data/logs/目录下面,日志名字以log结尾 41 | 2 daily表示每天切割 42 | 3 rotate 30表示日志保留30天 43 | 4 missingok表示忽略错误 44 | 5 notifempty表示如果日志为空,不切割 45 | 6 compress表示压缩 46 | 7 sharedscripts和endscript中间可以引用系统的命令 47 | 8 postrotate表示当切割之后要执行的命令 48 | ``` 49 | -------------------------------------------------------------------------------- /mon/stat.md: -------------------------------------------------------------------------------- 1 | #### 配置Nginx状态 2 | ``` 3 | Nginx有内置一个状态页,需要在编译的时候指定参数--with-http_stub_status_module参数方可打开。 4 | 也就是说,该功能是由http_stub_status_module模块提供,默认没有加载。 5 | ``` 6 | 7 | ##### Nginx配置文件示例 8 | ``` 9 | server{ 10 | listen 80; 11 | server_name www.aminglinux.com; 12 | 13 | location /status/ { 14 | stub_status on; 15 | access_log off; 16 | allow 127.0.0.1; 17 | allow 192.168.10.0/24; 18 | deny all; 19 | } 20 | } 21 | 22 | ``` 23 | 24 | ##### 配置说明 25 | * location /status/这样当访问/status/时即可访问到状态页内容。 26 | * stub_status on即打开了状态页。 27 | * access_log off不记录日志 28 | * allow和deny只允许指定IP和IP段访问,因为这个页面需要保护起来,并不公开,当然也可以做用户认证。 29 | 30 | ##### 测试和结果说明 31 | ``` 32 | 测试命令:curl -x127.0.0.1:80 www.aminglinux.com/status/ 33 | 34 | 结果如下: 35 | Active connections: 1 36 | server accepts handled requests 37 | 11 11 11 38 | Reading: 0 Writing: 1 Waiting: 0 39 | 40 | 说明: 41 | active connections – 活跃的连接数量 42 | server accepts handled requests — 总共处理的连接数、成功创建的握手次数、总共处理的请求次数 43 | 需要注意,一个连接可以有多次请求。 44 | reading — 读取客户端的连接数. 45 | writing — 响应数据到客户端的数量 46 | waiting — 开启 keep-alive 的情况下,这个值等于 active – (reading+writing), 意思就是 Nginx 已经处理完正在等候下一次请求指令的驻留连接. 47 | ``` -------------------------------------------------------------------------------- /optimize/linux_kernel.md: -------------------------------------------------------------------------------- 1 | #### 调整Linux内核参数 2 | ``` 3 | 作为高性能WEB服务器,只调整Nginx本身的参数是不行的,因为Nginx服务依赖于高性能的操作系统。 4 | 以下为常见的几个Linux内核参数优化方法。 5 | ``` 6 | * 1 net.ipv4.tcp_max_tw_buckets 7 | ``` 8 | 对于tcp连接,服务端和客户端通信完后状态变为timewait,假如某台服务器非常忙,连接数特别多的话,那么这个timewait数量就会越来越大。 9 | 毕竟它也是会占用一定的资源,所以应该有一个最大值,当超过这个值,系统就会删除最早的连接,这样始终保持在一个数量级。 10 | 这个数值就是由net.ipv4.tcp_max_tw_buckets这个参数来决定的。 11 | CentOS7系统,你可以使用sysctl -a |grep tw_buckets来查看它的值,默认为32768, 12 | 你可以适当把它调低,比如调整到8000,毕竟这个状态的连接太多也是会消耗资源的。 13 | 但你不要把它调到几十、几百这样,因为这种状态的tcp连接也是有用的, 14 | 如果同样的客户端再次和服务端通信,就不用再次建立新的连接了,用这个旧的通道,省时省力。 15 | ``` 16 | * 2 net.ipv4.tcp_tw_recycle = 1 17 | ``` 18 | 该参数的作用是快速回收timewait状态的连接。上面虽然提到系统会自动删除掉timewait状态的连接,但如果把这样的连接重新利用起来岂不是更好。 19 | 所以该参数设置为1就可以让timewait状态的连接快速回收,它需要和下面的参数配合一起使用。 20 | ``` 21 | 22 | * 3 net.ipv4.tcp_tw_reuse = 1 23 | ``` 24 | 该参数设置为1,将timewait状态的连接重新用于新的TCP连接,要结合上面的参数一起使用。 25 | ``` 26 | * 4 net.ipv4.tcp_syncookies = 1 27 | ``` 28 | tcp三次握手中,客户端向服务端发起syn请求,服务端收到后,也会向客户端发起syn请求同时连带ack确认, 29 | 假如客户端发送请求后直接断开和服务端的连接,不接收服务端发起的这个请求,服务端会重试多次, 30 | 这个重试的过程会持续一段时间(通常高于30s),当这种状态的连接数量非常大时,服务器会消耗很大的资源,从而造成瘫痪, 31 | 正常的连接进不来,这种恶意的半连接行为其实叫做syn flood攻击。 32 | 设置为1,是开启SYN Cookies,开启后可以避免发生上述的syn flood攻击。 33 | 开启该参数后,服务端接收客户端的ack后,再向客户端发送ack+syn之前会要求client在短时间内回应一个序号, 34 | 如果客户端不能提供序号或者提供的序号不对则认为该客户端不合法,于是不会发ack+syn给客户端,更涉及不到重试。 35 | ``` 36 | * 5 net.ipv4.tcp_max_syn_backlog 37 | ``` 38 | 该参数定义系统能接受的最大半连接状态的tcp连接数。客户端向服务端发送了syn包,服务端收到后,会记录一下, 39 | 该参数决定最多能记录几个这样的连接。在CentOS7,默认是256,当有syn flood攻击时,这个数值太小则很容易导致服务器瘫痪, 40 | 实际上此时服务器并没有消耗太多资源(cpu、内存等),所以可以适当调大它,比如调整到30000。 41 | ``` 42 | * 6 net.ipv4.tcp_syn_retries 43 | ``` 44 | 该参数适用于客户端,它定义发起syn的最大重试次数,默认为6,建议改为2。 45 | ``` 46 | * 7 net.ipv4.tcp_synack_retries 47 | ``` 48 | 该参数适用于服务端,它定义发起syn+ack的最大重试次数,默认为5,建议改为2,可以适当预防syn flood攻击。 49 | ``` 50 | * 8 net.ipv4.ip_local_port_range 51 | ``` 52 | 该参数定义端口范围,系统默认保留端口为1024及以下,以上部分为自定义端口。这个参数适用于客户端, 53 | 当客户端和服务端建立连接时,比如说访问服务端的80端口,客户端随机开启了一个端口和服务端发起连接, 54 | 这个参数定义随机端口的范围。默认为32768 61000,建议调整为1025 61000。 55 | ``` 56 | * 9 net.ipv4.tcp_fin_timeout 57 | ``` 58 | tcp连接的状态中,客户端上有一个是FIN-WAIT-2状态,它是状态变迁为timewait前一个状态。 59 | 该参数定义不属于任何进程的该连接状态的超时时间,默认值为60,建议调整为6。 60 | ``` 61 | * 10 net.ipv4.tcp_keepalive_time 62 | ``` 63 | tcp连接状态里,有一个是established状态,只有在这个状态下,客户端和服务端才能通信。正常情况下,当通信完毕, 64 | 客户端或服务端会告诉对方要关闭连接,此时状态就会变为timewait,如果客户端没有告诉服务端, 65 | 并且服务端也没有告诉客户端关闭的话(例如,客户端那边断网了),此时需要该参数来判定。 66 | 比如客户端已经断网了,但服务端上本次连接的状态依然是established,服务端为了确认客户端是否断网, 67 | 就需要每隔一段时间去发一个探测包去确认一下看看对方是否在线。这个时间就由该参数决定。它的默认值为7200秒,建议设置为30秒。 68 | ``` 69 | * 11 net.ipv4.tcp_keepalive_intvl 70 | ``` 71 | 该参数和上面的参数是一起的,服务端在规定时间内发起了探测,查看客户端是否在线,如果客户端并没有确认, 72 | 此时服务端还不能认定为对方不在线,而是要尝试多次。该参数定义重新发送探测的时间,即第一次发现对方有问题后,过多久再次发起探测。 73 | 默认值为75秒,可以改为3秒。 74 | ``` 75 | * 12 net.ipv4.tcp_keepalive_probes 76 | ``` 77 | 第10和第11个参数规定了何时发起探测和探测失败后再过多久再发起探测,但并没有定义一共探测几次才算结束。 78 | 该参数定义发起探测的包的数量。默认为9,建议设置2。 79 | ``` 80 | 81 | ##### 设置和范例 82 | ``` 83 | 在Linux下调整内核参数,可以直接编辑配置文件/etc/sysctl.conf,然后执行sysctl -p命令生效 84 | 85 | 结合以上分析的各内核参数,范例如下 86 | net.ipv4.tcp_fin_timeout = 6 87 | net.ipv4.tcp_keepalive_time = 30 88 | net.ipv4.tcp_max_tw_buckets = 8000 89 | net.ipv4.tcp_tw_reuse = 1 90 | net.ipv4.tcp_tw_recycle = 1 91 | net.ipv4.tcp_syncookies = 1 92 | net.ipv4.tcp_max_syn_backlog = 30000 93 | net.ipv4.tcp_syn_retries = 2 94 | net.ipv4.tcp_synack_retries = 2 95 | net.ipv4.ip_local_port_range = 1025 61000 96 | net.ipv4.tcp_keepalive_intvl = 3 97 | net.ipv4.tcp_keepalive_probes = 2 98 | 99 | 100 | ``` -------------------------------------------------------------------------------- /optimize/nginx_opt.md: -------------------------------------------------------------------------------- 1 | #### Nginx配置参数优化 2 | 3 | ``` 4 | Nginx作为高性能web服务器,即使不特意调整配置参数也可以处理大量的并发请求。 5 | 以下的配置参数是借鉴网上的一些调优参数,仅作为参考,不见得适于你的线上业务。 6 | ``` 7 | 8 | ##### worker进程 9 | 10 | * worker_processes 11 | ``` 12 | 该参数表示启动几个工作进程,建议和本机CPU核数保持一致,每一核CPU处理一个进程。 13 | ``` 14 | 15 | * worker_rlimit_nofile 16 | ``` 17 | 它表示Nginx最大可用的文件描述符个数,需要配合系统的最大描述符,建议设置为102400。 18 | 还需要在系统里执行ulimit -n 102400才可以。 19 | 也可以直接修改配置文件/etc/security/limits.conf修改 20 | 增加: 21 | #* soft nofile 655350 (去掉前面的#) 22 | #* hard nofile 655350 (去掉前面的#) 23 | ``` 24 | * worker_connections 25 | ``` 26 | 该参数用来配置每个Nginx worker进程最大处理的连接数,这个参数也决定了该Nginx服务器最多能处理多少客户端请求 27 | (worker_processes * worker_connections),建议把该参数设置为10240,不建议太大。 28 | ``` 29 | 30 | ##### http和tcp连接 31 | 32 | * use epoll 33 | ``` 34 | 使用epoll模式的事件驱动模型,该模型为Linux系统下最优方式。 35 | ``` 36 | * multi_accept on 37 | ``` 38 | 使每个worker进程可以同时处理多个客户端请求。 39 | ``` 40 | * sendfile on 41 | ``` 42 | 使用内核的FD文件传输功能,可以减少user mode和kernel mode的切换,从而提升服务器性能。 43 | ``` 44 | * tcp_nopush on 45 | ``` 46 | 当tcp_nopush设置为on时,会调用tcp_cork方法进行数据传输。 47 | 使用该方法会产生这样的效果:当应用程序产生数据时,内核不会立马封装包,而是当数据量积累到一定量时才会封装,然后传输。 48 | ``` 49 | * tcp_nodelay on 50 | ``` 51 | 不缓存data-sends(关闭 Nagle 算法),这个能够提高高频发送小数据报文的实时性。 52 | (关于Nagle算法) 53 | 【假如需要频繁的发送一些小包数据,比如说1个字节,以IPv4为例的话,则每个包都要附带40字节的头, 54 | 也就是说,总计41个字节的数据里,其中只有1个字节是我们需要的数据。 55 | 为了解决这个问题,出现了Nagle算法。 56 | 它规定:如果包的大小满足MSS,那么可以立即发送,否则数据会被放到缓冲区,等到已经发送的包被确认了之后才能继续发送。 57 | 通过这样的规定,可以降低网络里小包的数量,从而提升网络性能。】 58 | ``` 59 | 60 | * keepalive_timeout 61 | ``` 62 | 定义长连接的超时时间,建议30s,太短或者太长都不一定合适,当然,最好是根据业务自身的情况来动态地调整该参数。 63 | ``` 64 | * keepalive_requests 65 | ``` 66 | 定义当客户端和服务端处于长连接的情况下,每个客户端最多可以请求多少次,可以设置很大,比如50000. 67 | ``` 68 | * reset_timeout_connection on 69 | ``` 70 | 设置为on的话,当客户端不再向服务端发送请求时,允许服务端关闭该连接。 71 | ``` 72 | * client_body_timeout 73 | ``` 74 | 客户端如果在该指定时间内没有加载完body数据,则断开连接,单位是秒,默认60,可以设置为10。 75 | ``` 76 | * send_timeout 77 | ``` 78 | 这个超时时间是发送响应的超时时间,即Nginx服务器向客户端发送了数据包,但客户端一直没有去接收这个数据包。 79 | 如果某个连接超过send_timeout定义的超时时间,那么Nginx将会关闭这个连接。单位是秒,可以设置为3。 80 | ``` 81 | 82 | ##### buffer和cache(以下配置都是针对单个请求) 83 | 84 | * client_body_buffer_size 85 | ``` 86 | 当客户端以POST方法提交一些数据到服务端时,会先写入到client_body_buffer中,如果buffer写满会写到临时文件里,建议调整为128k。 87 | ``` 88 | * client_max_body_size 89 | ``` 90 | 浏览器在发送含有较大HTTP body的请求时,其头部会有一个Content-Length字段,client_max_body_size是用来限制Content-Length所示值的大小的。 91 | 这个限制body的配置不用等Nginx接收完所有的HTTP包体,就可以告诉用户请求过大不被接受。会返回413状态码。 92 | 例如,用户试图上传一个1GB的文件,Nginx在收完包头后,发现Content-Length超过client_max_body_size定义的值, 93 | 就直接发送413(Request Entity Too Large)响应给客户端。 94 | 将该数值设置为0,则禁用限制,建议设置为10m。 95 | ``` 96 | * client_header_buffer_size 97 | ``` 98 | 设置客户端header的buffer大小,建议4k。 99 | ``` 100 | * large_client_header_buffers 101 | ``` 102 | 对于比较大的header(超过client_header_buffer_size)将会使用该部分buffer,两个数值,第一个是个数,第二个是每个buffer的大小。 103 | 建议设置为4 8k 104 | ``` 105 | * open_file_cache 106 | ``` 107 | 该参数会对以下信息进行缓存: 108 | 打开文件描述符的文件大小和修改时间信息; 109 | 存在的目录信息; 110 | 搜索文件的错误信息(文件不存在无权限读取等信息)。 111 | 格式:open_file_cache max=size inactive=time; 112 | max设定缓存文件的数量,inactive设定经过多长时间文件没被请求后删除缓存。 113 | 建议设置 open_file_cache max=102400 inactive=20s; 114 | ``` 115 | 116 | * open_file_cache_valid 117 | ``` 118 | 指多长时间检查一次缓存的有效信息。建议设置为30s。 119 | ``` 120 | 121 | * open_file_cache_min_uses 122 | ``` 123 | open_file_cache指令中的inactive参数时间内文件的最少使用次数, 124 | 如,将该参数设置为1,则表示,如果文件在inactive时间内一次都没被使用,它将被移除。 125 | 建议设置为2。 126 | ``` 127 | 128 | ##### 压缩 129 | 130 | ``` 131 | 对于纯文本的内容,Nginx是可以使用gzip压缩的。使用压缩技术可以减少对带宽的消耗。 132 | 由ngx_http_gzip_module模块支持 133 | 134 | 配置如下: 135 | gzip on; //开启gzip功能 136 | gzip_min_length 1024; //设置请求资源超过该数值才进行压缩,单位字节 137 | gzip_buffers 16 8k; //设置压缩使用的buffer大小,第一个数字为数量,第二个为每个buffer的大小 138 | gzip_comp_level 6; //设置压缩级别,范围1-9,9压缩级别最高,也最耗费CPU资源 139 | gzip_types text/plain application/x-javascript text/css application/xml image/jpeg image/gif image/png; //指定哪些类型的文件需要压缩 140 | gzip_disable "MSIE 6\."; //IE6浏览器不启用压缩 141 | 142 | 测试: 143 | curl -I -H "Accept-Encoding: gzip, deflate" http://www.aminglinux.com/1.css 144 | 145 | ``` 146 | ##### 日志 147 | * 错误日志级别调高,比如crit级别,尽量少记录无关紧要的日志。 148 | * 对于访问日志,如果不要求记录日志,可以关闭, 149 | * 静态资源的访问日志关闭 150 | 151 | ##### 静态文件过期 152 | ``` 153 | 对于静态文件,需要设置一个过期时间,这样可以让这些资源缓存到客户端浏览器, 154 | 在缓存未失效前,客户端不再向服务期请求相同的资源,从而节省带宽和资源消耗。 155 | 156 | 配置示例如下: 157 | location ~* ^.+\.(gif|jpg|png|css|js)$ 158 | { 159 | expires 1d; //1d表示1天,也可以用24h表示一天。 160 | } 161 | ``` 162 | 163 | ##### 作为代理服务器 164 | ``` 165 | Nginx绝大多数情况下都是作为代理或者负载均衡的角色。 166 | 因为前面章节已经介绍过以下参数的含义,在这里只提供对应的配置参数: 167 | http 168 | { 169 | proxy_cache_path /data/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g; 170 | ...; 171 | server 172 | { 173 | proxy_buffering on; 174 | proxy_buffer_size 4k; 175 | proxy_buffers 2 4k; 176 | proxy_busy_buffers_size 4k; 177 | proxy_temp_path /tmp/nginx_proxy_tmp 1 2; 178 | proxy_max_temp_file_size 20M; 179 | proxy_temp_file_write_size 8k; 180 | 181 | location / 182 | { 183 | proxy_cache my_zone; 184 | ...; 185 | } 186 | } 187 | } 188 | 189 | ``` 190 | 191 | ##### SSL优化 192 | * 适当减少worker_processes数量,因为ssl功能需要使用CPU的计算。 193 | * 使用长连接,因为每次建立ssl会话,都会耗费一定的资源(加密、解密) 194 | * 开启ssl缓存,简化服务端和客户端的“握手”过程。 195 | ``` 196 | ssl_session_cache shared:SSL:10m; //缓存为10M 197 | ssl_session_timeout 10m; //会话超时时间为10分钟 198 | ``` 199 | -------------------------------------------------------------------------------- /proxy/bu_ca.md: -------------------------------------------------------------------------------- 1 | #### nginx的proxy_buffering和proxy_cache 2 | ``` 3 | 两个都是nginx代理中内存设置相关的参数。 4 | ``` 5 | 6 | ##### proxy_buffering设置 7 | ``` 8 | proxy_buffering主要是实现被代理服务器的数据和客户端的请求异步。 9 | 为了方便理解,我们定义三个角色,A为客户端,B为代理服务器,C为被代理服务器。 10 | 11 | 当proxy_buffering开启,A发起请求到B,B再到C,C反馈的数据先到B的buffer上, 12 | 然后B会根据proxy_busy_buffer_size来决定什么时候开始把数据传输给A。在此过程中,如果所有的buffer被写满, 13 | 数据将会写入到temp_file中。 14 | 15 | 相反,如果proxy_buffering关闭,C反馈的数据实时地通过B传输给A。 16 | ``` 17 | 18 | ##### #以下配置,都是针对每一个http请求的。 19 | ``` 20 | 1. proxy_buffering on; 21 | 该参数设置是否开启proxy的buffer功能,参数的值为on或者off。 22 | 如果这个设置为off,那么proxy_buffers和proxy_busy_buffers_size这两个指令将会失效。 23 | 但是无论proxy_buffering是否开启,proxy_buffer_size都是生效的 24 | 25 | 2. proxy_buffer_size 4k; 26 | 该参数用来设置一个特殊的buffer大小的。 27 | 从被代理服务器(C)上获取到的第一部分响应数据内容到代理服务器(B)上,通常是header,就存到了这个buffer中。 28 | 如果该参数设置太小,会出现502错误码,这是因为这部分buffer不够存储header信息。建议设置为4k。 29 | 30 | 3. proxy_buffers 8 4k; 31 | 这个参数设置存储被代理服务器上的数据所占用的buffer的个数和每个buffer的大小。 32 | 所有buffer的大小为这两个数字的乘积。 33 | 34 | 4. proxy_busy_buffer_size 16k; 35 | 在所有的buffer里,我们需要规定一部分buffer把自己存的数据传给A,这部分buffer就叫做busy_buffer。 36 | proxy_busy_buffer_size参数用来设置处于busy状态的buffer有多大。 37 | 38 | 对于B上buffer里的数据何时传输给A,我个人的理解是这样的: 39 | 1)如果完整数据大小小于busy_buffer大小,当数据传输完成后,马上传给A; 40 | 2)如果完整数据大小不少于busy_buffer大小,则装满busy_buffer后,马上传给A; 41 | 42 | 5. proxy_temp_path 43 | 语法:proxy_temp_path path [level1 level2 level3] 44 | 定义proxy的临时文件存在目录以及目录的层级。 45 | 46 | 例:proxy_temp_path /usr/local/nginx/proxy_temp 1 2; 47 | 其中/usr/local/nginx/proxy_temp为临时文件所在目录,1表示层级1的目录名为一个数字(0-9),2表示层级2目录名为2个数字(00-99) 48 | 49 | 6. proxy_max_temp_file_size 50 | 设置临时文件的总大小,例如 proxy_max_temp_file_size 100M; 51 | 52 | 7. proxy_temp_file_wirte_size 53 | 设置同时写入临时文件的数据量的总大小。通常设置为8k或者16k。 54 | 55 | ``` 56 | ##### proxy_buffer示例 57 | ``` 58 | server 59 | { 60 | listen 80; 61 | server_name www.aminglinux.com; 62 | proxy_buffering on; 63 | proxy_buffer_size 4k; 64 | proxy_buffers 2 4k; 65 | proxy_busy_buffers_size 4k; 66 | proxy_temp_path /tmp/nginx_proxy_tmp 1 2; 67 | proxy_max_temp_file_size 20M; 68 | proxy_temp_file_write_size 8k; 69 | 70 | location / 71 | { 72 | proxy_pass http://192.168.10.110:8080/; 73 | proxy_set_header Host $host; 74 | proxy_set_header X-Real-IP $remote_addr; 75 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 76 | 77 | } 78 | 79 | } 80 | ``` 81 | 82 | ##### proxy_cache设置 83 | ``` 84 | proxy_cache将从C上获取到的数据根据预设规则存放到B上(内存+磁盘)留着备用, 85 | A请求B时,B会把缓存的这些数据直接给A,而不需要再去向C去获取。 86 | 87 | proxy_cache相关功能生效的前提是,需要设置proxy_buffering on; 88 | 89 | ``` 90 | ##### #proxy_cache主要参数 91 | ``` 92 | 1. proxy_cache 93 | 语法:proxy_cache zone|off 94 | 95 | 默认为off,即关闭proxy_cache功能,zone为用于存放缓存的内存区域名称。 96 | 例:proxy_cache my_zone; 97 | 98 | 从nginx 0.7.66版本开始,proxy_cache机制开启后会检测被代理端的HTTP响应头中的"Cache-Control"、"Expire"头域。 99 | 如,Cache-Control为no-cache时,是不会缓存数据的。 100 | 101 | 2. proxy_cache_bypass 102 | 语法:proxy_cache_bypass string; 103 | 104 | 该参数设定,什么情况下的请求不读取cache而是直接从后端的服务器上获取资源。 105 | 这里的string通常为nginx的一些变量。 106 | 107 | 例:proxy_cahce_bypass $cookie_nocache $arg_nocache$arg_comment; 108 | 意思是,如果$cookie_nocache $arg_nocache$arg_comment这些变量的值只要任何一个不为0或者不为空时, 109 | 则响应数据不从cache中获取,而是直接从后端的服务器上获取。 110 | 111 | 3. proxy_no_cache 112 | 语法:proxy_no_cache string; 113 | 114 | 该参数和proxy_cache_bypass类似,用来设定什么情况下不缓存。 115 | 116 | 例:proxy_no_cache $cookie_nocache $arg_nocache $arg_comment; 117 | 表示,如果$cookie_nocache $arg_nocache $arg_comment的值只要有一项不为0或者不为空时,不缓存数据。 118 | 119 | 4. proxy_cache_key 120 | 语法:proxy_cache_key string; 121 | 122 | 定义cache key,如: proxy_cache_key $scheme$proxy_host$uri$is_args$args; (该值为默认值,一般不用设置) 123 | 124 | 5. proxy_cache_path 125 | 语法:proxy_cache_path path [levels=levels] keys_zone=name:size [inactive=time] [max_size=size] 126 | 127 | path设置缓存数据存放的路径; 128 | 129 | levels设置目录层级,如levels=1:2,表示有两级子目录,第一个目录名取md5值的倒数第一个值,第二个目录名取md5值的第2和3个值。如下图: 130 | ``` 131 | ![image](https://coding.net/u/aminglinux/p/nginx/git/raw/master/proxy/nginx_cache_levels.png) 132 | ``` 133 | keys_zone设置内存zone的名字和大小,如keys_zone=my_zone:10m 134 | 135 | inactive设置缓存多长时间就失效,当硬盘上的缓存数据在该时间段内没有被访问过,就会失效了,该数据就会被删除,默认为10s。 136 | 137 | max_size设置硬盘中最多可以缓存多少数据,当到达该数值时,nginx会删除最少访问的数据。 138 | 139 | 例:proxy_cache_path /data/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g 140 | 141 | ``` 142 | ##### proxy_cache示例 143 | ``` 144 | http 145 | { 146 | ...; 147 | 148 | proxy_cache_path /data/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g; 149 | 150 | ...; 151 | 152 | server 153 | { 154 | listen 80; 155 | server_name www.aminglinux.com; 156 | proxy_buffering on; 157 | proxy_buffer_size 4k; 158 | proxy_buffers 2 4k; 159 | proxy_busy_buffers_size 4k; 160 | proxy_temp_path /tmp/nginx_proxy_tmp 1 2; 161 | proxy_max_temp_file_size 20M; 162 | proxy_temp_file_write_size 8k; 163 | 164 | 165 | 166 | location / 167 | { 168 | proxy_cache my_zone; 169 | proxy_pass http://192.168.10.110:8080/; 170 | proxy_set_header Host $host; 171 | proxy_set_header X-Real-IP $remote_addr; 172 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 173 | 174 | } 175 | 176 | } 177 | } 178 | 179 | 说明:核心配置为proxy_cache_path那一行。 180 | ``` 181 | -------------------------------------------------------------------------------- /proxy/f_proxy.md: -------------------------------------------------------------------------------- 1 | #### Nginx反向代理配置 2 | 3 | ``` 4 | Nginx反向代理在生产环境中使用很多的。 5 | 6 | 场景1: 7 | 域名没有备案,可以把域名解析到香港一台云主机上,在香港云主机做个代理,而网站数据是在大陆的服务器上。 8 | 9 | 示例1: 10 | server 11 | { 12 | listen 80; 13 | server_name aminglinux.com; 14 | 15 | location / 16 | { 17 | proxy_pass http://123.23.13.11/; 18 | proxy_set_header Host $host; 19 | proxy_set_header X-Real-IP $remote_addr; 20 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 21 | } 22 | } 23 | ``` 24 | ##### 配置说明 25 | ##### #1. proxy_pass 26 | 27 | 在正向代理中,已经使用过该指令。 28 | 格式很简单: proxy_pass URL; 29 | 其中URL包含:传输协议(http://, https://等)、主机名(域名或者IP:PORT)、uri。 30 | 31 | 示例如下: 32 | proxy_pass http://www.aminglinux.com/; 33 | proxy_pass http://192.168.200.101:8080/uri; 34 | proxy_pass unix:/tmp/www.sock; 35 | 36 | 对于proxy_pass的配置有几种情况需要注意。 37 | 示例2: 38 | location /aming/ 39 | { 40 | proxy_pass http://192.168.1.10; 41 | ... 42 | } 43 | 44 | 45 | 示例3: 46 | location /aming/ 47 | { 48 | proxy_pass http://192.168.1.10/; 49 | ... 50 | } 51 | 52 | 示例4: 53 | location /aming/ 54 | { 55 | proxy_pass http://192.168.1.10/linux/; 56 | ... 57 | } 58 | 59 | 示例5: 60 | location /aming/ 61 | { 62 | proxy_pass http://192.168.1.10/linux; 63 | ... 64 | } 65 | 66 | 假设server_name为www.aminglinux.com 67 | 当请求http://www.aminglinux.com/aming/a.html的时候,以上示例2-5分别访问的结果是 68 | 69 | 示例2:http://192.168.1.10/aming/a.html 70 | 71 | 示例3:http://192.168.1.10/a.html 72 | 73 | 示例4:http://192.168.1.10/linux/a.html 74 | 75 | 示例5:http://192.168.1.10/linuxa.html 76 | 77 | 78 | ##### #2. proxy_set_header 79 | ``` 80 | proxy_set_header用来设定被代理服务器接收到的header信息。 81 | 82 | 语法:proxy_set_header field value; 83 | field为要更改的项目,也可以理解为变量的名字,比如host 84 | value为变量的值 85 | 86 | 如果不设置proxy_set_header,则默认host的值为proxy_pass后面跟的那个域名或者IP(一般写IP), 87 | 比如示例4,请求到后端的服务器上时,完整请求uri为:http://192.168.1.10/linux/a.html 88 | 89 | 如果设置proxy_set_header,如 proxy_set_header host $host; 90 | 比如示例4,请求到后端的服务器完整uri为:http://www.aminglinux.com/linux/a.html 91 | 92 | proxy_set_header X-Real-IP $remote_addr;和proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 93 | 用来设置被代理端接收到的远程客户端IP,如果不设置,则header信息中并不会透传远程真实客户端的IP地址。 94 | 可以用如下示例来测试: 95 | 96 | 示例6(被代理端) 97 | server{ 98 | listen 8080; 99 | server_name www.aminglinux.com; 100 | root /tmp/123.com_8080; 101 | index index.html; 102 | location /linux/ { 103 | echo "$host"; 104 | echo $remote_addr; 105 | echo $proxy_add_x_forwarded_for; 106 | } 107 | } 108 | 109 | 示例7(代理服务器上) 110 | server { 111 | listen 80; 112 | server_name www.aminglinux.com; 113 | 114 | location /aming/ 115 | { 116 | proxy_pass http://192.168.1.10:8080/linux/; 117 | proxy_set_header host $host; 118 | proxy_set_header X-Real-IP $remote_addr; 119 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 120 | } 121 | } 122 | 123 | ``` 124 | ##### #3. proxy_redirect 125 | ``` 126 | 该指令用来修改被代理服务器返回的响应头中的Location头域和“refresh”头域。 127 | 语法结构为: 128 | proxy_redirect redirect replacement; 129 | proxy_redirect default; 130 | proxy_redirect off; 131 | 132 | 示例8: 133 | server { 134 | listen 80; 135 | server_name www.aminglinux.com; 136 | index index.html; 137 | 138 | location / 139 | { 140 | proxy_pass http://127.0.0.1:8080; 141 | proxy_set_header host $host; 142 | proxy_set_header X-Real-IP $remote_addr; 143 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 144 | } 145 | } 146 | 147 | 当请求的链接为 http://www.aminglinux.com/aming 148 | 结果会返回301,定向到了 http://www.aminglinux.com:8080/aming/ 149 | 150 | 注意:返回301有几个先决条件 151 | 1. location后面必须是/; 152 | 2. proxy_pass后面的URL不能加uri,只能是IP或者IP:port结尾,并不能以/结尾; 153 | 3. 访问的uri必须是一个真实存在的目录,如,这里的aming必须是存在的 154 | 4. 访问的时候,不能以/结尾,只能是 www.aminglinux.com/aming 155 | 156 | 虽然,这4个条件挺苛刻,但确实会遇到类似的请求。解决方法是,加一行proxy_redirect http://$host:8080/ /; 157 | 158 | 示例9: 159 | server { 160 | listen 80; 161 | server_name www.aminglinux.com; 162 | index index.html; 163 | 164 | location / 165 | { 166 | proxy_pass http://127.0.0.1:8080; 167 | proxy_set_header host $host; 168 | proxy_redirect http://$host:8080/ /; 169 | proxy_set_header X-Real-IP $remote_addr; 170 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 171 | } 172 | } 173 | 174 | 175 | ``` -------------------------------------------------------------------------------- /proxy/f_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/proxy/f_proxy.png -------------------------------------------------------------------------------- /proxy/fp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/proxy/fp2.png -------------------------------------------------------------------------------- /proxy/lb.md: -------------------------------------------------------------------------------- 1 | #### Nginx的负载均衡配置 2 | ``` 3 | Nginx通过upstream和proxy_pass实现了负载均衡。本质上也是Nginx的反向代理功能,只不过后端的server为多个。 4 | ``` 5 | 6 | ##### 案例一(简单的轮询) 7 | ``` 8 | upstream www { 9 | server 172.37.150.109:80; 10 | server 172.37.150.101:80; 11 | server 172.37.150.110:80; 12 | } 13 | 14 | server { 15 | listen 80; 16 | server_name www.aminglinux.com; 17 | location / { 18 | proxy_pass http://www/; 19 | proxy_set_header Host $host; 20 | proxy_set_header X-Real-IP $remote_addr; 21 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 22 | } 23 | } 24 | 25 | 说明:当被代理的机器有多台时,需要使用upstream来定义一个服务器组, 26 | 其中www名字可以自定义,在后面的proxy_pass那里引用。 27 | 这样nginx会将请求均衡地轮询发送给www组内的三台服务器。 28 | 29 | ``` 30 | 31 | ##### 案例二(带权重轮询+ip_hash算法) 32 | ``` 33 | upstream www { 34 | server 172.37.150.109:80 weight=50; 35 | server 172.37.150.101:80 weight=100; 36 | server 172.37.150.110:80 weight=50; 37 | ip_hash; 38 | } 39 | 40 | server { 41 | listen 80; 42 | server_name www.aminglinux.com; 43 | location / { 44 | proxy_pass http://www/; 45 | proxy_set_header Host $host; 46 | proxy_set_header X-Real-IP $remote_addr; 47 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 48 | } 49 | } 50 | 51 | 说明:可以给www组内的三台机器配置权重,权重越高,则分配到的请求越多。 52 | ip_hash为nginx负载均衡算法,原理很简单,它根据请求所属的客户端IP计算得到一个数值,然后把请求发往该数值对应的后端。 53 | 所以同一个客户端的请求,都会发往同一台后端,除非该后端不可用了。ip_hash能够达到保持会话的效果。 54 | 55 | ``` 56 | 57 | ##### 案例三(upstream其他配置) 58 | ``` 59 | upstream www { 60 | server 172.37.150.109:80 weight=50 max_fails=3 fail_timeout=30s; 61 | server 172.37.150.101:80 weight=100; 62 | server 172.37.150.110:80 down; 63 | server 172.37.150.110:80 backup; 64 | } 65 | server 66 | { 67 | listen 80; 68 | server_name www.aminglinux.com; 69 | location / { 70 | proxy_next_upstream off; 71 | proxy_pass http://www/; 72 | proxy_set_header Host $host; 73 | proxy_set_header X-Real-IP $remote_addr; 74 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 75 | } 76 | } 77 | 78 | 说明:down,表示当前的server不参与负载均衡; 79 | backup,为预留的机器,当其他的server(非backup)出现故障或者忙的时候,才会请求backup机器; 80 | max_fails,允许请求失败的次数,默认为1。当失败次数达到该值,就认为该机器down掉了。 失败的指标是由proxy_next_upstream模块定义,其中404状态码不认为是失败。 81 | fail_timeount,定义失败的超时时间,也就是说在该时间段内达到max_fails,才算真正的失败。默认是10秒。 82 | 83 | proxy_next_upstream,通过后端服务器返回的响应状态码,表示服务器死活,可以灵活控制后端机器是否加入分发列表。 84 | 语法: proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_404 | off ...; 85 | 默认值: proxy_next_upstream error timeout 86 | 87 | error # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现错误 88 | timeout # 和后端服务器建立连接时,或者向后端服务器发送请求时,或者从后端服务器接收响应头时,出现超时 89 | invalid_header # 后端服务器返回空响应或者非法响应头 90 | http_500 # 后端服务器返回的响应状态码为500 91 | http_502 # 后端服务器返回的响应状态码为502 92 | http_503 # 后端服务器返回的响应状态码为503 93 | http_504 # 后端服务器返回的响应状态码为504 94 | http_404 # 后端服务器返回的响应状态码为404 95 | off # 停止将请求发送给下一台后端服务器 96 | 97 | ``` 98 | 99 | ##### 案例四(根据不同的uri) 100 | ``` 101 | upstream aa.com { 102 | server 192.168.0.121; 103 | server 192.168.0.122; 104 | } 105 | upstream bb.com { 106 | server 192.168.0.123; 107 | server 192.168.0.124; 108 | } 109 | server { 110 | listen 80; 111 | server_name www.aminglinux.com; 112 | location ~ aa.php 113 | { 114 | proxy_pass http://aa.com/; 115 | proxy_set_header Host $host; 116 | proxy_set_header X-Real-IP $remote_addr; 117 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 118 | } 119 | location ~ bb.php 120 | { 121 | proxy_pass http://bb.com/; 122 | proxy_set_header Host $host; 123 | proxy_set_header X-Real-IP $remote_addr; 124 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 125 | } 126 | location / 127 | { 128 | proxy_pass http://bb.com/; 129 | proxy_set_header Host $host; 130 | proxy_set_header X-Real-IP $remote_addr; 131 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 132 | } 133 | } 134 | 135 | 说明:请求aa.php的,会到aa.com组,请求bb.php的会到bb.com,其他请求全部到bb.com。 136 | 137 | ``` 138 | ##### 案例五(根据不同的目录) 139 | ``` 140 | upstream aaa.com 141 | { 142 | server 192.168.111.6; 143 | } 144 | upstream bbb.com 145 | { 146 | server 192.168.111.20; 147 | } 148 | server { 149 | listen 80; 150 | server_name www.aminglinux.com; 151 | location /aaa/ 152 | { 153 | proxy_pass http://aaa.com/aaa/; 154 | proxy_set_header Host $host; 155 | proxy_set_header X-Real-IP $remote_addr; 156 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 157 | } 158 | location /bbb/ 159 | { 160 | proxy_pass http://bbb.com/bbb/; 161 | proxy_set_header Host $host; 162 | proxy_set_header X-Real-IP $remote_addr; 163 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 164 | } 165 | location / 166 | { 167 | proxy_pass http://bbb.com/; 168 | proxy_set_header Host $host; 169 | proxy_set_header X-Real-IP $remote_addr; 170 | proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 171 | } 172 | } 173 | ``` -------------------------------------------------------------------------------- /proxy/nginx_cache_levels.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/proxy/nginx_cache_levels.png -------------------------------------------------------------------------------- /proxy/pic.md: -------------------------------------------------------------------------------- 1 | ##### 正向代理 2 | ![image](http://ask.apelearn.com/uploads/nginx/z_proxy.png) 3 | 4 | ![image](http://ask.apelearn.com/uploads/nginx/zp2.png) 5 | 6 | ##### 反向代理 7 | ![image](http://ask.apelearn.com/uploads/nginx/f_proxy.png) 8 | 9 | ![image](http://ask.apelearn.com/uploads/nginx/fp2.png) 10 | 11 | -------------------------------------------------------------------------------- /proxy/stream.md: -------------------------------------------------------------------------------- 1 | #### nginx 从1.9.0版本开始支持四层代理,但做四层代理时 编译需要添加 --with-stream模块 2 | 3 | #### nginx配置文件示例 4 | 5 | ``` 6 | http { 7 | ...... 8 | } 9 | 10 | ## stram模块 和http模块是一同等级 11 | stream { 12 | upstream app_server{ 13 | server 192.168.0.14:8028; 14 | #server 192.168.0.15:8028; 15 | } 16 | 17 | server { 18 | listen 8028; #8028端口将以4层TCP协议方式转发至后端app_sever; 19 | proxy_pass app_server; 20 | } 21 | 22 | } 23 | ``` 24 | 25 | #### UDP示例 26 | ``` 27 | stream { 28 | upstream dns { 29 | server 192.168.0.13:53; 30 | } 31 | 32 | server { 33 | listen 53 udp; 34 | proxy_pass dns; 35 | proxy_timeout 5s; 36 | } 37 | } 38 | 39 | ``` 40 | -------------------------------------------------------------------------------- /proxy/z_proxy.md: -------------------------------------------------------------------------------- 1 | #### Nginx正向代理配置 2 | 3 | Nginx正向代理使用场景并不多见。 4 | 需求场景1: 5 | 如果在机房中,只有一台机器可以联网,其他机器只有内网,内网的机器想用使用yum安装软件包,在能能联网的机器上配置一个正向代理即可。 6 | 7 | ##### Nginx正向代理配置文件 8 | 9 | 说明: 以下配置文件为nginx官方提供,该方法只能实现针对http的网站的访问,如果是https就会有问题。要想实现https的正向代理,可以使用一个三方模块,后面介绍。 10 | ``` 11 | server { 12 | listen 80 default_server; 13 | resolver 119.29.29.29; 14 | location / 15 | { 16 | proxy_pass http://$host$request_uri; 17 | } 18 | } 19 | ``` 20 | 21 | ##### Nginx正向代理配置执行说明 22 | 23 | * resolver 24 | 25 | 26 | ``` 27 | 语法:resolver address; 28 | 29 | address为DNS服务器的地址,国内通用的DNS 119.29.29.29为dnspod公司提供。 国际通用DNS 8.8.8.8或者8.8.4.4为google提供。 30 | 其他可以参考 http://dns.lisect.com/ 31 | 32 | 示例:resolver 119.29.29.29; 33 | ``` 34 | 35 | * default_server 36 | 37 | ``` 38 | 之所以要设置为默认虚拟主机,是因为这样就不用设置server_name了,任何域名解析过来都可以正常访问。 39 | ``` 40 | 41 | * proxy_pass 42 | 43 | ``` 44 | 该指令用来设置要代理的目标url,正向代理服务器设置就保持该固定值即可。关于该指令的详细解释在反向代理配置中。 45 | ``` 46 | 47 | ##### Nginx正向代理支持https 48 | 49 | 下载三方模块ngx_http_proxy_connect_module,github地址:https://github.com/chobits/ngx_http_proxy_connect_module 50 | 注意,不同的Nginx版本,还需要下载不同的patch包。 51 | 52 | 下面的例子,以1.9.12为例 53 | 54 | ``` 55 | wget http://nginx.org/download/nginx-1.9.12.tar.gz 56 | tar -xzvf nginx-1.9.12.tar.gz 57 | cd nginx-1.9.12/ 58 | patch -p1 < /path/to/ngx_http_proxy_connect_module/patch/proxy_connect.patch 59 | ./configure --add-dynamic-module=/path/to/ngx_http_proxy_connect_module 60 | make && make install 61 | 62 | ``` 63 | 64 | Nginx正向代理配置文件 65 | ``` 66 | server { 67 | listen 3128; 68 | 69 | 70 | # dns resolver used by forward proxying 71 | resolver 119.29.29.29; 72 | 73 | 74 | # forward proxy for CONNECT request 75 | proxy_connect; 76 | proxy_connect_allow 80 443 3000 9070 9074; 77 | proxy_connect_connect_timeout 10s; 78 | proxy_connect_read_timeout 10s; 79 | proxy_connect_send_timeout 10s; 80 | 81 | 82 | # forward proxy for non-CONNECT request 83 | location / { 84 | proxy_pass http://$host; 85 | proxy_set_header Host $host; 86 | } 87 | } 88 | 89 | ``` 90 | 91 | 测试示例 92 | ``` 93 | $ curl https://github.com/ -v -x 127.0.0.1:3128 94 | * Trying 127.0.0.1... -. 95 | * Connected to 127.0.0.1 (127.0.0.1) port 3128 (#0) | curl creates TCP connection with nginx (with proxy_connect module). 96 | * Establish HTTP proxy tunnel to github.com:443 -' 97 | > CONNECT github.com:443 HTTP/1.1 -. 98 | > Host: github.com:443 (1) | curl sends CONNECT request to create tunnel. 99 | > User-Agent: curl/7.43.0 | 100 | > Proxy-Connection: Keep-Alive -' 101 | > 102 | < HTTP/1.0 200 Connection Established .- nginx replies 200 that tunnel is established. 103 | < Proxy-agent: nginx (2)| (The client is now being proxied to the remote host. Any data sent 104 | < '- to nginx is now forwarded, unmodified, to the remote host) 105 | 106 | * Proxy replied OK to CONNECT request 107 | * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 -. 108 | * Server certificate: github.com | 109 | * Server certificate: DigiCert SHA2 Extended Validation Server CA | curl sends "https://github.com" request via tunnel, 110 | * Server certificate: DigiCert High Assurance EV Root CA | proxy_connect module will proxy data to remote host (github.com). 111 | > GET / HTTP/1.1 | 112 | > Host: github.com (3) | 113 | > User-Agent: curl/7.43.0 | 114 | > Accept: */* -' 115 | > 116 | < HTTP/1.1 200 OK .- 117 | < Date: Fri, 11 Aug 2017 04:13:57 GMT | 118 | < Content-Type: text/html; charset=utf-8 | Any data received from remote host will be sent to client 119 | < Transfer-Encoding: chunked | by proxy_connect module. 120 | < Server: GitHub.com (4)| 121 | < Status: 200 OK | 122 | < Cache-Control: no-cache | 123 | < Vary: X-PJAX | 124 | ... | 125 | ... ... | 126 | ... 127 | 128 | ``` 129 | 130 | #### linux机器上配置全局代理 131 | 在 /etc/profile 文件中增加如下三项。 132 | ``` 133 | export proxy="http://{proxy_server_ip}:3128" 134 | export http_proxy=$proxy 135 | export https_proxy=$proxy 136 | ``` 137 | 138 | 使配置生效 139 | ``` 140 | source /etc/profile 141 | ``` 142 | 143 | 对那些没有域名解析通过绑定hosts文件来访问的域名,不让其走http/https代理,需要额外增加环境变量: 144 | ``` 145 | export no_proxy='a.test.com,127.0.0.1,2.2.2.2' 146 | ``` 147 | -------------------------------------------------------------------------------- /proxy/z_proxy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/proxy/z_proxy.png -------------------------------------------------------------------------------- /proxy/zp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/proxy/zp2.png -------------------------------------------------------------------------------- /rewrite/break.md: -------------------------------------------------------------------------------- 1 | #### rewrite中的break和last 2 | 3 | 两个指令用法相同,但含义不同,需要放到rewrite规则的末尾,用来控制重写后的链接是否继续被nginx配置执行(主要是rewrite、return指令)。 4 | 5 | 示例1(连续两条rewrite规则): 6 | server{ 7 | listen 80; 8 | server_name test.com; 9 | root /tmp/123.com; 10 | 11 | rewrite /1.html /2.html ; 12 | rewrite /2.html /3.html ; 13 | 14 | } 15 | 当我们请求1.html时,最终访问到的是3.html,两条rewrite规则先后执行。 16 | 17 | 18 | ##### break和last在location {}外部 19 | 20 | 格式:rewrite xxxxx break; 21 | 22 | 示例2(增加break): 23 | server{ 24 | listen 80; 25 | server_name test.com; 26 | root /tmp/123.com; 27 | 28 | rewrite /1.html /2.html break; 29 | rewrite /2.html /3.html; 30 | } 31 | 当我们请求1.html时,最终访问到的是2.html 32 | 说明break在此示例中,作用是不再执行break以下的rewrite规则。 33 | 34 | 但,当配置文件中有location时,它还会去执行location{}段的配置(请求要匹配该location)。 35 | 36 | 示例3(break后面还有location段): 37 | server{ 38 | listen 80; 39 | server_name test.com; 40 | root /tmp/123.com; 41 | 42 | rewrite /1.html /2.html break; 43 | rewrite /2.html /3.html; 44 | location /2.html { 45 | return 403; 46 | } 47 | } 48 | 当请求1.html时,最终会返回403状态码,说明它去匹配了break后面的location{}配置。 49 | 50 | 以上2个示例中,可以把break替换为last,它们两者起到的效果一模一样。 51 | 52 | ##### 当break和last在location{}里面 53 | 54 | 示例4(什么都不加): 55 | server{ 56 | listen 80; 57 | server_name test.com; 58 | root /tmp/123.com; 59 | 60 | location / { 61 | rewrite /1.html /2.html; 62 | rewrite /2.html /3.html; 63 | } 64 | location /2.html 65 | { 66 | rewrite /2.html /a.html; 67 | } 68 | location /3.html 69 | { 70 | rewrite /3.html /b.html; 71 | } 72 | } 73 | 当请求/1.html,最终将会访问/b.html,连续执行location /下的两次rewrite,跳转到了/3.html,然后又匹配location /3.html 74 | 75 | 示例5(增加break): 76 | server{ 77 | listen 80; 78 | server_name test.com; 79 | root /tmp/123.com; 80 | 81 | location / { 82 | rewrite /1.html /2.html break; 83 | rewrite /2.html /3.html; 84 | } 85 | location /2.html 86 | { 87 | rewrite /2.html /a.html; 88 | } 89 | location /3.html 90 | { 91 | rewrite /3.html /b.html; 92 | } 93 | } 94 | 当请求/1.html,最终会访问/2.html 95 | 在location{}内部,遇到break,本location{}内以及后面的所有location{}内的所有指令都不再执行。 96 | 97 | 98 | 示例6(增加last): 99 | server{ 100 | listen 80; 101 | server_name test.com; 102 | root /tmp/123.com; 103 | 104 | location / { 105 | rewrite /1.html /2.html last; 106 | rewrite /2.html /3.html; 107 | } 108 | location /2.html 109 | { 110 | rewrite /2.html /a.html; 111 | } 112 | location /3.html 113 | { 114 | rewrite /3.html /b.html; 115 | } 116 | } 117 | 当请求/1.html,最终会访问/a.html 118 | 在location{}内部,遇到last,本location{}内后续指令不再执行,而重写后的url再次从头开始,从头到尾匹配一遍规则。 119 | 120 | 121 | ##### 结论 122 | 123 | * 当rewrite规则在location{}外,break和last作用一样,遇到break或last后,其后续的rewrite/return语句不再执行。但后续有location{}的话,还会近一步执行location{}里面的语句,当然前提是请求必须要匹配该location。 124 | * 当rewrite规则在location{}里,遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行。 125 | * 当rewrite规则在location{}里,遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。 126 | 127 | 128 | -------------------------------------------------------------------------------- /rewrite/example.md: -------------------------------------------------------------------------------- 1 | #### Rewrite实战 2 | 3 | 本部分内容为nginx生产环境中使用的场景示例。 4 | 5 | ##### 域名跳转(域名重定向) 6 | 7 | 示例1(不带条件的): 8 | server{ 9 | listen 80; 10 | server_name www.aminglinux.com; 11 | rewrite /(.*) http://www.aming.com/$1 permanent; 12 | ....... 13 | 14 | } 15 | 16 | 示例2(带条件的): 17 | server{ 18 | listen 80; 19 | server_name www.aminglinux.com aminglinux.com; 20 | if ($host != 'www.aminglinux.com') 21 | { 22 | rewrite /(.*) http://www.aminglinux.com/$1 permanent; 23 | } 24 | ....... 25 | 26 | } 27 | 示例3(http跳转到https): 28 | server{ 29 | listen 80; 30 | server_name www.aminglinux.com; 31 | rewrite /(.*) https://www.aminglinux.com/$1 permanent; 32 | ....... 33 | 34 | } 35 | 示例4(域名访问二级目录) 36 | server{ 37 | listen 80; 38 | server_name bbs.aminglinux.com; 39 | rewrite /(.*) http://www.aminglinux.com/bbs/$1 last; 40 | ....... 41 | 42 | } 43 | 示例5(静态请求分离) 44 | server{ 45 | listen 80; 46 | server_name www.aminglinux.com; 47 | location ~* ^.+.(jpg|jpeg|gif|css|png|js)$ 48 | { 49 | rewrite /(.*) http://img.aminglinux.com/$1 permanent; 50 | } 51 | 52 | ....... 53 | 54 | } 55 | 或者: 56 | server{ 57 | listen 80; 58 | server_name www.aminglinux.com; 59 | if ( $uri ~* 'jpg|jpeg|gif|css|png|js$') 60 | { 61 | rewrite /(.*) http://img.aminglinux.com/$1 permanent; 62 | } 63 | 64 | ....... 65 | 66 | } 67 | 68 | ##### 防盗链 69 | 70 | 示例6 71 | server{ 72 | listen 80; 73 | server_name www.aminglinux.com; 74 | location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$ 75 | { 76 | valid_referers none blocked server_names *.aminglinux.com aminglinux.com *.aming.com aming.com; 77 | if ($invalid_referer) 78 | { 79 | rewrite /(.*) http://img.aminglinux.com/images/forbidden.png; 80 | } 81 | } 82 | 83 | ....... 84 | 85 | } 86 | 说明:*这里是通配,跟正则里面的*不是一个意思,none指的是referer不存在的情况(curl -e 测试), 87 | blocked指的是referer头部的值被防火墙或者代理服务器删除或者伪装的情况, 88 | 该情况下,referer头部的值不以http://或者https://开头(curl -e 后面跟的referer不以http://或者https://开头)。 89 | 或者: 90 | location ~* ^.+.(jpg|jpeg|gif|css|png|js|rar|zip|flv)$ 91 | { 92 | valid_referers none blocked server_names *.aminglinux.com *.aming.com aminglinux.com aming.com; 93 | if ($invalid_referer) 94 | { 95 | return 403; 96 | } 97 | } 98 | 99 | 100 | ##### 伪静态 101 | 102 | 示例7(discuz伪静态): 103 | location / { 104 | rewrite ^([^\.]*)/topic-(.+)\.html$ $1/portal.php?mod=topic&topic=$2 last; 105 | rewrite ^([^\.]*)/forum-(\w+)-([0-9]+)\.html$ $1/forum.php?mod=forumdisplay&fid=$2&page=$3 last; 106 | rewrite ^([^\.]*)/thread-([0-9]+)-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=viewthread&tid=$2&extra=page%3D$4&page=$3 last; 107 | rewrite ^([^\.]*)/group-([0-9]+)-([0-9]+)\.html$ $1/forum.php?mod=group&fid=$2&page=$3 last; 108 | rewrite ^([^\.]*)/space-(username|uid)-(.+)\.html$ $1/home.php?mod=space&$2=$3 last; 109 | rewrite ^([^\.]*)/(fid|tid)-([0-9]+)\.html$ $1/index.php?action=$2&value=$3 last; 110 | } 111 | 112 | ##### rewrite多个条件的并且 113 | 114 | 示例8: 115 | location /{ 116 | set $rule 0; 117 | if ($document_uri !~ '^/abc') 118 | { 119 | set $rule "${rule}1"; 120 | } 121 | if ($http_user_agent ~* 'ie6|firefox') 122 | { 123 | set $rule "${rule}2"; 124 | } 125 | if ($rule = "012") 126 | { 127 | rewrite /(.*) /abc/$1 redirect; 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /rewrite/if.md: -------------------------------------------------------------------------------- 1 | #### if指令 2 | 3 | 格式:if (条件判断) { 具体的rewrite规则 } 4 | 5 | ##### 条件举例 6 | 7 | 条件判断语句由Nginx内置变量、逻辑判断符号和目标字符串三部分组成。 8 | 其中,内置变量是Nginx固定的非自定义的变量,如,$request_method, $request_uri等。 9 | 逻辑判断符号,有=, !=, ~, ~*, !~, !~* 10 | !表示相反的意思,~为匹配符号,它右侧为正则表达式,区分大小写,而~*为不区分大小写匹配。 11 | 目标字符串可以是正则表达式,通常不用加引号,但表达式中有特殊符号时,比如空格、花括号、分号等,需要用单引号引起来。 12 | 13 | ##### 示例1 14 | 15 | if ($request_method = POST) //当请求的方法为POST时,直接返回405状态码 16 | { 17 | return 405; //在该示例中并未用到rewrite规则,if中支持用return指令。 18 | } 19 | 20 | ##### 示例2 21 | 22 | if ($http_user_agent ~ MSIE) //user_agent带有MSIE字符的请求,直接返回403状态码 23 | { 24 | return 403; 25 | } 26 | 27 | 如果想同时限制多个user_agent,还可以写成这样 28 | 29 | if ($http_user_agent ~ "MSIE|firefox|spider") 30 | { 31 | return 403; 32 | } 33 | 34 | ##### 示例3 35 | 36 | if(!-f $request_filename) //当请求的文件不存在,将会执行下面的rewrite规则 37 | { 38 | rewrite 语句; 39 | } 40 | 41 | ##### 示例4 42 | 43 | if($request_uri ~* 'gid=\d{9,12}/') //\d表示数字,{9,12}表示数字出现的次数是9到12次,如gid=123456789/就是符合条件的。 44 | { 45 | rewrite 语句; 46 | } 47 | 48 | 49 | -------------------------------------------------------------------------------- /rewrite/return.md: -------------------------------------------------------------------------------- 1 | #### nginx的return指令 2 | 3 | 该指令一般用于对请求的客户端直接返回响应状态码。在该作用域内return后面的所有nginx配置都是无效的。 4 | 可以使用在server、location以及if配置中。 5 | 6 | 除了支持跟状态码,还可以跟字符串或者url链接。 7 | 8 | ##### 直接返回状态码 9 | 10 | 示例1: 11 | server{ 12 | listen 80; 13 | server_name www.aming.com; 14 | return 403; 15 | rewrite /(.*) /abc/$1; //该行配置不会被执行。 16 | } 17 | 18 | 示例2: 19 | server { 20 | ..... 21 | 22 | if ($request_uri ~ "\.htpasswd|\.bak") 23 | { 24 | return 404; 25 | rewrite /(.*) /aaa.txt; //该行配置不会被执行。 26 | } 27 | //如果下面还有其他配置,会被执行。 28 | ..... 29 | } 30 | 31 | ##### 返回字符串 32 | 33 | 示例3: 34 | server{ 35 | listen 80; 36 | server_name www.aming.com; 37 | return 200 "hello"; 38 | } 39 | 说明:如果要想返回字符串,必须要加上状态码,否则会报错。 40 | 还可以支持json数据 41 | 42 | 示例4: 43 | location ^~ /aming { 44 | default_type application/json ; 45 | return 200 '{"name":"aming","id":"100"}'; 46 | } 47 | 48 | 也支持写一个变量 49 | 50 | 示例5: 51 | location /test { 52 | return 200 "$host $request_uri"; 53 | } 54 | 55 | ##### 返回url 56 | 57 | 示例6: 58 | server{ 59 | listen 80; 60 | server_name www.aming.com; 61 | return http://www.aminglinux.com/123.html; 62 | rewrite /(.*) /abc/$1; //该行配置不会被执行。 63 | } 64 | 注意:return后面的url必须是以http://或者https://开头的。 65 | 66 | 67 | ##### 生产场景实战 68 | 69 | 背景:网站被黑了,凡是在百度点击到本网站的请求,全部都跳转到了一个赌博网站。 70 | 通过nginx解决: 71 | if ($http_referer ~ 'baidu.com') 72 | { 73 | return 200 ""; 74 | } 75 | 76 | 如果写成: 77 | return http://$host$request_uri; 在浏览器中会提示“重定向的次数过多”。 78 | 79 | 80 | -------------------------------------------------------------------------------- /rewrite/rewrite_ruler.md: -------------------------------------------------------------------------------- 1 | #### rewrite规则 2 | 3 | 格式:rewrite regex replacement [flag] 4 | 5 | * rewrite配置可以在server、location以及if配置段内生效 6 | 7 | * regex是用于匹配URI的正则表达式,其不会匹配到$host(域名) 8 | 9 | * replacement是目标跳转的URI,可以以http://或者https://开头,也可以省略掉$host,直接写$request_uri部分(即请求的链接) 10 | 11 | * flag,用来设置rewrite对URI的处理行为,其中有break、last、rediect、permanent,其中break和last在前面已经介绍过, 12 | rediect和permanent的区别在于,前者为临时重定向(302),而后者是永久重定向(301),对于用户通过浏览器访问,这两者的效果是一致的。 13 | 但是,对于搜索引擎蜘蛛爬虫来说就有区别了,使用301更有利于SEO。所以,建议replacemnet是以http://或者https://开头的flag使用permanent。 14 | 15 | ##### 示例1 16 | 17 | location / { 18 | rewrite /(.*) http://www.aming.com/$1 permanent; 19 | } 20 | 说明:.*为正则表达式,用()括起来,在后面的URI中可以调用它,第一次出现的()用$1调用,第二次出现的()用$2调用,以此类推。 21 | 22 | ##### 示例2 23 | 24 | location / { 25 | rewrite /.* http://www.aming.com$request_uri permanent; 26 | } 27 | 说明:在replacement中,支持变量,这里的$request_uri就是客户端请求的链接 28 | 29 | ##### 示例3 30 | 31 | server{ 32 | listen 80; 33 | server_name www.123.com; 34 | root /tmp/123.com; 35 | index index.html; 36 | rewrite /(.*) /abc/$1 redirect; 37 | } 38 | 说明:本例中的rewrite规则有问题,会造连续循环,最终会失败,解决该问题有两个方案。 39 | 关于循环次数,经测试发现,curl 会循环50次,chrome会循环80次,IE会循环120次,firefox会循环20次。 40 | 41 | ##### 示例4 42 | 43 | server{ 44 | listen 80; 45 | server_name www.123.com; 46 | root /tmp/123.com; 47 | index index.html; 48 | rewrite /(.*) /abc/$1 break; 49 | } 50 | 说明:在rewrite中使用break,会避免循环。 51 | 52 | ##### 示例5 53 | 54 | server{ 55 | listen 80; 56 | server_name www.123.com; 57 | root /tmp/123.com; 58 | index index.html; 59 | if ($request_uri !~ '^/abc/') 60 | { 61 | rewrite /(.*) /abc/$1 redirect; 62 | } 63 | } 64 | 说明:加一个条件限制,也可以避免产生循环 -------------------------------------------------------------------------------- /rewrite/variable.md: -------------------------------------------------------------------------------- 1 | #### nginx 常用全局变量 2 | 3 | | 变量 | 说明 | 4 | | :-------- | :----- | 5 | |$args |请求中的参数,如www.123.com/1.php?a=1&b=2的$args就是a=1&b=2 | 6 | |$content_length |HTTP请求信息里的"Content-Length" | 7 | |$conten_type | HTTP请求信息里的"Content-Type" | 8 | |$document_root|nginx虚拟主机配置文件中的root参数对应的值| 9 | |$document_uri|当前请求中不包含指令的URI,如www.123.com/1.php?a=1&b=2的$document_uri就是1.php,不包含后面的参数| 10 | |$host|主机头,也就是域名| 11 | |$http_user_agent|客户端的详细信息,也就是浏览器的标识,用curl -A可以指定| 12 | |$http_cookie|客户端的cookie信息| 13 | |$limit_rate|如果nginx服务器使用limit_rate配置了显示网络速率,则会显示,如果没有设置, 则显示0| 14 | |$remote_addr|客户端的公网ip| 15 | |$remote_port|客户端的port| 16 | |$remote_user|如果nginx有配置认证,该变量代表客户端认证的用户名| 17 | |$request_body_file|做反向代理时发给后端服务器的本地资源的名称| 18 | |$request_method|请求资源的方式,GET/PUT/DELETE等| 19 | |$request_filename|当前请求的资源文件的路径名称,相当于是$document_root/$document_uri的组合| 20 | |$request_uri|请求的链接,包括$document_uri和$args| 21 | |$scheme|请求的协议,如ftp,http,https| 22 | |$server_protocol|客户端请求资源使用的协议的版本,如HTTP/1.0,HTTP/1.1,HTTP/2.0等| 23 | |$server_addr|服务器IP地址| 24 | |$server_name|服务器的主机名| 25 | |$server_port|服务器的端口号| 26 | |$uri|和$document_uri相同| 27 | |$http_referer|客户端请求时的referer,通俗讲就是该请求是通过哪个链接跳过来的,用curl -e可以指定| 28 | -------------------------------------------------------------------------------- /ssl/ca.md: -------------------------------------------------------------------------------- 1 | ##### 先来一个例子 2 | ``` 3 | A公司的小明被派到B公司办事情。B公司如何信任小明是A公司派来的呢? 4 | ``` 5 | ##### 普通介绍信 6 | ``` 7 | 为了让B公司信任小明,A公司特意给小明开了一封介绍信,在信件中详细说明了小明的特征以及小明过来的目的, 8 | 并且声明这个小明确实是A公司派来的,除此之外还要有一个A公司的公章。 9 | 这样B公司前台小姐姐拿到介绍信后,通过信件内容和A公司公章就能判断出小明确实是A公司派来的员工。 10 | 11 | 那万一A公司公章是假的呢?毕竟公章伪造太容易了,这样岂不是会存在问题。咱们就暂且认为公章这种东西很难伪造, 12 | 否则故事无法继续喽。 13 | ``` 14 | ##### 引入第三方中介公司 15 | ``` 16 | 好,回到刚才的话题。如果和B公司有业务往来的公司很多,每个公司的公章都不同,那B公司的前台小姐姐就要懂得分辨各种公章, 17 | 非常滴麻烦。所以,有某个中介公司C,发现了这个商机。C公司专门开设了一项“代理公章”的业务。 18 |    19 | 于是今后,A公司的业务员去B公司,需要带2个介绍信: 20 | 介绍信1(含有C公司的公章及A公司的公章。并且特地注明:C公司信任A公司。) 21 | 介绍信2(仅含有A公司的公章,然后写上:兹有xxx先生/女士前往贵公司办理业务,请给予接洽......。) 22 | 23 | 这样不是增加麻烦了吗?有啥好处呢? 24 | 主要的好处在于,对于接待公司的前台,就不需要记住各个公司的公章分别是啥样子的,她只要记住中介公司C的公章即可。 25 | 当她拿到两份介绍信之后,先对介绍信1的C公章验明正身,确认无误之后,再比对“介绍信1”和“介绍信2”的两个A公章是否一致。 26 | 如果是一样的,那就可以证明“介绍信2”是可以信任的了。 27 | ``` 28 | ##### 相关专业术语的解释 29 | ``` 30 | 下面就着上面的例子,把相关的名词,作一些解释。 31 | ``` 32 | ##### 什么是证书? 33 | ``` 34 | 证书,洋文也叫“digital certificate”或“public key certificate”。 35 | 它是用来证明某某东西确实是某某的东西,通俗地说,证书就好比例子里面的公章。通过公章, 36 | 可以证明该介绍信确实是对应的公司发出的。 37 | 理论上,人人都可以找个证书工具,自己做一个证书。那如何防止坏人自己制作证书出来骗人呢? 38 | ``` 39 | ##### 什么是CA? 40 | ``` 41 | CA 是“Certificate Authority”的缩写,也叫“证书授权中心”。它是负责管理和签发证书的第三方机构, 42 | 就好比例子里面的中介C公司。 43 | 一般来说,CA必须是所有行业和所有公众都信任的、认可的。因此它必须具有足够的权威性。 44 | 就好比A、B两公司都必须信任C公司,才会找C公司作为公章的中介。 45 | ``` 46 | ##### 什么是CA证书? 47 | ``` 48 | CA证书,顾名思义,就是CA颁发的证书。 49 | 50 | 前面已经说了,人人都可以找工具制作证书。但是你一个小破孩制作出来的证书是没啥用处的。 51 | 因为你不是权威的CA机关,你自己搞的证书不具有权威性。 52 | 这就好比上述的例子里,某个坏人自己刻了一个公章,盖到介绍信上。但是别人一看, 53 | 不是受信任的中介公司的公章,就不予理睬。 54 | ``` 55 | ##### 什么是证书之间的信任关系? 56 | ``` 57 | 在开篇的例子里谈到,引入中介后,业务员要同时带两个介绍信。第一个介绍信包含了两个公章,并注明,公章C信任公章A。 58 | 证书间的信任关系,就和这个类似。就是用一个证书来证明另一个证书是真实可信滴。 59 | ``` 60 | 61 | ##### 什么是证书信任链? 62 | ``` 63 | 实际上,证书之间的信任关系,是可以嵌套的。 64 | 比如,C信任A1,A1信任A2,A2信任A3......这个叫做证书的信任链。 65 | 只要你信任链上的头一个证书,那后续的证书,都是可以信任滴。 66 | ``` 67 | 68 | ##### 什么是根证书? 69 | ``` 70 | 根证书的洋文叫“root certificate”,为了说清楚根证书是咋回事,再来看个稍微复杂点的例子。 71 | 假设C证书信任A和B;然后A信任A1和A2;B信任B1和B2。则它们之间,构成如下的一个树形关系(一个倒立的树)。 72 | ``` 73 | ![img](http://ask.apelearn.com/uploads/nginx/ca_tree.png) 74 | ``` 75 | 处于最顶上的树根位置的那个证书,就是“根证书”。除了根证书,其它证书都要依靠上一级的证书,来证明自己。 76 | 那谁来证明“根证书”可靠呢? 77 | 实际上,根证书自己证明自己是可靠滴(或者换句话说,根证书是不需要被证明滴)。 78 | 聪明的同学此刻应该意识到了:根证书是整个证书体系安全的根本。 79 | 所以,如果某个证书体系中,根证书出了问题(不再可信了),那么所有被根证书所信任的其它证书,也就不再可信了。 80 | ``` 81 | 82 | ##### 证书有啥用? 83 | 84 | CA证书的作用有很多,只列出常用的几个。 85 | 86 | * 验证网站是否可信(针对HTTPS) 87 | ``` 88 | 通常,我们如果访问某些敏感的网页(比如用户登录的页面),其协议都会使用HTTPS而不是HTTP,因为HTTP协议是明文的, 89 | 一旦有坏人在偷窥你的网络通讯,他/她就可以看到网络通讯的内容(比如你的密码、银行帐号、等)。 90 | 而 HTTPS 是加密的协议,可以保证你的传输过程中,坏蛋无法偷窥。 91 | 但是,千万不要以为,HTTPS协议有了加密,就可高枕无忧了。 92 | 假设有一个坏人,搞了一个假的网银的站点,然后诱骗你上这个站点。 93 | 假设你又比较单纯,一不留神,就把你的帐号,口令都输入进去了。那这个坏蛋的阴谋就得逞了。 94 | 为了防止坏人这么干,HTTPS 协议除了有加密的机制,还有一套证书的机制。通过证书来确保,某个站点确实就是某个站点。 95 | 有了证书之后,当你的浏览器在访问某个HTTPS网站时,会验证该站点上的CA证书(类似于验证介绍信的公章)。 96 | 如果浏览器发现该证书没有问题(证书被某个根证书信任、证书上绑定的域名和该网站的域名一致、证书没有过期), 97 | 那么页面就直接打开,否则的话,浏览器会给出一个警告,告诉你该网站的证书存在某某问题,是否继续访问该站点。 98 | ``` 99 | * 验证文件是否可信 100 | 101 | 本文参考于 https://program-think.blogspot.com/2010/02/introduce-digital-certificate-and-ca.html 102 | -------------------------------------------------------------------------------- /ssl/ca_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/ssl/ca_tree.png -------------------------------------------------------------------------------- /ssl/key.md: -------------------------------------------------------------------------------- 1 | ##### 生成CA根证书 2 | ``` 3 | # mkdir /etc/pki/ca_test //创建CA更证书的目录 4 | 5 | # cd /etc/pki/ca_test 6 | 7 | # mkdir root server client newcerts //创建几个相关的目录 8 | 9 | # echo 01 > serial //定义序列号为01 10 | 11 | # echo 01 > crlnumber //定义crl号为01 12 | 13 | # touch index.txt //创建index.txt 14 | 15 | # cd .. 16 | 17 | # vi tls/openssl.cnf //改配置文件 18 | default_ca = CA_default 改为 default_ca = CA_test 19 | [ CA_default ] 改为 [ CA_test ] 20 | dir = /etc/pki/CA 改为 dir = /etc/pki/ca_test 21 | certificate = $dir/cacert.pem 改为 certificate = $dir/root/ca.crt 22 | private_key = $dir/private/cakey.pe 改为 private_key = $dir/root/ca.key 23 | 24 | # openssl genrsa -out /etc/pki/ca_test/root/ca.key //生成私钥 25 | 26 | # openssl req -new -key /etc/pki/ca_test/root/ca.key -out /etc/pki/ca_test/root/ca.csr 27 | //生成请求文件,会让我们填写一些指标,这里要注意:如果在这一步填写了相应的指标, 28 | 比如Country Name、State or Province Name、hostname。 29 | 30 | # openssl x509 -req -days 3650 -in /etc/pki/ca_test/root/ca.csr -signkey /etc/pki/ca_test/root/ca.key -out /etc/pki/ca_test/root/ca.crt 31 | //生成crt文件 32 | ``` 33 | 34 | ##### 生成server端证书 35 | ``` 36 | # cd /etc/pki/ca_test/server 37 | 38 | # openssl genrsa -out server.key //生成私钥文件 39 | 40 | # openssl req -new -key server.key -out server.csr//生成证书请求文件,填写信息需要和ca.csr中的Organization Name保持一致 41 | 42 | # openssl ca -in server.csr -cert /etc/pki/ca_test/root/ca.crt -keyfile /etc/pki/ca_test/root/ca.key -out server.crt -days 3650 43 | //用根证书签名server.csr,最后生成公钥文件server.crt,此步骤会有两个地方需要输入y 44 | Sign the certificate? [y/n]:y 45 | 1 out of 1 certificate requests certified, commit? [y/n]y 46 | 47 | ``` 48 | 49 | ##### 生成客户端证书 50 | ``` 51 | 如果做ssl的双向认证,还需要给客户端生成一个证书,步骤和上面的基本一致 52 | # cd /etc/pki/ca_test/client 53 | 54 | # openssl genrsa -out client.key //生成私钥文件 55 | 56 | # openssl req -new -key client.key -out client.csr //生成请求文件,填写信息需要和ca.csr中的Organization Name保持一致 57 | 58 | # openssl ca -in client.csr -cert /etc/pki/ca_test/root/ca.crt -keyfile /etc/pki/ca_test/root/ca.key -out client.crt -days 3650 59 | //签名client.csr, 生成client.crt,此步如果出现 60 | failed to update database 61 | TXT_DB error number 2 62 | 63 | 需执行: 64 | # sed -i 's/unique_subject = yes/unique_subject = no/' /etc/pki/ca_test/index.txt.attr 65 | 66 | 执行完,再次重复执行签名client.csr那个操作 67 | ``` -------------------------------------------------------------------------------- /ssl/nginx.md: -------------------------------------------------------------------------------- 1 | #### Nginx配置SSL 2 | ##### Nginx配置示例(单向) 3 | ``` 4 | cp /etc/pki/ca_test/server/server.* /usr/local/nginx/conf/ 5 | { 6 | listen 443 ssl; 7 | server_name www.aminglinux.com; 8 | index index.html index.php; 9 | root /data/wwwroot/aminglinux.com; 10 | ssl on; 11 | ssl_certificate server.crt; 12 | ssl_certificate_key server.key; 13 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 14 | ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!eNULL; 15 | ssl_prefer_server_ciphers on; 16 | ... 17 | } 18 | ``` 19 | ##### 配置说明 20 | ``` 21 | 1. 443端口为ssl监听端口。 22 | 2. ssl on表示打开ssl支持。 23 | 3. ssl_certificate指定crt文件所在路径,如果写相对路径,必须把该文件和nginx.conf文件放到一个目录下。 24 | 4. ssl_certificate_key指定key文件所在路径。 25 | 5. ssl_protocols指定SSL协议。 26 | 6. ssl_ciphers配置ssl加密算法,多个算法用:分隔,ALL表示全部算法,!表示不启用该算法,+表示将该算法排到最后面去。 27 | 7. ssl_prefer_server_ciphers 如果不指定默认为off,当为on时,在使用SSLv3和TLS协议时,服务器加密算法将优于客户端加密算法。 28 | ``` 29 | ##### Nginx配置双向认证 30 | ``` 31 | cp /etc/pki/ca_test/root/ca.crt /usr/local/nginx/conf/ 32 | 配置示例: 33 | { 34 | listen 443 ssl; 35 | server_name www.aminglinux.com; 36 | index index.html index.php; 37 | root /data/wwwroot/aminglinux.com; 38 | ssl on; 39 | ssl_certificate server.crt; 40 | ssl_certificate_key server.key; 41 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 42 | ssl_ciphers ALL:!DH:!EXPORT:!RC4:+HIGH:+MEDIUM:!eNULL; 43 | ssl_prefer_server_ciphers on; 44 | ssl_client_certificate ca.crt; //这里的ca.crt是根证书公钥文件 45 | ssl_verify_client on; 46 | ... 47 | } 48 | 49 | ``` 50 | 51 | ##### 客户端(浏览器)操作 52 | ``` 53 | 如果不进行以下操作,浏览器会出现400错误。400 Bad Request(No required SSL certificate was sent) 54 | 首先需要将client.key转换为pfx(p12)格式 55 | 56 | # cd /etc/pki/ca_test/client 57 | # openssl pkcs12 -export -inkey client.key -in client.crt -out client.pfx //这一步需要输入一个自定义密码,一会在windows上安装的时候要用到,需要记一下。 58 | 59 | 然后将client.pfx拷贝到windows下,双击即可安装。 60 | 61 | 也可以直接curl测试: 62 | curl -k --cert /etc/pki/ca_test/client/client.crt --key /etc/pki/ca_test/client/client.key https://www.aminglinux.com/index.html 63 | ``` -------------------------------------------------------------------------------- /ssl/ssl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/ssl/ssl.jpg -------------------------------------------------------------------------------- /ssl/ssl.md: -------------------------------------------------------------------------------- 1 | #### SSL原理 2 | ``` 3 | 要想弄明白SSL认证原理,首先要对CA有有所了解,它在SSL认证过程中有非常重要的作用。 4 | 说白了,CA就是一个组织,专门为网络服务器颁发证书的,国际知名的CA机构有VeriSign、Symantec,国内的有GlobalSign。 5 | 每一家CA都有自己的根证书,用来对它所签发过的服务器端证书进行验证。 6 | 7 | 如果服务器提供方想为自己的服务器申请证书,它就需要向CA机构提出申请。 8 | 服务器提供方向CA提供自己的身份信息,CA判明申请者的身份后,就为它分配一个公钥, 9 | 并且CA将该公钥和服务器身份绑定在一起,并为之签字,这就形成了一个服务器端证书。 10 | 11 | 如果一个用户想鉴别另一个证书的真伪,他就用CA的公钥对那个证书上的签字进行验证,一旦验证通过,该证书就被认为是有效的。 12 | 证书实际是由证书签证机关(CA)签发的对用户的公钥的认证。 13 | 14 | 证书的内容包括:电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等等。 15 | 目前,证书的格式和验证方法普遍遵循X.509国际标准。 16 | ``` 17 | ##### #申请证书过程 18 | ![image](http://ask.apelearn.com/uploads/nginx/ssl_ca.png) 19 | ``` 20 | 首先要有一个CA根证书,然后用CA根证书来签发用户证书。 21 | 用户进行证书申请: 22 | 1. 先生成一个私钥 23 | 2. 用私钥生成证书请求(证书请求里应含有公钥信息) 24 | 3. 利用证书服务器的CA根证书来签发证书 25 | 26 | 这样最终拿到一个由CA根证书签发的证书,其实证书里仅有公钥,而私钥是在用户手里的。 27 | ``` 28 | 29 | ##### SSL工作流程(单向) 30 | ![image](http://ask.apelearn.com/uploads/nginx/ssl_auth.jpg) 31 | ``` 32 | 1.客户端say hello 服务端 33 | 2.服务端将证书、公钥等发给客户端 34 | 3.客户端CA验证证书,成功继续、不成功弹出选择页面 35 | 4.客户端告知服务端所支持的加密算法 36 | 5.服务端选择最高级别加密算法明文通知客户端 37 | 6.客户端生成随机对称密钥key,使用服务端公钥加密发送给服务端 38 | 7.服务端使用私钥解密,获取对称密钥key 39 | 8.后续客户端与服务端使用该密钥key进行加密通信 40 | ``` 41 | 42 | ##### SSL工作流程(双向) 43 | 单向认证,仅仅是客户端需要检验服务端证书是否是正确的,而服务端不会检验客户端证书是否是正确的。 44 | 双向认证,指客户端验证服务器端证书,而服务器也需要通过CA的公钥证书来验证客户端证书。 45 | 46 | 双向验证的过程: 47 | ``` 48 | 1.客户端say hello 服务端 49 | 2.服务端将证书、公钥等发给客户端 50 | 3.客户端CA验证证书,成功继续、不成功弹出选择页面 51 | 4.客户端将自己的证书和公钥发送给服务端 52 | 5.服务端验证客户端证书,如不通过直接断开连接 53 | 6.客户端告知服务端所支持的加密算法 54 | 7.服务端选择最高级别加密算法使用客户端公钥加密后发送给客户端 55 | 8.客户端收到后使用私钥解密并生成随机对称密钥key,使用服务端公钥加密发送给服务端 56 | 9.服务端使用私钥解密,获取对称密钥key 57 | 10.后续客户端与服务端使用该密钥key进行加密通信 58 | ``` 59 | -------------------------------------------------------------------------------- /ssl/ssl_auth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/ssl/ssl_auth.jpg -------------------------------------------------------------------------------- /ssl/ssl_ca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aminglinux/nginx/59895bf4bb088db638f2eacf90e59191819e6c6e/ssl/ssl_ca.png --------------------------------------------------------------------------------