Nginx Installation、Configuration、Rreverse Proxy、Load Balancing Learning
目录
1. Nginx简介 2. Nginx安装部署 3. Nginx安全配置 4. Nginx反向代理实践 5. Nginx负载均衡实践
1. Nginx简介
0x1: Nginx的基本特性
Nginx("engine x")是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP代理服务器
Nginx可以在大多数Unix like OS上编译运行,并有Windows移植版。它的的源代码使用2-clause BSD-like license
Nginx是一个很强大的高性能Web和反向代理服务器,它具有很多非常优越的特性:
1. 在高连接并发的情况下,Nginx是Apache服务器不错的替代品 2. 能够支持高达50,000个并发连接数的响应 3. Nginx选择了epoll and kqueue作为IO开发模型 4. Nginx作为负载均衡服务器: 1) Nginx既可以在内部直接支持Rails和PHP程序对外进行服务 2) 也可以支持作为HTTP代理服务器对外进行服务 5. Nginx采用C进行编写,不论是系统资源开销还是CPU使用效率都比Perlbal要好很多 6. Nginx代码完全用C语言从头写成,已经移植到许多体系结构和操作系统,包括:Linux、FreeBSD、Solaris、Mac OS X、AIX以及Microsoft Windows 7. Nginx有自己的函数库,并且除了zlib、PCRE和OpenSSL之外,标准模块只使用系统C库函数。而且,如果不需要或者考虑到潜在的授权冲突,可以不使用这些第三方库。 8. Nginx是一个安装非常的简单,配置文件非常简洁(支持perl语法),Bugs非常少的服务器 9. Nginx启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级
0x2: 结构与扩展
1. 一个主进程和多个工作进程。工作进程是单线程的,且不需要特殊授权即可运行 2. 高效的IO模式支持 1) kqueue(FreeBSD 4.1+) 2) epoll(Linux 2.6+) 3) rt signals(Linux 2.2.19+) 4) /dev/poll(Solaris 7 11/99+) 5) select 6) poll 3. 10,000非活动的 HTTP keep-alive连接仅需要2.5M内存 4. 最小化的数据拷贝操作 5. 其他HTTP功能 6. 基于IP和名称的虚拟主机服务 7. Memcached的GET接口 8. 支持keep-alive和管道连接 9. 灵活简单的配置,重新配置和在线升级而无须中断客户的工作进程 10. 可定制的访问日志,日志写入缓存,以及快捷的日志回卷,4xx-5xx错误代码重定向 11. 基于PCRE的rewrite重写模块 12. 基于客户端IP地址和HTTP基本认证的访问控制 13. 支持PUT、DELETE、MKCOL方法 14. 支持FLV(Flash视频) 15. 带宽限制 16. 处理静态文件,索引文件以及自动索引 17. 反向代理加速(无缓存),简单的负载均衡和容错(FastCGI) 18. 模块化的结构。过滤器包括 1) gzipping 2) byte ranges 3) chunked responses 4) SSI-filter 在SSI过滤器中,到同一个proxy或者FastCGI的多个子请求并发处理 19. SSL和TLS SNI支持 20. IMAP/POP3代理服务功能: 1) 使用外部HTTP认证服务器重定向用户到IMAP/POP3后端 2) 使用外部HTTP认证服务器认证用户后连接重定向到内部的SMTP后端
Relevant Link:
http://baike.baidu.com/view/926025.htm?fr=aladdin
2. Nginx安装部署
0x1: 安装依赖环境
要安装Nginx,至少需要先安装pcre, zlib、ssl
1. PCRE(Perl Compatible Regular Expressions) 这是一个Perl库,用来实现重写rewrite的目的 //cmd yum -y install gcc gcc-c++ cd /usr/local/ wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.35.zip unzip pcre-8.35.zip cd pcre-8.35 ./configure make make install 2. zlib 这是一个gzip压缩库,是提供数据压缩用的函式库 //cmd cd /usr/local/ wget http://zlib.net/zlib-1.2.8.tar.gz tar -zxvf zlib-1.2.8.tar.gz cd zlib-1.2.8 ./configure make make install //或者直接用yum安装 yum -y install zlib* 3. ssl //cmd cd /usr/local/ wget http://www.openssl.org/source/openssl-1.0.1i.tar.gz tar -zxvf openssl-1.0.1i.tar.gz cd openssl-1.0.1i ./config make make install
0x2: Nginx安装
//cmd cd /usr/local/ wget http://nginx.org/download/nginx-1.7.4.zip unzip nginx-1.7.4.zip cd nginx-1.7.4 ./configure --prefix=/usr/local/nginx make make install //或者 [nginx] name=nginx repo baseurl=http://nginx.org/packages/rhel/6/i386/ gpgcheck=0 enabled=1 //这里baseurl根据系统和版本填写
Relevant Link:
http://nginx.org/en/linux_packages.html#stable http://nginx.org/en/download.html
0x3: 启动Nginx
确保系统的80端口没被其他程序占用 netstat -ntlp |grep 80 nginx
0x4: 重启Nginx
nginx –s reload
3. Nginx安全配置
vim /etc/nginx/nginx.conf
0x1: Nginx运行用户和组
user nginx; /* cat /etc/passwd | grep nginx nginx:x:496:492:nginx user:/var/cache/nginx:/sbin/nologin */
对于例如apache、nginx服务器这类程序所运行的用户,有一些可以普遍遵循的最佳的安全实践
1. 单独为每个服务器建立专用账户 例如nginx帐号 cat /etc/passwd | grep nginx nginx:x:496:492:nginx user:/var/cache/nginx:/sbin/nologin 这个nginx账户是一个nologin账户,关于"nologin"这个安全机制,我们简单了解一下 "nologin"这种配置仍然允许这个用户执行重要的日常任务,比如收发信件,FTP,访问网络共享目录和其他任务。它只是阻止用户登录服务器。如果服务器是一个主域控制器,用户主要在他们的工作站上使用Linux,那么采用这样的配
置是个好方法。这个方法也可以阻止因为用户设置了脆弱的密码而导致的非法登录服务器的事件发生 nologin的配置指令如下 1) 存在的用户,执行这个命令: usermod -s /sbin/nologin <username > 2) 对新用户,可以使用这个命令: useradd -s /sbin/nologin <new username> 3) 用-D选项把每个用户的登录shell设置成缺省的/sbin/nolgin(这个需要在环境变量中定义一下别名) useradd -D -s /sbin/nologin 这样,在使用useradd增加新用户的时候,就不需要用-s选项指定登录shell了,缺省的登录shell就是/sbin/nologin
0x2: 启动进程数(性能相关)
//通常设置成和cpu的数量相等 worker_processes 4;
0x3: 日志信息: 全局错误日志及PID文件
//保存nginx运行日志的地方 error_log /var/log/nginx/error.log warn; //保存"当前"nginx服务器的主进程的进行号 pid /var/run/nginx.pid;
0x4: IO模式
events { #epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,可以大大提高nginx的性能 use epoll; #单个后台worker process进程的最大并发链接数 worker_connections 10240; }
关于epoll、多路复用IO模式的相关知识,请参阅另一篇文章
http://www.cnblogs.com/LittleHann/p/3897910.html
0x5: 其他配置
http { include /etc/nginx/mime.types; default_type application/octet-stream; error_page 400 403 500 502 503 504 /50x.html; index index.html index.shtml autoindex off; fastcgi_intercept_errors on; sendfile on; # These are good default values. tcp_nopush on; tcp_nodelay off; keepalive_timeout 65; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; #gzip on; include /etc/nginx/conf.d/*.conf; }
Relevant Link:
http://www.cnblogs.com/zhuhongbao/archive/2013/06/04/3118061.html
4. Nginx反向代理实践
0x1: 反向代理简介
反向代理(Reverse Proxy)方式是指以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器(其原理非常类似用iptables实现的IP复用技术,通过处于网关处的iptables将内网的DMZ区域的服务器流量NAT出来,向外部提供服务)
使用反向代理是可以降低原始WEB服务器的负载。反向代理服务器承担了对原始WEB服务器的静态页面的请求,防止原始服务器过载。它位于本地WEB服务器和Internet之间,处理所有对WEB服务器的请求,阻止了WEB服务器和Internet的直接通信。如果互联网用户请求的页面在代理服务器上有缓冲的话,代理服务器直接将缓冲内容发送给用户。如果没有缓冲则先向WEB服务器发出请求,取回数据,本地缓存后再发送给用户。这种方式通过降低了向WEB服务器的请求数从而降低了WEB服务器的负载(反向代理可以作为提高性能的一种方案)
0x2: 反向代理和普通代理的区别
1. 普通的代理服务器 通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发送到Web服务器上的http请求发送到代理服务器中。 2. 反向代理服务器 2.1 从名字上就可以看出来,反向代理的连接方向和普通代理是相反的。当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。 2.2 在反向代理的场景下,代理服务器对外就表现为一个Web服务器,外部网络就可以简单把它当作一个标准的Web服务器而不需要特定的配置。不同之处在于,这个服务器没有保存任何网页的真实数据,所有的静态网页或者CGI程
序,都保存在内部的Web服务器上。因此2.3 对反向代理服务器的攻击并不会使得网页信息遭到破坏,这样就增强了Web服务器的安全性。 3.4 反向代理方式和包过滤方式或普通代理方式并无冲突,因此可以在防火墙设备中同时使用这两种方式 1) 反向代理 用于外部网络访问内部网络时使用 2) 正向代理 提供内部网络对外部网络的访问能力 3) 包过滤方式 在实际的网络架构中,可以结合这些方式提供最佳的安全访问方式
0x3: 配置安全反向代理的不同方式
Secure client to proxy
如果未经授权的用户很少或根本没有机会访问代理服务器与内容服务器之间交换的信息,则此方案很有效
Secure proxy to content server
如果客户机在防火墙外部而内容服务器在防火墙内部,则此方案很有效。在此方案中,代理服务器可以充当站点之间的安全通道
Secure client to proxy and secure proxy to content server
如果需要保护服务器、代理服务器和客户机三者间所交换信息的安全,则此方案很有效。在此方案中,代理服务器既可起到站点间安全通道的作用,又可增加客户机验证的安全性
Relevant Link:
http://baike.baidu.com/view/1165595.htm?fr=aladdin
0x4: Nginx配置反向代理
Nginx反向代理的指令不需要新增额外的模块,默认自带proxy_pass指令,只需要修改配置文件就可以实现反向代理
vim /etc/nginx/littlehann.conf //为反向代理单独创建一个配置文件 ## Basic reverse proxy server ## upstream apachephp { #the server which our reverse proxy will connect server 10.68.92.2:80; } ## Start www.nowamagic.net ## server { listen 8080; server_name www.nowamagic.net; root /var/www/html/; index index.html index.htm index.php; ## send request back to readl server ## location / { proxy_pass http://apachephp; #Proxy Settings proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } } //在nginx的配置文件的http{}段引入新增的配置文件 vim /etc/nginx/nginx.conf include /etc/nginx/littlehann.conf; //重启nginx nginx -s reload
实验环境网络拓朴图
Relevant Link:
http://liuyu.blog.51cto.com/183345/166381/ http://www.nowamagic.net/academy/detail/1226280 http://baike.baidu.com/view/926025.htm?fr=aladdin
5. Nginx负载均衡实践
0x1: 负载均衡简介
nginx不单可以作为强大的web服务器,也可以作为一个反向代理服务器
最重要的是nginx还具备实现负载均衡的效果
1. nginx还可以按照调度规则实现动态、静态页面的分离 2. 可以按照轮询、ip哈希、URL哈希、权重等多种方式对后端服务器做负载均衡 3. 同时还支持后端服务器的健康检查
Nginx负载均衡(upstream)目前支持5种方式的分配,这是一种负载均衡的策略
1. 轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除 2. WEIGHT(权重) 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况 3. IP_HASH 每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决"负载集群session同步"的问题(因为hash具有结果一致性) 4. Fair(第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先分配 5. URL_HASH(第三方)
0x2: Nginx实现负载均衡的配置
vim /etc/nginx/balance.conf //为负载均衡单独创建一个配置文件 ## Basic load balance server ## upstream littlehann.balance.com { #the server which our reverse proxy will connect ##weight默认为1.weight越大,负载的权重就越大 server 10.68.102.31:80 weight=2; server 192.168.207.134:80 weight=1; } ## Start littlehann.balance.com ## server { listen 8080; server_name littlehann.balance.com; root /var/www/html/; index index.html index.htm index.php; ## send request back to real server ## location / { proxy_pass http://littlehann.balance.com; #Proxy Settings proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; proxy_max_temp_file_size 0; proxy_connect_timeout 90; proxy_send_timeout 90; proxy_buffer_size 4k; proxy_buffers 4 32k; proxy_busy_buffers_size 64k; proxy_temp_file_write_size 64k; } } //在nginx的配置文件的http{}段引入新增的配置文件 vim /etc/nginx/nginx.conf include /etc/nginx/balance.conf; //重启nginx nginx -s reload
实验中的网络架构如下
Nginx成功实现了负载均衡
从配置信息中我们可以看出来,负载均衡本质上就是反向代理的扩展(反向代理的强化版),在大多数情况下,负载均衡服务器运行在集群的前端负责接收访问请求,然后根据预设的策略向后端的集群(多台服务器)分别发起反向连接
0x3: 负载均衡下SESSION共享同步问题
在负载均衡模式下,最关键的一个问题是怎么实现多台服务器之间session的共享(例如串号、webshell间断可用访问等都和负载均衡下的session共享机制有关)
1. 使用cookie替代session 能把session改成cookie,就能避开session的一些弊端,在从前看的一本J2EE的书上,也指明在集群系统中不能用session,否则惹出祸端来就不好办。如果系统不复杂,就优先考虑能否将session去掉。 但是使用cookie也就意味着将http状态信息的保存任务放到用户身上,一旦用户禁用了cookie,则会给应用系统的交互体验代理很大的影响 2. 应用服务器自行实现共享 可以用数据库或memcached来保存session,从而在应用系统本身建立了一个session集群,用这样的方式可以令 session保证稳定,即使某个节点有故障,session也不会丢失,适用于较为严格但请求量不高的场合。但是它的效率是
不会很高的,不适用于对效率 要求高的场合 (这种方式也给我们带来一个启示: 如果某种数据的同步共享存在难题,则可以在架构上将它"后移",通过更后端的一个统一的节点服务器来进行统一调度) 3. ip_hash nginx中的ip_hash技术能够将某个ip的请求定向到同一台后端,这样一来这个ip下的某个客户端和某个后端就能建立起稳固的session,原理简单解释如下: result = function hash(ip); 由于hash函数的单向陷门特性,但来源ip足够大的时候,所有的ip就会被"平均"地映射到另一个空间域中(也就是后端集群中) ip_hash是在upstream配置中定义的: upstream backend { server 127.0.0.1:8080 ; server 127.0.0.1:9090 ; ip_hash; } ip_hash是容易理解的,但是因为仅仅能用ip这个因子来分配后端,因此ip_hash是有缺陷的,不能在一些情况下使用: 1) nginx不是最前端的服务器 ip_hash要求nginx一定是最前端的服务器,否则nginx得不到正确源ip,就不能根据ip作hash。譬如使用的是squid为最前端,那么nginx取ip时只能得到squid的服务器ip地址,用这个地址来作分流是肯定错乱的 (即源ip不是真实的源ip空间域,可能只有几个前端负载均衡,那ip_hash的作用自然就体现不出来了) 2) nginx的后端还有其它方式的负载均衡 假如nginx后端又有其它负载均衡,将请求又通过另外的方式分流了,那么某个客户端的请求肯定不能定位到同一台session应用服务器上。这么算起来,nginx后端只能直接指向应用服务器,或者再搭一个squid,然后指向应用服
务器。最好的办法是用location作一次分流,将需要session的部分请求通过ip_hash分流,剩下的走其它后端去。 4. upstream_hash 为了解决ip_hash的一些问题,可以使用upstream_hash这个第三方模块,这个模块多数情况下是用作url_hash的,但是并不妨碍将它用来做session共享: 1) 假如前端是squid,他会将ip加入x_forwarded_for这个http_header里,用upstream_hash可以用这个头做因子,将请求定向到指定的后端: 2) 假如在php中配置的session为无cookie方式,配合nginx自己的一个userid_module模块就可以用nginx自发一个cookie,可参见 2.1) userid模块的英文文档: http://wiki.nginx.org/HttpUseridModule 2.2) upstream_jvm_route模块 http://code.google.com/p/nginx-upstream-jvm-route/
Relevant Link:
http://www.cnblogs.com/xiaogangqq123/archive/2011/03/04/1971002.html http://wujie2008.iteye.com/blog/1685366 http://zyan.cc/post/306/ http://blog.zyan.cc/nginx_php_v6/
Copyright (c) 2014 LittleHann All rights reserved