利用nginx实现支付系统隐藏IP进行回调(补充)

最近有个朋友的网站出现无法回调的情况,现象为502错误,原因在于他网站加了CDN百度云加速,导致我支付系统无法异步回调通知

经过查询各种资料,问题发现在于https

相关文章:nginx反向代理,支持SNI的https回源

最关键的一句proxy_ssl_server_name on最关键的,也就是把主机名字传递给后端服务器,让对方服务器在TLS握手层面就可以收到host,便于打到具体的主机。(nginx 1.7开始支持)

server {
        listen       80;
        server_name  hidden.com;
        resolver     114.114.114.114;
		proxy_ssl_server_name on;

        location / {
            proxy_pass   $http_x_target;
        }
}

利用CDN让无法备案的域名使用国内服务器

搬瓦工云服务器要到期了,速度太慢,不再续费咯

本博客原先是基于国外搬瓦工服务器进行反向代理绕过备案

原文http://tom.cat/?p=39

后来改进了一下,使用自定义请求头,阿里云对80端口扫描拦截非备案域名流量,是依据请求头的host来识别,改成8888端口后,又遭遇流量限速的问题,这个当初用日本的云服务器测试过得出来的结论,即国外服务器反代进来用备案域名访问速度非常快,非备案的基本上打开网页都困难,速度极其的慢。

解决方式如下

国内阿里云服务器端nginx配置

server {
        listen       8888;
        server_name  ~^(www\.)?(.+)$;

        location / {
		    proxy_redirect  off;
            proxy_set_header Host $http_x_host_x;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			if ($http_x_host_x = 'tom.cat') {
				proxy_pass   http://localhost:8089;
				break ;
			}
			if ($http_x_host_x = 'whois.ci') {
				proxy_pass   http://localhost:8089;
				break ;
			}
            proxy_pass   http://localhost:8088;
        }
}

国外搬瓦工服务器端nginx配置

server {
        listen       80;
        server_name  tom.cat;
	location / {
		proxy_redirect  off;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Host-X $host;
		proxy_pass   http://www.xxx.com:8888/;
        }
}
server {
        listen       80;
        server_name  whois.ci;
	location / {
		proxy_redirect  off;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_set_header X-Host-X $host;
		proxy_pass   http://www.xxx.com:8888/;
        }
}

http配置节点需增加underscores_in_headers on;启用自定义请求头

nginx接收自定义请求头需要注意,搬瓦工端用X-Host-X,阿里云端用$http_x_host_x接收,即大写转小写,中横线转下划线,加 http_ 前缀

以上这样配置解决了访问速度的问题,接下来进入正题,现在搬瓦工不续费了,采用CDN来替代搬瓦工这个角色

CDN服务商:https://cdn.umistrong.com.cn/

进CDN后台添加域名,业务区域选择无备案,源站地址需要填写已备案的域名

添加域名后,按照要求认证域名并添加cname解析

进域名高级设置–>Header配置–>请求头配置

进域名缓存配置–>缓存规则表–>缓存规则

搞定结束!

再次利用nginx反向代理发送邮件隐藏源站IP

越来越发觉nginx是个神器,从上次隐藏回调IP,现在再次利用它来隐藏邮件发送的源站IP!

这两天网站加了CDN,目的是隐藏源站IP,现在问题来了,前置CDN解决了IP暴露问题,但是对于使用邮件注册会员的系统来说,就产生了IP暴露的问题,我们来看看是怎么回事

我使用的是QQ域名邮箱,显示邮件原文后就可以看到源站IP,这不是直接脱了裤子让人家打吗,问题总是需要解决的,研究了下nginx的用法,发现nginx可以TCP反代,这可是好东西啊!

先设置源站的nginx配置文件

stream {
upstream mail.com {
server 172.16.110.13:465 weight=1;
server 172.16.110.12:465 weight=1;
server 172.16.110.14:465 weight=1;
}

server {
    listen       465;
    proxy_pass   mail.com;
}

}

