Debian 8 (Jessie)安装Nginx StartSSL证书

本文将告诉你如何在Debian Jessie上安装最新的稳定版本的nginx。 它还将部署来自StartSSL的免费SSL证书。 在本文中,我们配置nginx使用强大的服务器端密码套件,并禁用易受攻击的SSLv2和SSLv3协议。

源码编译Nginx

虽然在许多情况下从软件包存储库进行安装nginx已经够用,但此安装方法的HTTP/2不能使所有浏览器兼容。 Google Chrome现在只允许与应用层协议协商(ALPN)的HTTP/2连接,OpenSSL 1.0.2或更高版本中支持此协议。 此版本不包括在默认Debian软件包存储库中,因此您需要手动添加它,并针对较新的OpenSSL编译nginx以启用对HTTP/2的完全支持。
请注意,当使用此方法时,您将负责更新nginx以包括最新的更新。
1.将Debian Backports存储库添加到包管理器检查更新的文件列表中:

  1. echo "deb http://ftp.debian.org/debian jessie-backports main " >> /etc/apt/sources.list.d/backports.list

2.更新可用包的列表:

  1. apt-get update

3.从backports存储库安装最新版本的OpenSSL及其库:

  1. apt-get install -t jessie-backports openssl libssl-dev

4.安装nginx依赖关系:

  1. apt-get install libpcre3-dev build-essential

5.将最新的稳定版本的nginx下载到/opt目录:

  1. cd /opt
  2. wget http://nginx.org/download/nginx-1.11.2.tar.gz

6.解压缩文件,然后切换到新目录:

  1. tar -zxvf nginx-1.*.tar.gz
  2. cd /opt/nginx-1.*

7.配置编译选项。 提供下面的示例以供参考。 根据您的需要,您可能希望添加其他选项,:

  1. ./configure –prefix=/opt/nginx –conf-path=/etc/nginx/nginx.conf –user=nginx –group=nginx –with-debug –with-threads –with-http_ssl_module –with-ipv6 –with-http_v2_module

此步骤完成后,您将看到配置摘要的输出。 一定要记住给定的文件路径,因为你很快就需要它们。
8.使用您在步骤7中指定的选项编译和安装nginx:

  1. make
  2. make install

9.创建nginx系统用户

  1. sudo adduser –system –no-create-home –disabled-login –disabled-password –group nginx

10.创建一个systemd服务脚本来运行nginx:
/lib/systemd/system/nginx.service:

  1. [Unit]
  2. Description=A high performance web server and a reverse proxy server
  3. After=network.target
  4.  
  5. [Service]
  6. Type=forking
  7. PIDFile=/opt/nginx/logs/nginx.pid
  8. ExecStartPre=/opt/nginx/sbin/nginx -t -q -g ‘daemon on; master_process on;’
  9. ExecStart=/opt/nginx/sbin/nginx -g ‘daemon on; master_process on;’
  10. ExecReload=/opt/nginx/sbin/nginx -g ‘daemon on; master_process on;’ -s reload
  11. ExecStop=-/sbin/start-stop-daemon –quiet –stop –retry QUIT/5 –pidfile /opt/nginx/logs/nginx.pid
  12. TimeoutStopSec=5
  13. KillMode=mixed
  14.  
  15. [Install]
  16. WantedBy=multi-user.target

如果使用步骤7中的编译配置选项,则可以完全按照以上的脚本。 但是,如果指定了自己的文件路径,则可能需要调整PIDFile的值以匹配您的PID文件,并且以Exec开头的行中的路径匹配您的nginx二进制文件路径。 这些文件路径包含在步骤7的输出中。
11.为nginx.service加上执行权限

  1. chmod +x /lib/systemd/system/nginx.service

12.启动nginx

  1. systemctl start nginx

或者,您可以设置nginx在启动时自动启动:

  1. systemctl enable nginx

生成私钥和证书签名请求(CSR)

1.创建一个目录来存储您的证书和私钥。 在Debian系统上,用于存储证书和私钥的默认位置在/etc/ssl/中。 在该位置创建一个新的nginx目录,以存储您的证书和nginx的私钥:

  1. mkdir /etc/ssl/nginx

2.切换到新创建的目录:

  1. cd /etc/ssl/nginx

3.生成4096位私有RSA密钥。 大多数证书颁发机构目前要求客户至少使用2048位专用RSA密钥。

  1. openssl genrsa -out server.key 4096

4.生成证书签名请求(CSR)。 在此示例中,server.key是上面创建的RSA私钥文件,server.csr是我们的CSR文件的名称:

  1. openssl req -new -key server.key -out server.csr

部署StartSSL证书

把证书签名请求文件server.csr提交到StartSSL网站,生效后下载证书相关文件,提取出里面的crt文件,并保存到/etc/ssl/nginx/server.crt。

收集其他必需的证书文件

1.确保您仍然在nginx SSL文件所在的目录中:

  1. cd /etc/ssl/nginx

2.下载StartSSL CA证书:

  1. wget http://www.startssl.com/certs/ca.pem

3.将StartSSL中间CA证书附加到该文件,创建统一的CA证书文件:

  1. curl http://www.startssl.com/certs/sub.class1.server.ca.pem >> ca.pem

4.创建包含您的签名证书和Nginx的StartSSL CA证书的单个文件:

  1. cat server.crt ca.pem > nginx.crt

安装StartSSL证书

1.默认情况下,nginx配置为仅在TCP端口80上提供HTTP请求。要使用SSL,您需要配置nginx以在TCP端口443上提供HTTPS请求。打开nginx SSL服务器块示例配置文件并调整配置.
/etc/nginx/conf.d/example_ssl.conf:

  1. # HTTPS server
  2. #
  3. server {
  4.     listen       443 ssl;
  5.     server_name  example.com;
  6.  
  7.     ssl_certificate      /etc/ssl/nginx/nginx.crt;
  8.     ssl_certificate_key  /etc/ssl/nginx/server.key;
  9.  
  10.     ssl_session_cache shared:SSL:10m;
  11.     ssl_session_timeout  5m;
  12.  
  13.     ssl_ciphers  "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH !RC4";
  14.     ssl_prefer_server_ciphers   on;
  15.  
  16.     ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  17.  
  18.     location / {
  19.         root   /opt/nginx/html;
  20.         index  index.html index.htm;
  21.     }
  22. }

