CentOS 7 中Nginx proxy 502的问题

环境 CentOS Linux release 7.0.1406 (Core)     Nginx    tomcat

使用nginx做前端,proxy后端tomcat 8080 端口,浏览器死活502 ,⊙︿⊙。

stackoverflow 上发现同样有人遇到此问题,

http://stackoverflow.com/questions/23948527/13-permission-denied-while-connecting-to-upstreamnginx

翻阅了Nginx的blog

http://nginx.com/blog/nginx-se-linux-changes-upgrading-rhel-6-6/

此问题在6.6以上就出现了,sudo cat /var/log/audit/audit.log | grep nginx | grep denied

查阅SELinux 日志,发现问题

type=AVC msg=audit(1420460715.553:594): avc:  denied  { name_connect } for  pid=3425 comm=”nginx” dest=8080 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:http_cache_port_t:s0 tclass=tcp_socket

 

执行命令(yum -y install policycoreutils-python)

sudo cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M mynginx
sudo semodule -i mynginx.pp

搞定,502请滚粗……

Nginx允许跨域设置

if ($request_method = 'OPTIONS') { 
        add_header Access-Control-Allow-Origin *; 
        add_header Access-Control-Allow-Credentials true; 
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; 
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type'; 
        return 200; 
    } 
     if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' *; 
        add_header 'Access-Control-Allow-Credentials' 'true'; 
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; 
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }

     if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' *; 
        add_header 'Access-Control-Allow-Credentials' 'true'; 
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; 
        add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
     }

worker_connections exceed open file resource limit: 1024

在Nginx优化的过程中,将 connections加大的时候Nginx发出警告

worker_connections exceed open file resource limit: 1024

此警告的问题是受限于Linux的最大文件数限制。

环境:centos5.8 64bit

ulimit -n

查看用户打开的最大文件数:1024

此处的1024是每个进程打开的最大文件数,对于系统的最大限制:

more /proc/sys/fs/file-max

355828

file-max是整机可以打开的fd数目,对确定的进程仍然是1024个。

那么我们来修改我们的限制。

修改/etc/security/limits.conf文件,在文件中添加如下行:
* soft noproc 65535
* hard noproc 65535
* soft nofile 65535
* hard nofile 65535
就是限制了任意用户的最大线程数和文件数为65535。

其中*为所有用户的打开文件数限制,可用’*’号表示修改所有用户的限制;soft或hard指定要修改软限制还是硬限制;10240则指定了想要修改的新的限制值,即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。

修改/etc/pam.d/login文件,在文件中添加如下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登录后,应该调用pam_limits.so模块来设置系统对该用户可使用的各种资源数量的最大限制(包括用户可打开的最大文件数限制),而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。修改完后保存此文件。

修改/etc/rc.local脚本,在脚本中添加如下行:
echo “65535″> /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为65535。修改完后保存此文件。

如果比较懒的话可以在 rc.local 里面 明确命令 ulimit -n xxxxx

除了在系统中进行设定 nofile(fs.file-max) 值外,可以在 nginx.conf 中指定worker_process可以使用的nofile值,如:

nginx

 

Nginx前端apache后端获取真实IP

我一直都是使用Nginx做前端,Tomcat做后端,这样的话我在程序里面从请求头里面可以提取出来真实的IP地址,但是PHP这东西毕竟咱不会,只是按照网上人家说的跟着瞎配,人家说Nginx做前端好,咱们就跟着弄呗,但是这样一来WP这个货只能获取Nginx的代理过来的IP地址,真郁闷,放眼望去全部是都是清一色:(
这里咱也找了一些教程,但是毕竟人家都是手工编译的环境,咱们小白只会用yum来安装,所以折腾了一下,也弄出来了,嘿嘿,分享一下
首先Nginx里面需要配置一下

proxy_pass http://IP:端口;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

这里的IP是你的Nginx反带后端的地址,根据自己的需要填写IP和端口吧!
下面就是把真实的IP地址封装到请求头里面带过去,然后Apache这家伙居然傻不拉几的自己不会辨别-。-
这就需要安装一个模块”rpaf”
rpaf的最新版本在这http://stderr.net/apache/rpaf/ 大家可以自己去下载!

1
2
3
4
wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz
tar zxf mod_rpaf-0.6.tar.gz
cd mod_rpaf-0.6
apxs -i -c -n mod_rpaf-2.0.so mod_rpaf-2.0.c

安装完毕之后会出现

注意里面的路径,千万不要弄错了!

然后就在你的apache 里面配置一下即可

1
2
3
4
5
LoadModule rpaf_module /usr/lib/httpd/mod_rpaf-2.0.so   (注意红框里面的路径要一样)
RPAFenable On
RPAFsethostname On
RPAFproxy_ips IP地址  (nginx前端地址)
RPAFheader X-Forwarded-For

路径不要错啦,还有就是ip要和nginx的ip填写的一样,就是和proxy_pass http://IP:端口;这里的IP要一样。

剩下的就是重启一下服务了。搞定!

Nginx启动了,但是无法访问

这几天在调试服务器,各种问题都展现出来了,十分的郁闷,或许就是这样,搞服务器的比搞程序的要值钱吧:)

