原文:http://blog.csdn.net/wzy_1988/article/details/8549290 需求简介 基于nginx搭建了一个https访问的虚拟主机,监听的域名是test.com,但是很多用户不清楚https和http的区别,会很容易敲成http://test.com,这时会报出404错误,所以我需要做基于test.com域名的http向https的强制跳转 我总结了三种方式,跟大家共享一下 nginx的rewrite方法 思路 这应该是大家最容易想到的方法,将所有的http请求通过rewrite重写到https上即可 配置 server { listen 192.168.1.111:80; server_name test.com; rewrite ^(.*)$ https://$host$1 permanent; } 搭建此虚拟主机完成后,就可以将http://test.com的请求全部重写到https://test.com上了 nginx的497状态码 error code 497 497 – normal request was sent to HTTPS 解释:当此虚拟站点只允许https访问时,当用http访问时nginx会报出497错误码 思路 利用error_page命令将497状态码的链接重定向到https://test.com这个域名上 配置 server { listen 192.168.1.11:443; #ssl端口 listen 192.168.1.11:80; #用户习惯用http访问,加上80,后面通过497状态码让它自动跳到443端口 server_name test.com; #为一个server{……}开启ssl支持 ssl on; #指定PEM格式的证书文件 ssl_certificate /etc/nginx/test.pem; #指定PEM格式的私钥文件 ssl_certificate_key /etc/nginx/test.key; #让http请求重定向到https请求 error_page 497 https://$host$uri?$args; } index.html刷新网页 思路 上述两种方法均会耗费服务器的资源,我们用curl访问baidu.com试一下,看百度的公司是如何实现baidu.com向www.baidu.com的跳转 可以看到百度很巧妙的利用meta的刷新作用,将baidu.com跳转到www.baidu.com.因此我们可以基于http://test.com的虚拟主机路径下也写一个index.html,内容就是http向https的跳转 index.html [html] view plaincopyprint? <html> <meta http-equiv="refresh" content="0;url=https://test.com/"> </html> nginx虚拟主机配置 server { listen 192.168.1.11:80; server_name test.com; location / { #index.html放在虚拟主机监听的根目录下 root /srv/www/http.test.com/; } #将404的页面重定向到https的首页 error_page 404 https://test.com/; } 后记 上述三种方法均可以实现基于nginx强制将http请求跳转到https请求,大家可以评价一下优劣或者根据实际需求进行选择。 from:http://www.cnblogs.com/yun007/p/3739182.html
View Details在前面《Nginx服务器开箱体验》 一文中我们从开箱到体验,感受了一下Nginx服务器的魅力。Nginx是轻量级的高性能Web服务器,提供了诸如HTTP代理和反向代理、负载均衡、缓存等一系列重要特性,因而在实践之中使用广泛,笔者也在学习和实践之中。
在本文中,我们继续延续前文,从前文给出的一份示例配置清单开始,详解一下Nginx服务器的各种配置指令的作用和用法。
在阅读本文前,大家要有一个概念,在实现正常的TCP/IP 双方通信情况下,是无法伪造来源 IP 的,也就是说,在 TCP/IP 协议中,可以伪造数据包来源 IP ,但这会让发送出去的数据包有去无回,无法实现正常的通信。这就像我们给对方写信时,如果写出错误的发信人地址,而收信人按信封上的发信人地址回信时,原发信人是无法收到回信的。 一些DDoS 攻击,如 SYN flood, 就是利用了 TCP/ip 的此缺陷而实现攻击的。《计算机网络》教材一书上,对这种行为定义为“发射出去就不管”。 因此,本文标题中的伪造来源IP 是带引号的。并非是所有 HTTP 应用程序中存在此漏洞。 那么在HTTP 中, " 伪造来源 IP", 又是如何造成的?如何防御之? 在理解这个原理之前,读者有必要对HTTP 协议有所了解。 HTTP 是一个应用层协议,基于请求 / 响应模型。客户端(往往是浏览器)请求与服务器端响应一一对应。 请求信息由请求头和请求正文构成(在GET 请求时,可视请求正文为空)。请求头类似我们写信时信封上的基本信息,对于描述本次请求的一些双方约定。而请求正文就类似于信件的正文。服务器的响应格式,也是类似的,由响应头信息和响应正文构成。 为了解这个原理,可使用Firefox Firebug, 或 IE 浏览器插件 HTTPwatch 来跟踪 HTTP 请求 / 响应数据。 本文中,以HTTPwatch 为例说明之。安装 httpwatch 并重启 IE 浏览器后, IE 的工具栏上出现其图标,点击并运行 Httpwatch, 就会在浏览器下方显示出 HTTPWatch 的主界面。 点击左下角红色的“Record ”按钮,并在地址栏输入 www.baidu.com, 等页面打开后,选中一个请求,并在下方的 tab 按钮中选择“ Stream ”,如图: 左边即是请求数据,右边即是服务器响应数据。左边的请求头均以回车换行结束,即“\r\n ” , 最后是一个空行(内容为 \r\n ) , 表示请求 header 结束。而请求 header 中除第一行外,其它行均由 header 名称, header 值组成,如 Accept-Encoding: gzip, deflate , header 名称与值之间有冒号相隔,之间的空格是可有可无的。 那么,在HTTP 应用程序中,如何取得指定的请求 header 信息呢?这里使用 PHP 语言为例说明。对所有客户端请求 header, PHP 程序中取得其值的方式如下: $_SERVER['HTTP_ HEADER_NAME '] HEADER_NAME应该以换成对应的 header 名称,此项的规律是:全大写,连接线变成下划线。比如要取得客户端的User-Agent 请求头,则使用 $_SERVER['HTTP_USER_AGENT'], 掌握这个规律,即可达到举一反三的效果。如要取得 COOKIE 信息,则使用 $_SERVER['HTTP_COOKIE'] 即可。也就是说, $_SERVER 数组中,以 HTTP 开头的项均属于客户端发出的信息。 回归到HTTP 应用程序层,来源 IP 的重要性不言而语,例如表单提交限制,频率等等均需要客户端 IP 信息。使用流行的 Discuz X2.5 的文件 source/class/discuz/discuz_application.php 中的代码片断: private function _get_client_ip() { $ip = $_SERVER['REMOTE_ADDR']; if (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; 如以下的JSP代码片段: public String getIpAddr(HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip; } 以上代码片段即是获取客户端IP ,这段程序会尝试检查 HTTP_CLIENT_IP, HTTP_X_FORWARDED_FOR, 根据之前的原理说明,以 HTTP_ 开头的 header, 均属于客户端发送的内容。那么,如果客户端伪造 Client-Ip, X-Forward-For ,不就可以欺骗此程序,达到“伪造 IP ”之目的? 那么如何伪造这项值?如果你会写程序,并了解HTTP 协议,直接伪造请求 header 即可。或者使用 Firefox 的Moify Headers 插件即可。 按图示顺序号输入或点击相应按钮。Start 按钮这里变为红色 Stop ,说明设置成功。 这时,如果我们使用Firefox 访问其它网站,网站服务器就针接收到我们伪造的 X-Forward-For, 值为 1.1.1.1 。 严格意义上讲,这并不是程序中的漏洞。Discuz 为了保持较好的环境兼容性 ( 包含有反向代理的 web 服务器环境,如 nginx 作为 php fastcgi 的前端代理 ) ,如此处理是可以理解的。那么如何处理,才能杜绝这个问题呢? 服务器重新配置X-Forward-For 为正确的值。 如对典型的nginx + php fastcgi 环境( nginx 与 php fastcgi 是否位于同一机器,并不妨碍此问题的产生) , nginx和 php fastcig 进程直接通信: 切记,$_SERVER['REMOTE_ADDR'] 是由 nginx 传递给 php 的参数,就代表了与当前 nginx 直接通信的客户端的 IP (是不能伪造的)。 再比如,存在中间层代理服务器的环境: 这种情况下,后端的HTTP 文件服务器上获取取的 REMOTE_ADDR 永远是前端的 squid/varnish cache 服务器的通信 IP 。 服务器集群之间的通信,是可以信任的。我们要做的就是在离用户最近的前端代理上,强制设定X-Forward-For 的值,后端所有机器不作任何设置,直接信任并使用前端机器传递过来的 X-Forward-For 值即可。 即在最前端的Nginx 上设置: location ~ ^/static { proxy_pass ….; proxy_set_header X-Forward-For $remote_addr ; […]
View DetailsOpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库、第三方模块以及大多数的依赖项。用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关。 OpenResty® 通过汇聚各种设计精良的 Nginx 模块(主要由 OpenResty 团队自主开发),从而将 Nginx 有效地变成一个强大的通用 Web 应用平台。这样,Web 开发人员和系统工程师可以使用 Lua 脚本语言调动 Nginx 支持的各种 C 以及 Lua 模块,快速构造出足以胜任 10K 乃至 1000K 以上单机并发连接的高性能 Web 应用系统。 OpenResty® 的目标是让你的Web服务直接跑在 Nginx 服务内部,充分利用 Nginx 的非阻塞 I/O 模型,不仅仅对 HTTP 客户端请求,甚至于对远程后端诸如 MySQL、PostgreSQL、Memcached 以及 Redis 等都进行一致的高性能响应。 from:http://openresty.org/cn/
View Details在nginx配置文件增加以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
location / { # 如果请求的文件已存在,直接返回 if (-f $request_filename) { break; } set $supercache_file ''; set $supercache_uri $request_uri; set $supercache 1; set $ihttp_host ''; if ($request_method = POST) { set $supercache 0; } # 仅在访问文章永久链接时使用静态文件,请求中带参数则不使用静态缓存 set $qs 0; if ($query_string) { set $qs 1; } # 不过从 twitter, facebook, feedburner 链接点过来的,总是带参数,这些访问仍然可以使用静态文件 if ($query_string ~* "^utm_source=([^&]+)&utm_medium([^&]+)&utm_campaign=([^&]+)(&utm_content=([^&]+))?$") { set $qs 0; set $supercache_uri $document_uri; } #deactivate on high load if ($qs = 1) { set $supercache 0; } # 针对已登录用户(发表过评论),可以不静态化。在访问量高峰时可注释掉 if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) { set $supercache 0; } # 支持移动设备,访问移动版本的网页缓存 if ($http_user_agent ~* '(iphone|ipod|aspen|incognito|webmate|android|dream|cupcake|froyo|blackberry9500|blackberry9520|blackberry9530|blackberry9550|blackberry 9800|webos|s8000|bada)') { set $ihttp_host '-mobile'; } # 指定静态缓存文件的路径 if ($supercache = 0) { set $supercache_uri ''; } if ($supercache_uri ~ ^(.+)$) { set $supercache_file /wp-content/cache/supercache/$http_host$1/index${ihttp_host}.html; } # 只有当缓存文件存在时,才进行 rewrite if (-f $document_root$supercache_file) { #rewrite ^(.*)$ $supercache_file break; rewrite ^ $supercache_file last; } # 所有其他请求,转给 wordpress 处理 if (!-e $request_filename) { rewrite . /index.php last; } |
针对已登录用户(发表过评论),可以不静态化。在访问量高峰时可注释掉
1 2 3 4 5 |
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) { set $supercache 0; } } |
from:http://blog.csdn.net/wangdada111/article/details/71189332
View Details为了在前端正确地显示字体,浏览器必须使用正确的http header来接受字体文件。如果服务器没有设置要求的头信息,那么有些浏览器就会在控制台报错或者直接不能显示。 可能你的服务器已经配置好了,你无须再动任何东西。如果没有配置好,那么你需要注意下面几点: 首先,修改mime-type headers; 其次设置CORS headers-仅当你从不同域下获取字体文件或者html页面的时候。(*注意:如果你没有设置CORS headers信息,你可以直接把字体文件(路径)嵌入到CSS样式中。如果你去fontello网站下载到本地的话fontello.css中就已经这样做好了) 下面介绍两大主流服务器的字体支持配置: Apache 设置正确的mime-type来支持字体文件,将下面的设置加入到服务器配置文件中:
1 2 3 4 |
AddType <span class="hljs-type">application</span>/font-sfnt otf ttf AddType <span class="hljs-type">application</span>/font-woff woff AddType <span class="hljs-type">application</span>/font-woff2 woff2 AddType <span class="hljs-type">application</span>/vnd.ms-fontobject eot |
如果你不能修改配置文件,那么就在你的项目下新建一个*.htaccess文件,添加下面的设置: 设置CORS headers 信息:
1 2 3 |
<span class="hljs-subst"><</span>FilesMatch <span class="hljs-string">".(eot|ttf|otf|woff|woff2)"</span><span class="hljs-subst">></span> <span class="hljs-keyword">Header</span> <span class="hljs-built_in">set</span> Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Allow</span><span class="hljs-attribute">-Origin</span> <span class="hljs-string">"*"</span> <span class="hljs-subst"><</span>/FilesMatch<span class="hljs-subst">></span> |
Nginx Nginx服务器默认是没有支持字体的mime-type设置的,并且对.eot文件的mime-type也是不正确的。在配置文件夹下找到mime-type设置的地方。通常,在mimes.types文件下。 搜索.eot,并在下它的设置下添加下面几行:
1 2 3 4 |
<span class="hljs-type">application</span>/font-sfnt otf ttf; <span class="hljs-type">application</span>/font-woff woff; <span class="hljs-type">application</span>/font-woff2 woff2; <span class="hljs-type">application</span>/vnd.ms-fontobject eot; |
对于CORS headers 信息设置,添加下面的几行到你的vhost配置中:
1 2 3 4 |
location ~<span class="hljs-subst">*</span> <span class="hljs-subst">\</span><span class="hljs-built_in">.</span>(eot<span class="hljs-subst">|</span>otf<span class="hljs-subst">|</span>ttf<span class="hljs-subst">|</span>woff<span class="hljs-subst">|</span>woff2)$ { add_header Access<span class="hljs-attribute">-Control</span><span class="hljs-attribute">-Allow</span><span class="hljs-attribute">-Origin</span> <span class="hljs-subst">*</span>; } |
from:http://blog.csdn.net/yypsober/article/details/52012577
View Details安装nginx yum install nginx 设置nginx开启起动 systemctl start nginx 测试 访问http://你的域名或IP/ 查看nginx安装位置 whereis nginx nginx: /usr/sbin/nginx /etc/nginx /usr/share/nginx /usr/share/man/man3/nginx.3pm.gz /usr/share/man/man8/nginx.8.gz 安装php yum install php php-mysql php-fpm 安装过程中经常会见到如下问题: 2:postfix-2.10.1-6.el7.x86_64 有缺少的需求 libmysqlclient.so.18()(64bit) 2:postfix-2.10.1-6.el7.x86_64 有缺少的需求 libmysqlclient.so.18(libmysqlclient_18)(64bit) 解决方法: 把php-mysql换成php-mysqlnd 即执行 yum install php php-mysqlnd php-fpm 配置php处理器 vim /etc/php.ini 查找cgi.fix_pathinfo 将 ;cgi.fix_pathinfo=1改为cgi.fix_pathinfo=0 配置www.conf vim /etc/php-fpm.d/www.conf 将 user = nobody group = nobody 改为 user = nginx group = nginx 前提是已经创建了nginx用户和nginx组。 起动php-fpm systemctl start php-fpm 设置php-fpm开机启动 systemctl enable php-fpm 配置nginx 打开/etc/nginx/conf.d/default.conf,如果不存在则创建 粘贴 server { listen 80; server_name server_domain_name_or_IP; note that these lines are originally from […]
View Details1:查看环境: 1 2 [root@10-4-14-168 html]# cat /etc/redhat-release CentOS release 6.5 (Final) 2:关掉防火墙 1 [root@10-4-14-168 html]# chkconfig iptables off 3:配置CentOS 6.0 第三方yum源(CentOS默认的标准源里没有nginx软件包) 1 #wget http://www.atomicorp.com/installers/atomic 1 #sh ./atomic 1 #yum check-update 4:安装开发包和库文件 1 2 3 4 #yum -y install ntp make openssl openssl-devel pcre pcre-devel libpng libpng-devel libjpeg-6b libjpeg-devel-6b freetype freetype-devel gd gd-devel zlib zlib-devel gcc gcc-c++ libXpm libXpm-devel ncurses ncurses-devel libmcrypt libmcrypt-devel libxml2 libxml2-devel imake autoconf automake screen sysstat compat-libstdc++-33 curl curl-devel 5:卸载已安装的apache、mysql、php 1 2 3 # yum remove httpd # yum remove mysql # yum remove php 6:安装nginx 1 […]
View Details有时候你想在一台服务器上为不同的域名运行不同的站点。比如www.siteA.com作为博客,www.siteB.com作为论坛。你可以把两个域名的IP都解析到你的服务器上,但是没法在Nginx的根目录里同时运行两个不同的网站。这时候,你就需要使用虚拟目录了。假设你把博客放在”/home/user/www/blog”下,论坛放在”/home/user/www/forum”下。下面我们就开始配置了: 在Nginx配置目录下,创建一个”vhost”目录。本例假设Nginx是默认安装,配置目录在”/etc/nginx” $ sudo mkdir /etc/nginx/vhost 创建siteA的配置文件 $ sudo vi /etc/nginx/vhost/vhost_siteA.conf 输入以下配置信息 server { listen 80; # 监听端口 server_name www.siteA.com siteA.com; # 站点域名 root /home/user/www/blog; # 站点根目录 index index.html index.htm index.php; # 默认导航页 location / { # WordPress固定链接URL重写 if (!-e $request_filename) { rewrite (.*) /index.php; } } # PHP配置 location ~ \.php$ { fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; include fastcgi_params; } } 同siteA一样创建siteB的配置文件,两者仅有的不同是”server_name”和”root”目录 $ sudo vi /etc/nginx/vhost/vhost_siteB.conf server { … server_name www.siteB.com siteB.com; # 站点域名 root /home/user/www/forum; # 站点根目录 … } 打开nginx.conf文件 sudo vi /etc/nginx/nginx.conf 将虚拟目录的配置文件加入到”http {}”部分的末尾 http { […]
View Details1. 全站ssl 全站做ssl是最常见的一个使用场景,默认端口443,而且一般是单向认证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
server { listen 443; server_name example.com; root /apps/www; index index.html index.htm; ssl on; ssl_certificate ../SSL/ittest.pem; ssl_certificate_key ../SSL/ittest.key; # ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; # ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; # ssl_prefer_server_ciphers on; } |
如果想把http的请求强制转到https的话:
1 2 3 4 5 6 7 8 |
server { listen 80; server_name example.me; rewrite ^ https://$server_name$request_uri? permanent; ### 使用return的效率会更高 # return 301 https://$server_name$request_uri; } |
ssl_certificate证书其实是个公钥,它会被发送到连接服务器的每个客户端,ssl_certificate_key私钥是用来解密的,所以它的权限要得到保护但nginx的主进程能够读取。当然私钥和证书可以放在一个证书文件中,这种方式也只有公钥证书才发送到client。 ssl_protocols指令用于启动特定的加密协议,nginx在1.1.13和1.0.12版本后默认是ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2,TLSv1.1与TLSv1.2要确保OpenSSL >= 1.0.1 ,SSLv3 现在还有很多地方在用但有不少被攻击的漏洞。 ssl_ciphers选择加密套件,不同的浏览器所支持的套件(和顺序)可能会不同。这里指定的是OpenSSL库能够识别的写法,你可以通过 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5’(后面是你所指定的套件加密算法) 来看所支持算法。 ssl_prefer_server_ciphers on设置协商加密算法时,优先使用我们服务端的加密套件,而不是客户端浏览器的加密套件。 https优化参数 ssl_session_cache shared:SSL:10m; : 设置ssl/tls会话缓存的类型和大小。如果设置了这个参数一般是shared,buildin可能会参数内存碎片,默认是none,和off差不多,停用缓存。如shared:SSL:10m表示我所有的nginx工作进程共享ssl会话缓存,官网介绍说1M可以存放约4000个sessions。 详细参考serverfault上的问答ssl_session_cache。 ssl_session_timeout : 客户端可以重用会话缓存中ssl参数的过期时间,内网系统默认5分钟太短了,可以设成30m即30分钟甚至4h。 设置较长的keepalive_timeout也可以减少请求ssl会话协商的开销,但同时得考虑线程的并发数了。 提示:在生成证书请求csr文件时,如果输入了密码,nginx每次启动时都会提示输入这个密码,可以使用私钥来生成解密后的key来代替,效果是一样的,达到免密码重启的效果: HTTPS服务器优化 SSL操作需要消耗CPU资源,所以在多处理器的系统,需要启动多个工作进程,而且数量需要不少于可用CPU的个数。最消耗CPU资源的SSL操作是SSL握手,有两种方法可以将每个客户端的握手操作数量降到最低:第一种是保持客户端长连接,在一个SSL连接发送多个请求,第二种是在并发的连接或者后续的连接中重用SSL会话参数,这样可以避免SSL握手的操作。会话缓存用于保存SSL会话,这些缓存在工作进程间共享,可以使用ssl_session_cache指令进行配置。1M缓存可以存放大约4000个会话。默认的缓存超时是5分钟,可以使用ssl_session_timeout加大它。下面是一个针对4核系统的配置优化的例子,使用10M的共享会话缓存:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
worker_processes 4; http { ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; server { listen 443; server_name www.example.com; keepalive_timeout 70; ssl on; ssl_certificate www.example.com.crt; ssl_certificate_key www.example.com.key; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers HIGH:!aNULL:!MD5; |
from:http://blog.csdn.net/mr_raptor/article/details/51854746
View Details