然后设置源站的hosts文件

127.0.0.1 mail.com

最后设置3台代理服务器的nginx配置

stream {
server {
listen 465;
proxy_pass smtp.qq.com:465;
}
}

因为使用的是SSL,采用465端口,自己看就明白了,举一反三,其他端口应该也差不多!

邮件配置

email.host=mail.com
email.port=465
email.username=service@umistrong.com.cn
email.password=password
email.from=service@umistrong.com.cn

最后贴一下我用的邮件发送工具类,是SSL版本的


import java.security.GeneralSecurityException;
import java.util.; import javax.mail.;
import javax.mail.internet.*;
import com.sun.mail.util.MailSSLSocketFactory;
public class EmailUtils {

private static String host = PropertiesUtils.getProperties().getProperty("email.host");
private static String port = PropertiesUtils.getProperties().getProperty("email.port");
private static String userName = PropertiesUtils.getProperties().getProperty("email.username");
private static String password = PropertiesUtils.getProperties().getProperty("email.password");
private static String from = PropertiesUtils.getProperties().getProperty("email.from");

public static void sendHTMLEmail(String to,String subject,String content) throws GeneralSecurityException{
    // 获取系统属性
    Properties properties = System.getProperties();

    // 设置邮件服务器
    properties.setProperty("mail.smtp.host", host);
    properties.put("mail.smtp.port", port);

    properties.put("mail.smtp.auth", "true");
    MailSSLSocketFactory sf = new MailSSLSocketFactory();
    sf.setTrustAllHosts(true);
    properties.put("mail.smtp.ssl.enable", "true");
    properties.put("mail.smtp.ssl.socketFactory", sf);
    // 获取默认session对象
    Session session = Session.getDefaultInstance(properties,new Authenticator(){
        public PasswordAuthentication getPasswordAuthentication()
        {
            return new PasswordAuthentication(userName,password); //发件人邮件用户名、密码
        }
    });

    try{
        // 创建默认的 MimeMessage 对象
        MimeMessage message = new MimeMessage(session);

        // Set From: 头部头字段
        message.setFrom(new InternetAddress(from));

        // Set To: 头部头字段
        message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

        // Set Subject: 头部头字段
        message.setSubject(subject);

        // 设置消息体
        message.setContent(content,"text/html; charset=utf-8");

        // 发送消息
        Transport.send(message);
    }catch (MessagingException mex) {
        mex.printStackTrace();
    }
}
}

这样搞完以后,对原先支付系统无需任何改动,只需要改动配置文件的邮件发送服务器地址即可,负载均衡发邮件,美滋滋!!!

收工睡觉,哈哈哈!

利用nginx实现支付系统隐藏IP进行回调

之前开发了一套聚合支付系统——优米云支付https://pay.umistrong.com.cn/

虽然目前系统没有遭遇DDOS攻击,但是还是需要未雨绸缪,避免未来可能发生的攻击,对云服务器隐藏IP是有必要的。

我们都知道,网站前置CDN进行IP隐藏很容易,但是对于支付系统这类需要对商户网站进行回调,由于是用本系统发起对商户网站的http请求,自然会有IP暴露的问题。

实现隐藏IP有3个思路

方案1.使用apache的httpclient进行代理访问

    //设置代理IP、端口、协议(请分别替换)
    HttpHost proxy = new HttpHost("你的代理的IP", 8080, "http");

    //把代理设置到请求配置
    RequestConfig defaultRequestConfig = RequestConfig.custom()
            .setProxy(proxy)
            .build();

    //实例化CloseableHttpClient对象
    CloseableHttpClient httpclient = HttpClients.custom().setDefaultRequestConfig(defaultRequestConfig).build();

    //访问目标地址
    HttpGet httpGet = new HttpGet("http://www.baidu.com");

    //请求返回
    CloseableHttpResponse httpResp = httpclient.execute(httpGet);
    try {
        int statusCode = httpResp.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.SC_OK) {
            System.out.println("成功");
        }
    } catch (Exception e) {

    } finally {
        httpResp.close();
    }