哈哈,开个小玩笑,下面来看一下比较苦逼的问题。

服务器是6G的内存,所以选用64bit的OS,在centos6的情况下各种环境不适应,真的很头疼,这是多方的问题,勉强搭载出来了服务,开始第二台的调试。

这个redhat更苦逼,yum 安装完了Nginx之后,无法通过浏览器上的地址栏拉访问,一直处于等待回应状态。

去Nginx的报错日志查看
2011/12/21 15:43:52 [emerg] 16079#0: eventfd() failed (38: Function not implemented)
2011/12/21 15:43:52 [alert] 16078#0: worker process 16079 exited with fatal code 2 and can not be respawn
2011/12/21 15:45:49 [emerg] 16105#0: eventfd() failed (38: Function not implemented)
2011/12/21 15:45:49 [alert] 16104#0: worker process 16105 exited with fatal code 2 and can not be respawn

 

一脸大汗,原来是OS的内核问题,大家多注意吧。

PS:

Linux VPS 内核版本是 2.6.18,只有 2.6.22 以后版本才支持 ,解决方法很简单,升级内核就可以了。

手工安装Nginx

其实这不是第一次写,写这个是针对上篇的RedHat的问题

有兴趣的看下,无兴趣的可以Skip

1
2
3
4
5
6
7
8
9
10
11
12
13
安装pcre
# wget http://sourceforge.net/projects/pcre/files/pcre/8.11/pcre-8.11.tar.gz/download
# tar xvf pcre-8.11.tar.gz 
# cd pcre-8.11
# ./configure --prefix=/usr/local/
# make && make install
 
安装nginx
# wget http://nginx.org/download/nginx-0.8.53.tar.gz
# tar xvf nginx-0.8.53.tar.gz
# cd nginx-0.8.53
# ./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module 
# make && make install

Nginx下 301和302跳转

首先明白什么是301和302

301的含义是“永久重定向”,而302的含义是“临时重定向”。

302 重定向和网址劫持(URL hijacking)有什么关系呢?这要从搜索引擎如何处理302转向说起。从定义来说,从网址A做一个302重定向到网址B时,主机服务器的隐含意思是 网址A随时有可能改主意,重新显示本身的内容或转向其他的地方。大部分的搜索引擎在大部分情况下,当收到302重定向时,一般只要去抓取目标网址就可以 了,也就是说网址B。

实际上如果搜索引擎在遇到302转向时,百分之百的都抓取目标网址B的话,就不用担心网址URL劫持了。

问 题就在于,有的时候搜索引擎,尤其是Google,并不能总是抓取目标网址。为什么呢?比如说,有的时候A网址很短,但是它做了一个302重定向到B网 址,而B网址是一个很长的乱七八糟的URL网址,甚至还有可能包含一些问号之类的参数。很自然的,A网址更加用户友好,而B网址既难看,又不用户友好。这 时Google很有可能会仍然显示网址A。

由于搜索引擎排名算法只是程序而不是人,在遇到302重定向的时候,并不能像人一样的去准确判定 哪一个网址更适当,这就造成了网址URL劫持的可能性。也就是说,一个不道德的人在他自己的网址A做一个302重定向到你的网址B,出于某种原因, Google搜索结果所显示的仍然是网址A,但是所用的网页内容却是你的网址B上的内容,这种情况就叫做网址URL劫持。你辛辛苦苦所写的内容就这样被别 人偷走了。

其实302的跳转本身是没有错的,但因为被一些作弊者用多了,Google当然对这个就比较敏感了,毕竟Google面对的是如此海量的数据,你难道不怕被误杀吗?

Google的官方内容一再强调用301来转移内容,况且,301和302在程序上的设置相差很小,既然如此,何必要冒险用302呢?