将server_name的值替换为您的域或子域名称。 请确保ssl_certificate和ssl_certificate_key的值与您创建的证书和私钥的文件路径相匹配。 行ssl_session_cache,ssl_ciphers和ssl_protocols应与上述配置匹配。
根据您安装nginx的方式,默认情况下可能不会创建此文件。 例如,如果从源编译nginx,则需要创建example_ssl.conf文件并将此配置复制到其中。 如果是这种情况,您还需要将以下行添加到主要nginx配置文件中的http块:

  1. include     /etc/nginx/conf.d/*.conf;

2.重启nginx

  1. systemctl restart nginx

Debian 6 (Squeeze)安装Nginx uWSGI

uWSGI服务器提供了一个非FastCGI方法用于使用nginx Web服务器部署Python应用程序。 与nginx结合,uWSGI提供极大的稳定性,灵活性和高性能。 但是,要部署具有uWSGI和nginx的应用程序,必须手动编译包含uwsgi模块的nginx。

安装uWSGI

首先执行以下命令来更新系统并安装uWSGI的依赖关系:

  1. apt-get update
  2. apt-get upgrade
  3. apt-get install build-essential psmisc python-dev libxml2 libxml2-dev python-setuptools

依顺序执行以下命令以下载和编译uWSGI:

  1. cd /opt/
  2. wget http://projects.unbit.it/downloads/uwsgi-0.9.6.5.tar.gz
  3. tar -zxvf uwsgi-0.9.6.5.tar.gz
  4. mv uwsgi-0.9.6.5/ uwsgi/
  5. cd uwsgi/
  6. python setup.py install

执行以下命令以创建系统用户来运行uwsgi进程:

  1. adduser –system –no-create-home –disabled-login –disabled-password –group uwsgi

执行以下命令以设置所需的文件权限:

  1. chown -R uwsgi:uwsgi /opt/uwsgi
  2. touch /var/log/uwsgi.log
  3. chown uwsgi /var/log/uwsgi.log

编译nginx及uWSGI模块

执行以下命令来下载和编译nginx及uwsgi模块。 如果您以前从Debian软件包安装了nginx,请在此时删除它们。

  1. apt-get install libpcre3-dev libssl-dev
  2. cd /opt/
  3. wget http://nginx.org/download/nginx-1.0.0.tar.gz
  4. tar -zxvf nginx-1.0.0.tar.gz
  5. cd /opt/nginx-1.0.0/
  6. ./configure –prefix=/opt/nginx –user=nginx –group=nginx –with-http_ssl_module
  7. make
  8. make install
  9. adduser –system –no-create-home –disabled-login –disabled-password –group nginx
  10. wget -O init-deb.sh http://www.linode.com/docs/assets/682-init-deb.sh
  11. mv init-deb.sh /etc/init.d/nginx
  12. chmod +x /etc/init.d/nginx
  13. /usr/sbin/update-rc.d -f nginx defaults
  14. /etc/init.d/nginx start

配置uWSGI

执行以下命令以下载init脚本来管理uWSGI进程,位于/etc/init.d/uwsgi:

  1. cd /opt/
  2. wget -O init-deb.sh http://www.linode.com/docs/assets/683-uwsgi-init-deb.sh
  3. mv /opt/init-deb.sh /etc/init.d/uwsgi
  4. chmod +x /etc/init.d/uwsgi

创建/etc/default/uwsgi文件用来存放Python应用程序的特定设置。 MODULE指定包含wsgi规范的Python模块的名称。 考虑下面的例子:
/etc/default/uwsgi:

  1. PYTHONPATH=/srv/www/example.com/application
  2. MODULE=wsgi_configuration_module

如果要部署“Hello World”应用程序,请将以下代码插入到/srv/www/example.com/application/wsgi配置module.py文件中:
/srv/www/example.com/application/wsgi_configuration_module.py:

  1. import os
  2. import sys
  3.  
  4. sys.path.append(‘/srv/www/example.com/application’)
  5.  
  6. os.environ[‘PYTHON_EGG_CACHE’] = ‘/srv/www/example.com/.python-egg’
  7.  
  8. def application(environ, start_response):
  9.     status = ‘200 OK’
  10.     output = ‘Hello World!’
  11.  
  12.     response_headers = [(‘Content-type’, ‘text/plain’),
  13.                         (‘Content-Length’, str(len(output)))]
  14.     start_response(status, response_headers)
  15.  
  16.     return [output]

执行以下命令使此初始化脚本可执行,确保WSGI在下一个重新启动后重新启动,并启动服务:

  1. /usr/sbin/update-rc.d -f uwsgi defaults
  2. /etc/init.d/uwsgi start

配置nginx

为uWSGI应用程序的站点创建类似于以下内容的nginx服务器配置:

  1. server {
  2.     listen   80;
  3.     server_name www.example.com example.com;
  4.     access_log /srv/www/example.com/logs/access.log;
  5.     error_log /srv/www/example.com/logs/error.log;
  6.  
  7.     location / {
  8.         include        uwsgi_params;
  9.         uwsgi_pass     127.0.0.1:9001;
  10.     }
  11.  
  12.     location /static {
  13.         root   /srv/www/example.com/public_html/static/;
  14.         index  index.html index.htm;
  15.     }
  16. }

所有以/static结尾的网址请求都会直接从/srv/www/example.com/public_html/static目录提供。 通过执行以下命令重新启动Web服务器:

  1. /etc/init.d/nginx restart

Ubuntu 14.04安装nginx PageSpeed

本文说明如何安装nginx(发音engine-x)与ngx_pagespeed模块。 PageSpeed可帮助您缩小CSS,JavaScript和图片,从HTML中删除空白,并执行许多其他任务。

安装所需的包

Pagespeed需要一些额外的软件包,您应该安装它们才能正常运行。 通过在终端中执行以下命令:

  1. sudo apt-get install build-essential zlib1g-dev libpcre3 libpcre3-dev unzip

下载ngx_pagespeed模块

安装必要的软件包后,必须下载模块。 在本文中,最新的ngx_pagespeed版本1.9.32.6。
1.确保您在主目录中:

  1. cd

2.定义将要安装的版本号:

  1. NPS_VERSION=1.9.32.6

3.现在,您需要下载模块的源代码:

  1. wget https://github.com/pagespeed/ngx_pagespeed/archive/release-${NPS_VERSION}-beta.zip

4.使用gunzip命令提取文件:

  1. unzip release-${NPS_VERSION}-beta.zip

5.移动到modules目录:

  1. cd ngx_pagespeed-release-${NPS_VERSION}-beta/

6.下载一些其他文件:

  1. wget https://dl.google.com/dl/page-speed/psol/${NPS_VERSION}.tar.gz

7.使用tar命令提取文件:

  1. tar -xzvf ${NPS_VERSION}.tar.gz

下载并编译Nginx

现在我们已经下载了ngx_pagespeed,我们需要使用ngx_pagespeed模块编译Nginx。 在终端中执行如下命令。
1.您现在需要回到您的主目录:

  1. cd

2.在此命令中,您将定义将使用的Nginx的版本,以便您不必一次又一次地输入它。 在写这篇文章的时候,当前,稳定版本的Nginx是1.8.0:

  1. NGINX_VERSION=1.8.0

3.从其官方网站使用wget下载Nginx源码:

  1. wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz

4.解压nginx压缩包

  1. tar -xvzf nginx-${NGINX_VERSION}.tar.gz

5.解压源码后,进入nginx目录

  1. cd nginx-${NGINX_VERSION}/

6.接下来,使用PageSpeed模块编译Nginx:

  1. ./configure –add-module=$HOME/ngx_pagespeed-release-${NPS_VERSION}-beta

7.准备编译

  1. make

8.执行以下命令,安装Nginx与Pagespeed模块:

  1. sudo make install

配置Nginx ngx_pagespeed

1.Pagespeed需要一个新目录,以便存储压缩的CSS和javascript的缓存:

  1. sudo mkdir /var/ngx_pagespeed_cache

2.您需要更改文件夹的所有权,以便Web服务器可以写入此目录:

  1. sudo chown www-data:www-data /var/ngx_pagespeed_cache

3.你需要添加一些新的代码在Nginx配置文件以激活该模块:

  1. sudo nano /usr/local/nginx/conf/nginx.conf

4.然后,您需要将以下代码添加到要启用PageSpeed模块的server块:
/usr/local/nginx/conf/nginx.conf:

  1. pagespeed on;
  2. pagespeed FileCachePath /var/ngx_pagespeed_cache;
  3. location ~ ".pagespeed.([a-z].)?[a-z]{2}.[^.]{10}.[^.]+" {
  4.  add_header "" "";
  5. }
  6. location ~ "^/pagespeed_static/" { }
  7. location ~ "^/ngx_pagespeed_beacon$" { }

还要确保Nginx作为www-data运行。 在conf文件的顶部,取消user注释并用www-data替换nobody。

启动Nginx

1.已完成配置,启动web服务器

  1. sudo /usr/local/nginx/sbin/nginx

2.停止web服务器

  1. sudo /usr/local/nginx/sbin/nginx -s stop

检查模块是否工作

您已编译并配置模块。 您可能需要在部署应用程序之前检查模块是否正常工作。 在本地计算机(即您的计算机)的终端上执行以下命令:

  1. curl -I website_url_or_IP_adress

你会在响应中看到类似X-Page-Speed:1.9.32.6的东西。 这意味着您已经在您的服务器上成功安装了ngx_pagespeed。

Nginx服务器性能调优

Worker

相关worker设置比较简单,只需要设置正确的数量。

Worker Processes

如果您的站点流量不大,Nginx,数据库和Web应用程序都运行在同一台服务器上。则在/etc/nginx/nginx.conf中,设置worker_processes 1;
如果您的站点流量比较大或者服务器只运行了Nginx,请为每个CPU核心设置一个工作线程:worker_processes auto;
如果你想手动设置,你可以使用grep ^processor /proc/cpuinfo | wc -l来查找服务器的cpu线程数。

Worker Connections

worker_connections选项设置每个worker进程一次可以处理的最大连接数。 默认情况下,worker连接限制为512,但系统可以处理比这值更多的连接。
适当的值可以通过测试得出。 系统的核心限制也可以通过使用ulimit找到:

  1. ulimit -n

输出:

  1. 65536

您还可以设置使用epoll,一个可扩展的I/O事件通知机制来触发事件,确保充分利用I/O性能。
最后,您可以使用multi_accept使worker一次接受所有新连接。
设置如下:

  1. events {
  2.     worker_connections 66536;
  3.     use epoll;
  4.     multi_accept on;
  5. }

HTTP和TCP优化

Keep Alive

Keep alive能减少浏览器重新连接的次数。
keepalive_timeout和keepalive_requests控制保持活动设置。
sendfile优化Nginx提供文件系统的静态文件服务的性能,如logo。
tcp_nodelay允许Nginx使TCP发送多个缓冲区作为单独的数据包。
tcp_nopush通过激活TCP堆栈中的TCP_CORK选项来优化一次向下游发送的数据量。 TCP_CORK阻塞数据,直到分组到达MSS,这等于MTU减去IP报头的40或60字节。
/etc/nginx/nginx.conf

  1. keepalive_timeout 65;
  2. keepalive_requests 100000;
  3. sendfile on;
  4. tcp_nopush on;
  5. tcp_nodelay on;

Buffer Size

调整缓冲区大小可能是有利的。 如果缓冲区大小太低,那么Nginx将写入一个临时文件。 这将导致过多的磁盘I/O。
client_body_buffer_size处理客户端缓冲区大小。 大多数客户端缓冲区都来自POST方法表单提交。 128k通常是此设置的不错选择。
client_max_body_size设置最大body缓冲区大小。 如果请求中的大小超过配置的值,则会将413(请求实体过大)错误返回给客户端。 不过浏览器无法正确显示413错误。 将大小设置为0将禁用对客户机请求正文大小的检查。
client_header_buffer_size处理客户端头大小。 默认情况下,1k通常是一个合理的选择。
large_client_header_buffers设置客户端头的缓冲区的最大数量和大小。 4个报头与4k缓冲区应该足够了。
output_buffers设置用于从磁盘读取响应的缓冲区的数量和大小。 如果可能,客户端数据的传输将被推迟,直到Nginx至少具有要发送的数据的字节数的集合大小。 零值禁止推迟数据传输。
/etc/nginx/nginx.conf:

  1. client_body_buffer_size      128k;
  2. client_max_body_size         10m;
  3. client_header_buffer_size    1k;
  4. large_client_header_buffers  4 4k;
  5. output_buffers               1 32k;
  6. postpone_output              1460;

连接队列

可以更改/etc/sysctl.conf文件中的某些指令,以便为连接和buckets设置Linux队列的大小。 更新net.core.somaxconn和net.ipv4.tcp_max_tw_buckets会更改等待Nginx接受的连接的队列大小。 如果内核日志中有错误消息,请增加该值,直到错误消失。
/etc/sysctl.conf:

  1. net.core.somaxconn = 65536
  2. net.ipv4.tcp_max_tw_buckets = 1440000

可以通过使用net.core.netdev_max_backlog标记设置最大积压量,将数据包缓存在网卡中,然后交给CPU。 有关更改此值的建议,请参阅网卡文档。

超时

超时设置还可以大幅提高性能。
client_body_timeout指令设置服务器等待客户端完成发送body的最大时间。
client_header_timeout指令设置服务器等待客户端完成发送header的最大时间。
sent_timeout指定对客户端的响应超时。 此超时不适用于整个传输,而是仅应用于两个后续的客户端读取操作之间。 因此,如果客户端没有读取任何数据这段时间,那么Nginx关闭连接。
/etc/nginx/nginx.conf:

  1. client_header_timeout  3m;
  2. client_body_timeout    3m;
  3. send_timeout           3m;

静态资源服务

如果您的网站提供静态资源(如CSS/JavaScript/images),Nginx可以缓存这些文件很短的时间。 在配置块中添加这个命令会告诉Nginx缓存1000个文件30秒,不包括在20秒内未被访问的任何文件,只有5倍或更多的文件。 如果你不经常部署,你可以安全地把这些数字调得更高。
/etc/nginx/nginx.conf:

  1. open_file_cache max=1000 inactive=20s;
  2. open_file_cache_valid 30s;
  3. open_file_cache_min_uses 5;
  4. open_file_cache_errors off;

您还可以缓存特定位置的资源。 缓存文件很长时间是有好处的,尤其是如果文件由版本控制系统管理。
/etc/nginx/nginx.conf

  1. location ~* .(woff|eot|ttf|svg|mp4|webm|jpg|jpeg|png|gif|ico|css|js)$ {
  2.     expires 365d;
  3. }

Gzip压缩内容

对于纯文本的内容,Nginx可以使用gzip压缩将这些资源返回给客户端。 现代的网络浏览器都支持gzip压缩的内容,这将减少网络传输的字节数。 下面的列表是可压缩内容类型的“安全”列表; 但是,您只需要启用您在Web应用程序中使用的内容类型。

/etc/nginx/nginx.conf:

  1. gzip on;
  2. gzip_min_length 1000;
  3. gzip_types: text/html application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;
  4. gzip_disable "MSIE [1-6].";

文件系统优化

临时端口

当Nginx充当代理时,到上游服务器的每个连接使用临时或短暂的端口。
ip_local_port_range定义端口范围值。 常见设置为

  1. net.ipv4.ip_local_port_range 1024 65000。

tcp_fin_timeout指定端口必须处于非活动状态才能重用于其他连接的时间。 默认值通常为60秒,但通常可以安全地减少到30或甚至15秒:

  1. net.ipv4.tcp_fin_timeout 15

最大Backlog Packets设置

net.ipv4.tcp_max_syn_backlog设置保留在Backlog中的最大数据包数量,超过后内核会丢弃。 正常值为net.ipv4.tcp_max_syn_backlog = 3240000。

文件描述符

文件描述符是用于处理诸如连接和打开文件等操作系统资源。 Nginx每个连接最多可以使用两个文件描述符。 例如,如果它是代理,通常有一个文件描述符用于客户端连接,另一个用于连接到代理服务器,不过如果使用HTTP keep alives,这个比率要低得多。 对于需要服务大量连接的系统,可能需要调整这些设置。
sys.fs.file max定义文件描述符的系统范围限制。 nofile定义用户文件描述符限制,在/etc/security/limits.conf文件中设置。
/etc/security/limits.conf:

  1. soft nofile 4096
  2. hard nofile 4096

示例文件

/etc/sysctl.conf:

  1. net.core.somaxconn = 65536
  2. net.ipv4.tcp_max_tw_buckets = 1440000
  3. net.ipv4.ip_local_port_range = 1024 65000
  4. net.ipv4.tcp_fin_timeout = 15
  5. net.ipv4.tcp_window_scaling = 1
  6. net.ipv4.tcp_max_syn_backlog = 3240000

/etc/security/limits.conf:

  1. soft nofile 4096
  2. hard nofile 4096

nginx.conf:

  1. pid /var/run/nginx.pid;
  2. worker_processes  2;
  3.     
  4. events {
  5.     worker_connections   65536;
  6.     use epoll;
  7.     multi_accept on;
  8. }
  9.     
  10. http {
  11.     keepalive_timeout 65;
  12.     keepalive_requests 100000;
  13.     sendfile         on;
  14.     tcp_nopush       on;
  15.     tcp_nodelay      on;
  16.         
  17.     client_body_buffer_size    128k;
  18.     client_max_body_size       10m;
  19.     client_header_buffer_size    1k;
  20.     large_client_header_buffers  4 4k;
  21.     output_buffers   1 32k;
  22.     postpone_output  1460;
  23.         
  24.     client_header_timeout  3m;
  25.     client_body_timeout    3m;
  26.     send_timeout           3m;
  27.         
  28.     open_file_cache max=1000 inactive=20s;
  29.     open_file_cache_valid 30s;
  30.     open_file_cache_min_uses 5;
  31.     open_file_cache_errors off;
  32.         
  33.     gzip on;
  34.     gzip_min_length  1000;
  35.     gzip_buffers     4 4k;
  36.     gzip_types       text/html application/x-javascript text/css application/javascript text/javascript text/plain text/xml application/json application/vnd.ms-fontobject application/x-font-opentype application/x-font-truetype application/x-font-ttf application/xml font/eot font/opentype font/otf image/svg+xml image/vnd.microsoft.icon;
  37.     gzip_disable "MSIE [1-6].";
  38.  
  39.     # [ debug | info | notice | warn | error | crit | alert | emerg ]
  40.     error_log  /var/log/nginx.error_log  warn;
  41.         
  42.     log_format main      ‘$remote_addr – $remote_user [$time_local]  ‘
  43.       ‘"$request" $status $bytes_sent ‘
  44.       ‘"$http_referer" "$http_user_agent" ‘
  45.         ‘"$gzip_ratio"’;
  46.  
  47.     log_format download  ‘$remote_addr – $remote_user [$time_local]  ‘
  48.       ‘"$request" $status $bytes_sent ‘
  49.       ‘"$http_referer" "$http_user_agent" ‘
  50.         ‘"$http_range" "$sent_http_content_range"’;
  51.         
  52.     map $status $loggable {
  53.         ~^[23]  0;
  54.         default 1;
  55.     }
  56.         
  57.     server {
  58.         listen        127.0.0.1;
  59.         server_name   127.0.0.1;
  60.         root         /var/www/html;
  61.         access_log   /var/log/nginx.access_log  main;
  62.             
  63.         location / {
  64.             proxy_pass         http://127.0.0.1/;
  65.             proxy_redirect     off;
  66.             proxy_set_header   Host             $host;
  67.             proxy_set_header   X-Real-IP        $remote_addr;
  68.             proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
  69.             proxy_connect_timeout      90;
  70.             proxy_send_timeout         90;
  71.             proxy_read_timeout         90;
  72.             proxy_buffer_size          4k;
  73.             proxy_buffers              4 32k;
  74.             proxy_busy_buffers_size    64k;
  75.             proxy_temp_file_write_size 64k;
  76.             proxy_temp_path            /etc/nginx/proxy_temp;
  77.         }
  78.             
  79.         location ~* .(woff|eot|ttf|svg|mp4|webm|jpg|jpeg|png|gif|ico|css|js)$ {
  80.             expires 365d;
  81.         }
  82.     }
  83. }

Ubuntu 12.04 (Precise Pangolin)安装Nginx PHP FastCGI

nginx web服务器是一个快速,轻量级的服务器,旨在有效地处理低流量和高流量网站的需求。 虽然通常用于提供静态内容,但它也能够处理动态页面。 本文说明如何在Ubuntu 12.04 LTS(Precise Pangolin)Linux服务器上安装 Nginx PHP FastCGI。

安装所需软件包

执行以下命令更新系统并安装nginx Web服务器,PHP和编译器工具:

  1. apt-get update
  2. apt-get upgrade
  3. apt-get install nginx php5-cli php5-cgi spawn-fcgi psmisc

配置虚拟主机

创建目录

在本指南中,域“example.com”用作示例网站。 您应该在后续的配置步骤中替换您自己的域名。 首先,创建保存内容和日志文件的目录:

  1. mkdir -p /srv/www/www.example.com/public_html
  2. mkdir /srv/www/www.example.com/logs
  3. chown -R www-data:www-data /srv/www/www.example.com

UNIX套接字配置示例

接下来,您需要定义网站的虚拟主机文件。 此示例使用UNIX套接字连接到fcgiwrap。 请务必将“example.com”的所有实例更改为您的域名。
/etc/nginx/sites-available/www.example.com

  1. server {
  2.     server_name www.example.com example.com;
  3.     access_log /srv/www/www.example.com/logs/access.log;
  4.     error_log /srv/www/www.example.com/logs/error.log;
  5.     root /srv/www/www.example.com/public_html;
  6.  
  7.     location / {
  8.         index  index.html index.htm;
  9.     }
  10.  
  11.     location ~ .php$ {
  12.         include /etc/nginx/fastcgi_params;
  13.         fastcgi_pass unix:/var/run/php-fastcgi/php-fastcgi.socket;
  14.         fastcgi_index index.php;
  15.         fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
  16.     }
  17. }

创建一个名为/usr/bin/php-fastcgi的文件,包含以下内容:

/usr/bin/php-fastcgi

  1. #!/bin/bash
  2.  
  3. FASTCGI_USER=www-data
  4. FASTCGI_GROUP=www-data
  5. SOCKET=/var/run/php-fastcgi/php-fastcgi.socket
  6. PIDFILE=/var/run/php-fastcgi/php-fastcgi.pid
  7. CHILDREN=6
  8. PHP5=/usr/bin/php5-cgi
  9.  
  10. /usr/bin/spawn-fcgi -s $SOCKET -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

增加执行权限

  1. chmod +x /usr/bin/php-fastcgi

TCP套接字配置示例

或者,您可能希望使用TCP套接字。 如果是这样,请按如下示例修改nginx虚拟主机配置文件。 同样,请确保将“example.com”的所有实例替换为您的域名。
/etc/nginx/sites-available/www.example.com

  1. server {
  2.     server_name www.example.com example.com;
  3.     access_log /srv/www/www.example.com/logs/access.log;
  4.     error_log /srv/www/www.example.com/logs/error.log;
  5.     root /srv/www/www.example.com/public_html;
  6.  
  7.     location / {
  8.         index  index.html index.htm;
  9.     }
  10.  
  11.     location ~ .php$ {
  12.         include /etc/nginx/fastcgi_params;
  13.         fastcgi_pass 127.0.0.1:9000;
  14.         fastcgi_index index.php;
  15.         fastcgi_param SCRIPT_FILENAME /srv/www/www.example.com/public_html$fastcgi_script_name;
  16.     }
  17. }

创建一个名为/usr/bin/php-fastcgi的文件,包含以下内容:

  1. #!/bin/bash
  2.  
  3. FASTCGI_USER=www-data
  4. FASTCGI_GROUP=www-data
  5. ADDRESS=127.0.0.1
  6. PORT=9000
  7. PIDFILE=/var/run/php-fastcgi/php-fastcgi.pid
  8. CHILDREN=6
  9. PHP5=/usr/bin/php5-cgi
  10.  
  11. /usr/bin/spawn-fcgi -a $ADDRESS -p $PORT -P $PIDFILE -C $CHILDREN -u $FASTCGI_USER -g $FASTCGI_GROUP -f $PHP5

增加执行权限:

  1. chmod +x /usr/bin/php-fastcgi

激活启动服务

执行如下命令激活网站

  1. cd /etc/nginx/sites-enabled/
  2. ln -s /etc/nginx/sites-available/www.example.com

创建一个名为/etc/init.d/php-fastcgi的文件,包含以下内容:
/etc/init.d/php-fastcgi:

  1. #!/bin/bash
  2.  
  3. PHP_SCRIPT=/usr/bin/php-fastcgi
  4. FASTCGI_USER=www-data
  5. FASTCGI_GROUP=www-data
  6. PID_DIR=/var/run/php-fastcgi
  7. PID_FILE=/var/run/php-fastcgi/php-fastcgi.pid
  8. RET_VAL=0
  9.  
  10. case "$1" in
  11.     start)
  12.       if [[ ! -d $PID_DIR ]]
  13.       then
  14.         mkdir $PID_DIR
  15.         chown $FASTCGI_USER:$FASTCGI_GROUP $PID_DIR
  16.         chmod 0770 $PID_DIR
  17.       fi
  18.       if [[ -r $PID_FILE ]]
  19.       then
  20.         echo "php-fastcgi already running with PID `cat $PID_FILE`"
  21.         RET_VAL=1
  22.       else
  23.         $PHP_SCRIPT
  24.         RET_VAL=$?
  25.       fi
  26.   ;;
  27.     stop)
  28.       if [[ -r $PID_FILE ]]
  29.       then
  30.         kill `cat $PID_FILE`
  31.         rm $PID_FILE
  32.         RET_VAL=$?
  33.       else
  34.         echo "Could not find PID file $PID_FILE"
  35.         RET_VAL=1
  36.       fi
  37.   ;;
  38.     restart)
  39.       if [[ -r $PID_FILE ]]
  40.       then
  41.         kill `cat $PID_FILE`
  42.         rm $PID_FILE
  43.         RET_VAL=$?
  44.       else
  45.         echo "Could not find PID file $PID_FILE"
  46.       fi
  47.       $PHP_SCRIPT
  48.       RET_VAL=$?
  49.   ;;
  50.     status)
  51.       if [[ -r $PID_FILE ]]
  52.       then
  53.         echo "php-fastcgi running with PID `cat $PID_FILE`"
  54.         RET_VAL=$?
  55.       else
  56.         echo "Could not find PID file $PID_FILE, php-fastcgi does not appear to be running"
  57.       fi
  58.   ;;
  59.     *)
  60.       echo "Usage: php-fastcgi {start|stop|restart|status}"
  61.       RET_VAL=1
  62.   ;;
  63. esac
  64. exit $RET_VAL

启动php-fastcgi和nginx:

  1. chmod +x /etc/init.d/php-fastcgi
  2. update-rc.d php-fastcgi defaults
  3. /etc/init.d/php-fastcgi start
  4. /etc/init.d/nginx start

Apache服务器性能调优

Apache配置对您的服务器的性能有重大影响。 提高服务器性能的最简单方法是关闭不需要的模块。 本指南涵盖Apache模块,关闭哪些模块以及其他Apache性能调整选项。

工具

有多种工具可以帮助确定是否需要更改资源设置,包括top命令和负载测试程序Siege。 使用以下命令查看使用统计信息

  1. echo [PID]  [MEM]  [PATH] &&  ps aux | awk ‘{print $2, $4, $11}’ | sort -k2rn | head -n 20
  2. ps -eo pcpu,pid,user,args | sort -k 1 -r | head -20

更详细用于帮助了解Apache资源使用情况的工具包括Apache mod_status和Apache2Buddy。

Apache mod_status

Apache mod_status通过生成详细的状态页面来显示与入站服务器连接相关的信息。示例如下:
1.打开您的网站的配置文件。 此文件位于Debian / Ubuntu系统上的/etc/apache2/sites-available/example.com.conf或CentOS / Fedora系统上的/etc/httpd/conf.d/vhost.conf。
2.将以下内容添加到块中:
/etc/apache2/sites-available/example.com.conf (Debian/Ubuntu)
/etc/httpd/conf.d/vhost.conf (CentOS/Fedora)

  1. <Location /server-status>
  2.   SetHandler server-status
  3.   Order Deny,Allow
  4.   Deny from all
  5.   Allow from localhost
  6. </Location>

3.Apache mod_status还提供了一个名为ExtendedStatus的选项,该选项提供有关向Apache发送的每个请求的额外信息。 要启用ExtendedStatus编辑您的Apache配置文件:
/etc/apache2/apache2.conf (Debian/Ubuntu)
/etc/httpd/confd/httpd.conf (CentOS/Fedora)

  1. ExtendedStatus On

4.重启Apache
Debian/Ubuntu:

  1. service apache2 restart

CentOS/Fedora:

  1. /bin/systemctl reload httpd.service

5.要查看生成的文件,请下载Lynx:
Debian/Ubuntu:

  1. apt-get install lynx

Fedora/CentOS:

  1. yum install lynx

6.查看状态页

  1. lynx http://localhost/server-status

Apache2Buddy

Apache2Buddy脚本与MySQLTuner类似,它检查您的Apache设置,并根据您的Apache进程内存和总体RAM提出建议。 虽然它是一个相当基本的程序,专注于MaxClients指令,不过Apache2Buddy相当有用,可以通过单个命令运行:

  1. curl -L http://apache2buddy.pl/ | perl

多处理模块

Apache提供两个多处理模块,三个(如果在Apache 2.4上),用于管理您的设置。
每个模块创建子进程,主要区别在于它们如何处理线程。

Prefork

prefork模块在启动时创建多个子进程,每个子进程只处理一个线程。 由于这些进程一次只处理一个线程,因此如果有太多的并发请求,请求速度就会受到影响。 如果发生这种情况,一些请求基本上必须等待处理。 要处理此问题,请增加生成的子进程数,但请注意,这会增加RAM使用量。 Prefork是最安全的模块,当使用不是线程安全的模块时使用。

Worker

Worker模块的子进程在每个进程中生成许多线程,每个线程都能处理请求。 这提升了服务器的并发能力,当然也能减少服务器内存使用量。 总的来说,工作模块提供了更高的性能,但是比prefork安全性更低,不能与不是线程安全的模块一起使用。

Event

Event模块仅在Apache 2.4上可用,并且基于Worker MPM。 和Worker一样,它为每个子进程创建多个线程,一个线程专用于KeepAlive连接,一旦请求发出,它就传递给子线程。 这对于多个并发连接很有用,特别是那些不是同时处于活动状态但却偶尔请求的连接。 在SSL连接的情况下,Event MPM的作用与Worker相同。

模块配置

一旦选择了MPM,您需要更改配置中的值。 这些设置位于Debian / Ubuntu上的/etc/apache2/apache2.conf文件和CentOS / Fedora上的/etc/httpd/conf/httpd.conf文件。 MPM配置如下:

  1. <IfModule mpm_prefork_module>
  2.     StartServers          4
  3.     MinSpareServers       20
  4.     MaxSpareServers      40
  5.     MaxClients           200
  6.     MaxRequestsPerChild  4500
  7. </IfModule>

对于其他MPM,分别将替换为或以使用Worker和Event。
重新配置Apache服务器的下一步是更改上述设置。 要做到这一点,你需要知道每个值的作用,以及如何更好地调节它。
同样,进行配置更改的最佳方法是进行增量更改,然后监视效果。

StartServers

StartServers值指示启动时创建的子进程数,并根据负载进行动态控制。 通常没有理由更改此数字,除非您的服务器频繁重新启动,并在重新启动时接收大量请求。

MinSpareServers

设置空闲子进程的最小数量。 如果进程数少于MinSpareServer数,则会在Apache 2.2或更低版本上以每秒一个的速率创建更多进程。 使用Apache 2.4,此速率呈指数增长,从1开始到每秒生成32个子进程。 这个值的作用是,当收到一个新请求时,它可以直接使用空闲线程而不需要新生成一个; 如果已经没有可用线程了,Apache会新生成一个子进程,不过这会消耗服务器资源以及延长请求处理时间。 注意,太多的空闲进程也会对服务器产生不利影响。

MaxSpareServers

设置空闲子进程的最大数量。 如果空闲进程超出这个值,多余的将会终止。 除非您的网站非常繁忙,否则此数字不应设置过高,因为即使空闲进程也会消耗资源。

MaxClients

可同时提供的最大请求数量,请求数超过限制时后来的请求将入队列。 如果这个设置太低,队列中的连接可能会超时; 但是,如果设置过高,则会导致内存不足出现swap。 如果此值增加超过256,则还必须增加ServerLimit值。
计算最佳值的一种方法是用服务器可用内存除以每个Apache进程使用的内存量,注意要为其他进程留出一些内存空间。 使用ApacheBuddy帮助确定这些值,或下面的命令。
要确定每个Apache进程使用的RAM,请在Debian或Ubuntu系统上将apache2替换为httpd:

  1. ps -ylC httpd –sort:rss

除以1024转为Mb
获取内存使用信息:

  1. free -m

Apache mod_alias设置路径别名

在许多情况下,Apache主机提供的所有资源都位于该主机的DocumentRoot中。 DocumentRoot是在配置块中指定的目录。 此目录用于表示用户在文件系统上通过HTTP访问的各种文件,目录和资源。 但是,管理员通常要对文件系统上不位于DocumentRoot中的资源提供HTTP访问。 虽然Apache在某些情况下将遵循符号链接,但这可能很难维护。 因此,Apache可以指定一个Alias以让请求中的路径使用另一个路径

创建Alias

通常,虚拟主机配置指定一个DocumentRoot,按照惯例会指定public_html/或public/命名的目录。 如果example.com虚拟主机的文档根目录是/srv/www/example.com/public_html/,则对http://www.example.com/index.htm的请求将返回位于/srv/www/example.com/public_html/index.htm。
如果管理员需要在code/资源请求访问/srv/git/public/下的文件,即可以在http://example.com/code/访问它,则需要设置别名。 如下示例:

  1. DocumentRoot /srv/www/example.com/public_html/
  2. Alias /code /srv/git/public
  3. <Directory /srv/git/public>
  4.     Order allow,deny
  5.     Allow from all
  6. </Directory>

如果没有Alias指令,对http://example.com/code/的请求将返回/srv/www/example.com/public_html/code/文件夹中的可用资源。 但是,别名将指示Apache提供来自/srv/git/public目录的内容。 配置块允许远程用户访问此目录。
使用Alias指令时需要考虑几个重要因素:
Directory配置块需要在Alias指令之后创建。 这使得可以允许访问和以其他方式配置那些目录。 在上面的示例中是/srv/git/public。
通常,在Alias指令中避免使用尾部斜杠。 如果请求http://example.com/code应用的是Alias /code/ /srv/git/public/指令,请求URL没有尾部斜杠,即没有匹配Alias,资源将从DocumentRoot提供。
Alias指令需要在根级服务器配置(例如httpd.conf)或配置块中创建。
除了Alias之外,Apache还提供了一个AliasMatch指令,它提供类似的功能。 AlaisMatch提供了将给定资源的一类请求别名到DocumentRoot之外的位置的额外功能。 让我们考虑另一个虚构的example.com虚拟主机配置:

  1. DocumentRoot /srv/www/example.com/public_html/
  2. AliasMatch /code/projects/(.+) /srv/git/projects/$1
  3. <DirectoryMatch "^/srv/git/projects/.+$">
  4.     Order allow,deny
  5.     Allow from all
  6. </Directory>

在此示例中,对http://example.com/code/projects/my_app和http://example.com/code/projects/my_app2等网址的请求将分别由/srv/git/projects/my_app和/srv/git/projects/my_app2提供资源。 然而,http://example.com/code/projects将从/srv/www/example.com/public_html/code/projects/而不是/srv/git/projects/提供,因为在别名中的/code/projects/(.+有尾部斜杠。
虽然Alias的用例有点少,但是该功能对于维护安全且易于维护的Web服务器非常有效。

Apache安装web应用防火墙mod_security

ModSecurity是Apache Web服务器的Web应用程序防火墙。 除了提供日志记录功能,ModSecurity可以实时监视HTTP流量,以便检测攻击。 ModSecurity还可作为Web入侵检测工具,允许您对Web系统中发生的可疑事件做出反应。

安装ModSecurity

Ubuntu / Debian

  1. sudo apt-get install libxml2 libxml2-dev libxml2-utils
  2. sudo apt-get install libaprutil1 libaprutil1-dev
  3. sudo apt-get install libapache-mod-security

CentOS / Fedora

1.通过逐个输入以下命令来安装GCC编译器和依赖关系:

  1. sudo yum install mod_security

2.通过输入以下命令重新启动Apache:

  1. sudo /etc/init.d/httpd restart

OWASP ModSecurity核心规则集

对于基本配置,我们将使用OWASP核心规则集。 安装说明在SpiderLabs GitHub项目中:
https://github.com/SpiderLabs/owasp-modsecurity-crs/blob/master/INSTALL

配置ModSecurity

你可能需要用到modsecurity_10_crs_config,我们从示例中复制一份

  1. cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf

有五个规则目录:
activated_rules
base_rules
experimental_rules
optional_rules
slr_rules
有两种方式配置ModSecurity:使用基本规则集,或使用符号链接。 以下章节说明如何使用这两种方法。

使用基本规则集

如果您准备使用基本规则集,而不想使用符号链接配置文件,请执行以下步骤:
1.修改httpd.conf文件,如下所示:
/etc/apache2/httpd.conf (Debian / Ubuntu):

  1. <IfModule security2_module>
  2. Include modsecurity-crs/.conf Include modsecurity-crs/base_rules/.conf
  3. </IfModule>

/etc/httpd/conf/httpd.conf (CentOS / Fedora)

  1. <IfModule security2_module>
  2. Include modsecurity-crs/.conf Include modsecurity-crs/base_rules/.conf
  3. </IfModule>

2.在modsecurity crs_20_protocol_violations.conf文件中,将REQBODY_ERROR变量重命名为REQBODY_PROCESSOR_ERROR。
3.重新启动Apache以使更新生效:
Debian / Ubuntu:

  1. /etc/init.d/apache2 restart

CentOS / Fedora:

  1. /etc/init.d/httpd restart

使用符号链接

如果您希望以符号方式将这些配置文件链接到activated_rules目录,请执行以下步骤:
1.编辑Apache配置文件,使IfModule看起来像这样:
/etc/apache2/httpd.conf (Debian / Ubuntu):

  1. <IfModule security2_module>
  2. Include modsecurity-crs/modsecurity_crs_10_config.conf Include modsecurity-crs/activated_rules/*.conf </IfModule>

/etc/httpd/conf/httpd.conf (CentOS / Fedora):

  1. <IfModule security2_module>
  2. Include modsecurity-crs/modsecurity_crs_10_config.conf Include modsecurity-crs/activated_rules/*.conf </IfModule>

2.在重新启动Apache之前创建符号链接。 下面列出几个示例。
要将所有base_rules复制到activated_rules: > > for f in ls base_rules/ ; do ln -s /usr/local/apache/conf/crs/base_rules/$f activated_rules/$f ; done >
要将评论垃圾邮件规则从可选规则目录复制到activated_rules目录:>> for f in ls optional_rules/ | grep comment_spam ; do sudo ln -s /usr/local/apache/conf/crs/optional_rules/$f activated_rules/$f ; done >
3.重新启动Apache以使更新生效:
Debian / Ubuntu:

  1. /etc/init.d/apache2 restart

CentOS / Fedora:

  1. /etc/init.d/httpd restart

在Apache服务器使用mod_rewrite模块重定向URL

在Web开发中,通常设置HTTP能在URL不映射文件系统中的文件时访问资源。 虽然可以在某种程度上使用重定向语句来解决这个问题,但是许多部署对于URL重写具有更复杂的需求。 Apache的mod_rewrite提供重写功能,以便用户使用简洁明了的URL进行交互,同时仍然能够为管理员提供他们认为合适的网站目录架构。

重写URL

在块或.htaccess文件中,使用以下行启用mod_rewrite:

  1. RewriteEngine on

您可以创建任意数量的重写规则。 这些规则提供了服务器比较入站请求的模式。 如果请求与重写模式匹配,则服务器按照规则所述修改请求,并处理该请求。 下面是一个重写规则的例子:

  1. RewriteRule ^post-id/([0-9]+)$ /posts/$1.html

让我们解析这条规则:首先,请注意,第一个字符串是匹配传入请求的模式。 第二个字符串指定要提供的实际文件。 Mod_rewrite模式使用正则表达式语法:^匹配字符串的开头,$匹配字符串的结尾,这意味着重写引擎不会重写与模式部分匹配的字符串。
上面的例子会重写指定以/post-id/开头的路径的所有URL,并包含一个或多个数字(例如[0-9]+),在/posts/目录中提供相应的.html文件。 模式中的括号术语指定了作为$1,$2,$3等传递给第二个字符串的变量。
您可以创建和应用多个重写规则,但这些规则是顺序匹配的。 表示RewriteRules的顺序可以影响匹配的规则。
或者,您可以插入RewriteBase指令来修改重写规则的行为。 让我们假设:
这些指令是为/srv/www/example.com/public_html/目录指定的。
某些用户以http://example.com/post-id/200形式发送请求,其中200可能是长于一位数的任何数字。
某些用户以http://example.com/page/title-of-page的形式发送请求,其中“title of page”可能代表任何字符串。
这些文件位于/srv/www/example.com/public_html/objects/上,匹配请求文件名称,扩展名为.html。

  1. RewriteEngine on
  2. RewriteBase /objects
  3. RewriteRule ^post-id/([0-9]+)$ $1.html
  4. RewriteRule ^page/([^/]+)$ $1.html

上面的重写规则集作用如下:
http://example.com/post-id/200/,提供位于/srv/www/example.com/public_html/objects/200.html的文件
http://example.com/page/free-the-toast/,提供位于/srv/example.com/public_html/objects/free-the-toast.html的文件

在特定条件下重写URL

使用RewriteCond参数,您可以限制使用RewriteRule的条件。 让我们从WordPress应用程序的默认重写规则中获取以下示例:

  1. RewriteEngine On
  2. RewriteBase /
  3. RewriteCond %{REQUEST_FILENAME} !-f
  4. RewriteCond %{REQUEST_FILENAME} !-d
  5. RewriteRule . /index.php [L]

在此示例中,以上下文的顶层开始的所有请求都受重写规则的影响。 这由RewriteBase /指令指定。 上下文由在虚拟主机,目录块或.htaccess文件中指定伪指令的位置决定。
RewriteCond语句指示Apache仅当满足条件时才应用遵循的规则。 在上述示例中,匹配请求的文件名称在文件系统上不存在(例如,!-f),或者目录不存在(例如!-d)的请求。
简而言之,如果两者都为真,并且文件和目录都不存在,则Web服务器将请求附加到index.php。 也就是说,f用户请求http://example.com/?post=123或http://example.com/post/123,服务器将返回index.php?post=123或index.php/post/123。

mod_rewrite设置响应码

最后,有一些代码,你可以附加到一个RewriteRule,修改重写的行为。 在前面的例子RewriteRule ./index.php [L],我们看到代表“最后规则”的[L]选项。 这阻止Apache应用任何其他重写规则。 最常见的附加选项包括:
F告诉客户端该URL被禁止,用HTTP代码403响应。
N强制mod_rewrite重新开始重写过程,并允许多阶段重写。
R告诉客户端所请求的页面已经移动,具有用于临时重定向的HTTP代码302。 要表示该网页已永久移动,请指定“R=301”。
您可以在RewriteRule结尾处指定多个选项,用逗号分隔它们,如:[L,R=301]

Apache配置结构

Directory选项

块指的是文件系统中的目录,并指定Apache对于该目录的行为。 此目录块以角括号括起,并以单词“ Directory”开头,并指向文件系统中目录的路径。 目录块中设置的选项适用于指定的目录及其子目录。 以下是目录块的示例:

  1. <Directory /srv/www/example.com/public_html/images>
  2.     Order Allow,Deny
  3.     Allow from all
  4.     Deny 55.1
  5. </Directory>

关于块的附加注释:
目录块不能彼此嵌套。
目录块可以嵌套在块中。
目录块中包含的路径可以包含通配符。 星号(例如*)将匹配任何系列的字符,而问号(例如?)将匹配任何单个字符。 如果需要控制所有虚拟主机的DocumentRoot的选项,这可能很有用。 如下行:

  1. <Directory /srv/www/*/public_html>