第一种方案,需要在每个代理服务器安装代理软件,并且有多台代理时候,依赖支付系统内轮询做负载均衡。

方案2.开发扩展模块,支付系统调用扩展模块接口进行通信

第二种方案,扩展模块需要部署到每个代理服务器,假设扩展模块用java开发,就需要每台服务器安装JRE,也很麻烦,负载均衡可在支付系统做也可在扩展模块做。

方案3.使用nginx的反向代理,在java发起请求时候,自定义header携带网址参数,nginx端设置proxy_pass 使用获取到的header参数即可

第三种方案就简单了,依靠nginx自带的负载均衡,本文重点说的这个方案,非常灵活!!!

java代码部分,增加X-Target的header

URL url = new URL("hidden.com");
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
httpConn.setRequestProperty("X-Target", requestUrl);//requestUrl为商户网站回调地址

hosts文件设置本地解析,支付系统和nginx负载均衡放同一服务器上

127.0.0.1 hidden.com

nginx负载均衡端配置underscores_in_headers必须开,否则nginx无法接收自定义header,proxy_set_header X-Target也要加,这个需要向下级nginx传递header,nginx获取自定义header的写法$http_前缀加上名称小写且中划线变成下划线,这里upstream我用了三台服务器,权重都是1,平均分配

http {
	underscores_in_headers on;
	
	upstream hidden.com {
		server 172.16.110.13:80 weight=1;
		server 172.16.110.12:80 weight=1;
		server 172.16.110.14:80 weight=1;
	}
	
	server {
        	listen       80;
        	server_name  hidden.com;

       	 	location / {
			proxy_set_header X-Target $http_x_target;
        		proxy_pass   http://hidden.com;
        	}
	}
}

nginx代理端配置, resolver一定要加,不然会出现502错误

	server {
        	listen       80;
        	server_name  hidden.com;
        	resolver     8.8.8.8;

        	location / {
           		 proxy_pass   $http_x_target;
        	}
	}

至此配置完成,后续增加代理服务器就很方便了,可以在负载均衡端增加节点,或者在代理服务器下继续传递X-Target,理论上是无限级传递。

利用nginx反向代理让无法备案的域名使用国内服务器

需要准备的

可备案且已备案域名一个,我用了个.com域名

无法备案域名一个,就是现在这个tom.cat

国内云服务器,我用的阿里云

国外云服务器,我用的搬瓦工,最便宜的那个

nginx的nginx.conf配置文件加上如下配置信息

server {
listen 80;
server_name tom.cat;
location / {
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://www.xxx.com:8888/;
}
}

server_name 是需要绑定的域名,并且域名A记录指向国外服务器IP

proxy_pass 这个是国内访问的地址,域名A记录需要指向国内云服务器,端口号可以带,也可以不带,这里需要分情况讨论

如果不配置 proxy_set_header Host $host; 就可以在 proxy_pass 中使用80端口,如果配置了此参数,就需要使用非80端口,因为阿里云对解析至国内阿里云服务器的未备案域名根据请求头的 Host 进行拦截。

这里我选择了配置 proxy_set_header Host $host; 参数,并在国内服务器使用8888端口,因为我的另一项目需要检测来路域名,根据实际的来路域名显示不同的信息,也就是java中的request.getServerName()获取到浏览器是通过哪个域名进行访问的。如果不配置,在反向代理时候 Host 不会被转发,导致真实的来路域名丢失,进而 request.getServerName() 只会获取到 www.xxx.com 而不是真正的tom.cat

也许有人会问,既然国外都有服务器,直接把网站安装在国外不是更简单吗,这里我说明下,我买的是搬瓦工的linux主机,最便宜那款,一年才 $18.89 USD,我本身对linux就不怎么会,能把nginx装好就很不错了,再去学安装php和mysql估计得吐血,并且买的这款国外服务器配置很差劲,便宜没好货你懂得。