那么就来看看nginx的配置代码吧。

301跳转设置:

server {
listen 80;
server_name xxx.com;
rewrite ^/(.*) http://72xit.com/$1 permanent;
access_log off;
}

302跳转设置:

server {
listen 80;
server_name xxx.com;
rewrite ^/(.*) http://72xit.com/$1 redirect;
access_log off;
}

yum安装Nginx

之前的Nginx的YUM源不能用了,本想着去Nginx官方网站去手工安装一下,但是发现nginx的官方也提供源的维护了。

Pre-Built Linux Packages for Stable

To enable automatic updates of Linux packages set up the yum repository for the RHEL/CentOS distributions, or the apt repository for the Debian/Ubuntu distributions.

To set up the yum repository for RHEL/CentOS, choose the corresponding nginx-release package from the list:

This package contains yum configuration file and a public PGP key necessary to authenticate signed RPMs. Download and install it, then run the following:

yum install nginx

Alternatively, a repository configuration can be added manually without installing the nginx-release package. Create the file named/etc/yum.repos.d/nginx.repo with the following contents:

[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/OS/OSRELEASE/$basearch/
gpgcheck=0
enabled=1

Replace “OS” with “rhel” or “centos”, depending on the distribution used, and “OSRELEASE” with “5” or “6”, for 5.x or 6.x versions, respectively.

For Debian/Ubuntu, in order to authenticate the nginx repository signature and to eliminate warnings about missing gpg key during installation of the nginx package, it is necessary to add the key used to sign the nginx packages and repository to the aptprogram keyring. Please download this key from our web site, and add it to the apt program keyring with the following command:

sudo apt-key add nginx_signing.key

 

For Debian 6 append the following to the end of the /etc/apt/sources.list file:

deb http://nginx.org/packages/debian/ squeeze nginx
deb-src http://nginx.org/packages/debian/ squeeze nginx

 

For Ubuntu 10.04 append the following to the end of the /etc/apt/sources.list file:

deb http://nginx.org/packages/ubuntu/ lucid nginx
deb-src http://nginx.org/packages/ubuntu/ lucid nginx

 

For Debian/Ubuntu then run the following commands:

apt-get update
apt-get install nginx

如此一来方便很多,因为我是centos5系统,所以还是

rpm -Uvh http://nginx.org/packages/centos/5/noarch/RPMS/nginx-release-centos-5-0.el5.ngx.noarch.rpm
yum -y install nginx

Nginx 根据访问终端跳转页面

有些需求需要同一个域名识别终端来展示不同的界面,使用Nginx获取UA来判断终端类型,实现简单的跳转操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
 server_name g3.tm-sp.com;
 listen 80;
 access_log off;
 location / {
 if ($http_user_agent ~ "((MIDP)|(WAP)|(UP.Browser)|(Smartphone)|(Obigo)|(Mobile)|(AU.Browser)|(wxd.Mms)|(WxdB.Browser)|(CLDC)|(UP.Link)|(KM.Browser)|(UCWEB)|(SEMC\-Browser)|(Mini)|(Symbian)|(Palm)|(Nokia)|(Panasonic)|(MOT)|(SonyEricsson)|(NEC)|(Alcatel)|(Ericsson)|(BENQ)|(BenQ)|(Amoisonic)|(Amoi)|(Capitel)|(PHILIPS)|(SAMSUNG)|(Lenovo)|(Mitsu)|(Motorola)|(SHARP)|(WAPPER)|(LG)|(EG900)|(CECT)|(Compal)|(kejian)|(Bird)|(BIRD)|(G900/V1.0)|(Arima)|(CTL)|(TDG)|(Daxian)|(DAXIAN)|(DBTEL)|(Eastcom)|(EASTCOM)|(PANTECH)|(Dopod)|(Haier)|(HAIER)|(KONKA)|(KEJIAN)|(LENOVO)|(Soutec)|(SOUTEC)|(SAGEM)|(SEC)|(SED)|(EMOL)|(INNO55)|(ZTE)|(iPhone)|(Android)|(Windows CE)|(Wget)|(Java)|(curl)|(Opera))"){
	rewrite ^/(.*)$ http://221.180.20.228:8081/wap/$1 ;
}
if ( $http_user_agent ~ ^$ )  {  
	rewrite ^/(.*)$ http://221.180.20.228:8081/wap/$1 ;  
}         
 proxy_pass http://221.180.20.228:8080;
 }
}