File选项

如果需要进一步控制服务器上目录中的特定文件,可以使用指令。 这控制Web服务器关于单个文件的行为。 指令将应用于具有指定名称的任何文件。 例如,以下示例指令将匹配文件系统中名为roster.htm的任何文件:

  1. <Files roster.htm>
  2.      Order Allow,Deny
  3.      Deny from all
  4. </Files>

如果包含在块中,将应用于DocumentRoot中名为roster.htm的所有文件或位于该主机的DocumentRoot中的目录。 如果指令包含在块中,则指定的选项将应用于目录中名为roster.htm的所有文件,或指定的目录的子目录中。

Location选项

虽然和块控制Apache关于文件系统中位置的行为,但指令控制Apache关于客户端请求的特定路径的行为。 如果用户请求http://www.example.com/webmail/inbox/,网络服务器将在DocumentRoot下的webmail /inbox /目录中查找,例如/srv/www/example.com/public_html/webmail/inbox/。 此功能的一个常见用途可能是允许脚本处理对给定路径发出的请求。 例如,以下块将指定路径的所有请求都定向到一个mod_python脚本:

  1. <Location /webmail/inbox>
  2.     SetHandler python-program
  3.     PythonHandler modpython
  4.     PythonPath "[‘/srv/www/example.com/application/inbox’] + sys.path"
  5. </Location>