顺便说下我国内云服务器的配置,WIN2012 64位,4H8G5M

谈谈我最近的创业项目

我最近的创业项目,跟域名行业有点像,关键点就是一个字——靓

项目用的域名QLLH.COM也是从许建华手里买来的,一如既往的基友价。低于四声行情价收来的。

域名正好对应网站名称——麒麟靓号,一个销售手机靓号的网站,网站一开始并不叫这个名字,是后来域名到手后根据字母想出来的,和许总商量了2个名字,麒麟靓号和青龙靓号,我选择了前者,因为麒麟有祥瑞的寓意。麒麟靓号网站虽然简陋一些,但是该有的功能都有了,性能也相当不错,技术方面采用spring+springMVC+mybatis开发,由于19年6月时候第一次创业失败后,急忙转型至靓号行业,一开始就对市面上现成的手机号销售网站源码不太满意,并且基本上同行都是用同一套程序,外观方面千篇一律,就算勉强用上,未来二次开发也不容易,毕竟现成的玩意是ASP.NET语言写的,于是决定自己开发一个全新的网站,陆陆续续开发了4个月,终于在10月国庆后正式上线了。网站上线之前也提早开通了百度推广账户,正好赶上福州百度8月底的开户活动。

说到搜索引擎推广开户,还真是不得不从百度先开始开,这样会省下一大笔开户费,百度这个搜索引擎行业的霸主,自然不可能免开户费,不过可以趁着活动,开户费有便宜一些,并且对后续360搜索,搜狗,UC神马这几个平台的开户都有切切实实的优惠,至于哪些优惠我就告诉大家吧,百度推广户开通后,我们的一些企业信息也会通过他们行业渠道流到各个平台,这在行业里头应该算是信息共享,搜狗、UC神马、360搜索几个服务商就开始陆陆续续找上我,他们给出的条件都不错,都是主动提出免开户费以及降低推广户的预存门槛,这对初次创业的人来说可以省下不少的钱,从 搜狗、UC神马、360搜索 这3家来说,我省了至少一万二的开户费用,并且开户时间要选择在月底和年底,销售冲业绩的时候,优惠力度最大,这是我总结到的经验。

未完待续更新中。。。

人生中的第一个博客

本博客域名TOM.CAT,从好友手里收来的,至于收来的价格,友情价,捡漏价,抄底价。

域名的原主人是非主流域名圈内的大佬——许建华,此人富得流油,却经常对我哭穷。

之所以用此域名做博客,跟本人职业有关,没猜错,JAVA程序猿一只。

.cat 后缀域名不能备案,所以不能用国内服务器,不过这博客是部署在国内服务器上,用国外的搬瓦工反向代理至国内阿里云,算是勉强能用吧,访问速度有些慢。至于为何不直接部署在搬瓦工,原因当然是买的最便宜的搬瓦工,配置很辣鸡,并且不怎么会用linux,好吧,暴露了,我不是一个合格的程序员,哈哈,丢人呐。

准备过阵子有钱了换个香港的服务器

初次玩博客,对WordPress也不是很懂,以后再慢慢完善咯。

有想交换友链的朋友在博客中留言哦。

撸到了一只世界级的猫

在日常生活中,猫已经是最常见的动物。但在社交网络上,猫已超脱了本身,形成了一股猫文化。

当然这篇文章并不是在探讨如何撸猫,而是向大家介绍今天的主角 TOM.CAT (域名),提起这只猫的名字你一定会觉得熟悉,毕竟汤姆猫杰瑞鼠深入人心,当然 TOM.CAT 所拥有的含义也不仅仅只是动画片中的汤姆猫,由大家自行补充吧。

.Cat域名后缀目前建站必须使用或含有当地语言或当地文化,不强制要求全部为当地语言或文化。可建立多语言站点,但:多语言必须包含其中有当地语言即可。