关于域名与Nginx反向代理的一些事儿

前几天,tx云的客服突然打电话给我,说我的域名备案有问题,一是域名绑定解析的服务器非tx云服务器;二是网站内容带有评论,属于交互式类型,与备案不符。限一天之内整改,否则域名将无法接入tx云。当时还在上班,也没多谈。晚上回去之后,没时间去修改,第二天直接被邮件通知说已上报管局。这波操作真的是有点蛮横霸道,不讲情面,毫无商量的余地啊!原本我的一级域名托管在Github是没有问题的,只是想开通下二级域名,而将二级域名绑定到tx云服务器,需要备案才行。现在备案不成,一级域名也被将被列入“黑名单”了。可能是因为与处女座隔得太近的原因,心里面对这个事情一直放不下,趁着周末时间充足,就想着抓紧时间把这个问题给了结了。

问题回顾

上面提到的主要有两个问题,第二个问题属于内容上的,对于网站来说,解决起来不是很麻烦,关键是想不想撤掉评论了。目前自己使用的是disqus,纯粹嵌入进来的,暂且不管吧。后续如果站点被封了,再想其他的方法解决好了。对于第一个问题,其实也有个方法,就是在服务器上部署一套编译hexo的node环境。但这对于服务器来说,不是很好,毕竟服务器的内存有限,上面还部署了neo4j来构建图谱QA,以及一些python服务等。能节省资源就节省下,毕竟都是穷孩子。那么,有没有更好的方法呢?

晚上睡觉前,仔细想了想,若要自己的站点内容不变,并且还要满足域名绑定的是tx云服务器,能够想到的就是采用反向代理,将一级域名绑定到tx云,然后再通过nginx转发到github上去。说起来好像有点道理,真要实现起来,还是需要点工程能力才行。前段时间,刚好在服务器上配置了二级域名的转发,这次基于之前的配置稍作修改应该就OK了。实际上,说简单也不简单,说不简单其实也比较简单,关键就是在于是否了解它。闲话不多说了,下面来看看具体实现!

反向代理

上面提到了反向代理,那么究竟什么是反向代理呢?举个栗子吧。

对于铁路来说,大家都比较熟悉,铁路客户服务中心的客服电话是12306,它是一个统一的客服电话入口,当我们需要咨询或是投诉铁路订票、退票相关问题时,只需要拨打12306电话,然后按0进入人工服务台即可,对面究竟是谁来接,我们不care,我们唯一需要确定的是,对面会有人来回应我们的电话(相当于服务器响应客户端请求),即使是很多人在同一时刻拨打12306(并发),也能得到响应。这个场景里面,拨打电话的我们,就是Client(客户端),而12306的客服就是Server(服务端),服务端采用了统一的入口,具体如何分发或转接,对于Client来说就类似一个黑盒。反向代理就是这个道理,如Fig 1所示,它代理的就是Server端。

Fig 1.反向代理原理图(source: https://dev.to/remyg/nginx-reverse-proxy-54d7)

了解什么是反向代理之后,下面来看看在我这个场景里面如何应用。

反向代理的实现

方法一:反向代理至Github

链路:一级域名->云服务器(proxy)->Github。

一级域名绑定服务器的具体方法这里就不一一展开了,如Fig 2所示,通过下面的配置绑定之后,就可以通过http://www.csuldw.com直接访问服务器的80端口了。想要进一步进行转发,就需要nginx来的协助了。

Fig 2.一级域名解析

nginx代理配置如下,它监听的是80端口,同时域名为一级域名,在location上面,首先配置的是“/”,设置它的proxy_set_headerproxy_passgithub.io的子域名,该子域名能够直接访问我托管在github上面的项目。配置完了之后,整条链路就已经打通了,不过图片之类的还是无法显示,还需要将图片之类的转发到github上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name csuldw.com www.csuldw.com;
root html;
location / {
proxy_set_header Host csuldw.github.io;
proxy_pass http://csuldw.github.io; #转发到github
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ^~/assets/ {
proxy_pass http://csuldw.github.io/assets/;
}
}

通过上面的配置之后,一级域名解析的就是tx服务器了,同时项目的内容还是托管在github,变动的地方不大。然而让人愁的是访问速度太慢,于是便想到了下面这条链路。

方法二:反向代理至二级域名

链路:一级域名->云服务器(proxy)->二级域名(通过CNAME绑定到csuldw.github.io)

首先通过CNAME方式将blog.csuldw.com子域名绑定到csuldw.github.io,然后我们将之前nginx配置的直接转发到github的地方改成blog.csuldw.com就OK了。具体的配置内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 80;
server_name csuldw.com www.csuldw.com;
root html;
location / {
proxy_set_header Host blog.csuldw.com;
proxy_pass http://blog.csuldw.com; #转发到github
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ^~/assets/ {
proxy_pass http://blog.csuldw.com/assets/;
}
}

这两条链路差别不大,但是效果却不一样,要是没尝试真的很难相信。做了上面的配置之后,顺便在nginx中添加了https(证书目前用的tx云解析的),配置如下,就当做个笔记,后续需要再来查看下!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
listen 443 ssl;
server_name www.csuldw.com csuldw.com; #填写绑定证书的域名
ssl_certificate /usr/local/nginx/conf/1_csuldw.com_bundle.crt; # 指定证书的位置,绝对路径
ssl_certificate_key /usr/local/nginx/conf/2_csuldw.com.key; # 绝对路径,同上
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #按照这个协议配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;#按照这个套件配置
ssl_prefer_server_ciphers on;
location / {
proxy_set_header Host blog.csuldw.com;
proxy_pass https://blog.csuldw.com; #转发请求
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ^~/assets/ {
proxy_pass https://blog.csuldw.com/assets/;
}
}

结束语

经过这番折腾之后,目前一级域名csuldw.com绑定的是自己的tx云服务器,经过nginx路由之后,会将一级域名指向二级域名blog.csuldw.com,而二级域名绑定的是csuldw.github.io,所以当我们直接访问一级域名的时候,实际上响应的页面就是csuldw.github.io。整个链路可能有点绕,很多童鞋可能也不会用到,这篇文章就当是一篇小结吧,后续如有用到,再来回顾下。

参考文献

  1. Nginx Reverse Proxy:https://dev.to/remyg/nginx-reverse-proxy-54d7
  2. https://en.wikipedia.org/wiki/Reverse_proxy