htaccess选项

除了上面讨论的配置方法,默认情况,Apache会从位于该目录中的文件读取目录的配置选项。 此文件通常称为.htaccess。 在您的httpd.conf和连接的文件中查找以下配置选项:

  1. AccessFileName .htaccess
  2.  
  3. <Files ~ "^.ht">
  4.     Order allow,deny
  5.     Deny from all
  6. </Files>

第一行告诉Apache在.htaccess文件中查找可公开访问的目录中的配置选项。 第二个指令指示Apache拒绝名称以.ht开头的文件的所有请求。 这将阻止访问者访问配置选项。
您可以更改AccessFileName以指定其他Apache可以查找这些配置选项的名称。 如果更改此选项,请务必更新指令以防止无意中的公开访问。 出于安全原因,不建议这样做。
块中的任何选项,都可以在.htaccess文件中配置。 .htaccess文件使得没有服务器权限的普通用户可以自己配置部署Apache选项。

“Match”指令和正则表达式

除了上述基本指令之外,Apache还允许服务器管理员在指定目录,文件和位置方面有一些额外的灵活性。 这些“Match”块和正则表达式定义的指令块允许管理员为一类目录,文件和位置定义一组配置选项。 这里是一个例子:

  1. <DirectoryMatch "^.+/images">
  2.     Order Allow,Deny
  3.     Allow from all
  4.     Deny 55.1
  5. </DirectoryMatch>

此配置块指定与正则表达式^+ images匹配的目录的多个选项。 换句话说,以多个字符开头并以图片结尾的任何路径都将与这些选项匹配,包括以下路径:/srv/www/example.com/public_html/images/,/srv/www/example.com/public_html/objects/images和/home/username/public/www/images。

  1. <Directory ~ "^.+/images">
  2.     Order Allow,Deny
  3.     Allow from all
  4.     Deny 55.1
  5. </Directory>

Apache提供类似的功能,可以在Location,Files使用正则表达式匹配一类目录或文件。 如下配置:

  1. <Files ~ "^..+">
  2.     Order allow,deny
  3.     Deny from all
  4. </Files>
  5.  
  6. <FilesMatch "^..+">
  7.     Order allow,deny
  8.     Deny from all
  9. </FilesMatch>
  10.  
  11. <Location ~ "inbox$">
  12.     Order Deny,Allow
  13.     Deny from all
  14.     Allow 192.168
  15. </Location>
  16.  
  17. <LocationMatch "inbox$">
  18.     Order Deny,Allow
  19.     Deny from all
  20.     Allow 192.168
  21. </LocationMatch>

注意,上述和指令是等效的,和指令也是同样的。