搭建基于 Nginx 反向代理与 Let's Encrypt 自动续期的前端服务

作者:wiLdGoose 发布时间:September 30, 2018 分类:技术 Technology

好久不在贵行混,殊不知原先那套 LAMP 或 LNMP 的架构早已奥特且随着岁月流逝慢慢发生了升级与变迁。

这次要玩的是一套提供前端服务的架构。大致交代一下故事背景:

1、负载机绑定了 1 个公网 IP 与 1 个私网 IP(VIP地址、私网 IP 漂移、HAProxy 高可用啥的需要运营商配合,正在准备,以后玩过了再写),部署 Nginx 用于反向代理;
2、前端服务所在主机与负载机在同一私网网段内。

好了,故事开始。

首先部署完负载机的 Nginx 服务,用于监听负载机的 TCP 80 及 443 端口。值得注意的是若使用源码编译方式安装 Nginx,记得添加:

--with-http_ssl_module --with-http_realip_module

其实直接 yum 也阔以。安装后对配置文件 nginx.conf 进行调整:

user www www;
worker_processes auto;
error_log /path/to/logs/error.log;
pid /path/to/logs/nginx.pid;
worker_rlimit_nofile 65535;
events {
    use epoll;
    worker_connections 65535;
}
http {
    include mime.types;
    default_type application/octet-stream;
    include /usr/local/nginx/conf/reverse-proxy.conf;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    client_max_body_size 50m; #缓冲区代理缓冲用户端请求的最大字节数,可以理解为保存到本地再传给用户
    client_body_buffer_size 256k;
    client_header_timeout 3m;
    client_body_timeout 3m;
    send_timeout 3m;
    proxy_connect_timeout 300s; #nginx跟后端服务器连接超时时间(代理连接超时)
    proxy_read_timeout 300s; #连接成功后,后端服务器响应时间(代理接收超时)
    proxy_send_timeout 300s;
    proxy_buffer_size 64k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
    proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
    proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
    proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传递请求,而不缓冲到磁盘
    proxy_ignore_client_abort on; #不允许代理端主动关闭连接
    server {
        listen 80;
        server_name _;
        location / {
            root html;
            index index.html index.htm;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }
}

记得打开防火墙端口,若还有上级网络安全策略等,更新配置。

前端机 Web 服务因人而异了,这里假定还是由 Nginx 提供前端服务,部署过程略,监听前端机的 TCP 80 端口。值得注意的是需要在 Nginx 配置文件中定义日志格式:

log_format access '$HTTP_X_REAL_IP - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $HTTP_X_Forwarded_For';
 
access_log /path/to/logs/access.log access;

在负载机上编辑反向代理的配置文件:

vim /usr/local/nginx/conf/reverse-proxy.conf

若有多个 server 可再行扩展:

server
{
    listen 80;
    server_name sub.domain.com;
    location / {
        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_pass http://192.168.x.x;
    }
    access_log /path/to/logs/sub.domain.com_access.log;
}

截至目前,http 协议的转发已经完成。域名解析完成且生效后,访问应该会从负载机走私网定向到前端机。看了一圈日志没问题后,继续折腾 https。

SSL 证书提供商毫无疑问是 Let's Encrypt。据我所知有 certbot-auto 与 acme.sh 两种方式来实现证书自动申请与续展,前者貌似只能支持单个域名,而后者目前已支持泛域名证书。因此我选择后者。

配置过程就不展开了,中文版引导在这里。值得注意的是,若使用 certbot-auto,则需要修改负载机 Nginx 的反向代理配置文件,将 .well-known 目录指向本地:

server {
    listen 80;
    server_name sub.domain.com;
    […]
    location /.well-known {
            alias /path/to/sub.domain.com/.well-known;
    }

    location / {
        # proxy commands go here
        […]
    }
}

若使用 acme.sh,则既可通过 .well-known 目录来验证,也可通过 DNS 解析来验证(需提前向域名注册商申请 API)。可参考这里

好了,到这里,证书更新的事儿也是自动的。

去喝杯咖啡吧~

Update:

已实现客户端到负载机的访问是公网 https,负载机转发到前端机走私网 http。已遇到一个问题,最新版的 phpMyAdmin 会提示:

服务器和客户端上指示的 HTTPS 之间不匹配。这可能导致 phpMyAdmin 无法正常工作或存在安全风险。请修复您的服务器配置以正确指示 HTTPS。

嗯~有待进一步解决。

Update:

上述问题解决方案:在 phpMyAdmin 的配置文件中添加:

$cfg['PmaAbsoluteUri'] = 'https://pma.xxx.com';

即可。

电信客服网站再现低级错误 电话欠费一目了然

作者:wiLdGoose 发布时间:February 29, 2008 分类:技术 Technology

春节期间实在不想出门,所以在网上给自己的电话缴费,结果发现浙江电信缴费网站上的一个设计缺陷,于是乎发了一篇文。据说后来这文章曾被朋友投递到 cnbeta,我去看时已经删除了。然后我看到网友 Billwang 发表评论说漏洞已被修复,随后我证实了这一信息。再后来浙江电信的叔叔阿姨就找到了我,详情可以看这个截图

说实话,经过这件事情,我对浙江电信的工作效率和工作态度的认知有了一个较大的改变。由于工作的原因,平时与电信部门的官员打交道也不少。在我的认知中看来,像这样的问题起码需要两个月时间解决:基层工作人员发现问题,上报主管;主管平时工作较忙,在一周内提交到技术部门的负责人核实;技术部门老大的工作就更忙,于是又需要一周的时间安排查证工作;然后搞技术的小伙子也很懒,也需要一周的时间磨洋工;磨出来之后将结果反馈给老大,这时已经过去大半个月了;随后技术部门的老大将报告提交到主管经理,主管经理需要一周时间审核这份报告,随后报送分管领导;分管领导在接到文件后的一周召开讨论会,讨论是否需要将这份报告提交上级主管单位;讨论会结束后,小秘整理会议纪要,报送接口人向上级主管单位转达文件;后者接到文件后又开始一个新的轮回……

总而言之,他们这次的反映速度和解决问题的耗时让我非常惊讶。当然,能找到我本人也是情理之外、意料之中。在表扬了浙江电信某些同学的工作能力后,让我们继续关注一下他们在网上收钱的工具目前运作的如何。

首先登录浙江电信网上客服中心

选择导航栏的“自助服务”:

选择左下角的“充值交费”(事后我发现这个地址居然可以直接访问,并不需要事先登录):

与上次一样,填入要查询话费信息的电话号码:

又见阿里巴巴集团欠费 90 万元:

通过观察其实不难发现,在这个查询过程中,整个浏览器的 URL 是不改变的。也就是说这个页面使用了嵌入式框架,我们在框架页面上点击右键,查看页面属性:

将这个 URL 直接复制到新窗口中打开,依然有效:

我原以为是 session 或者 cookie 在起作用。在我退出登录后再次刷新页面,结果依旧。然后我在浏览器中直接打开这个地址:http://www.114mall.cn/ctpay,结果是这样的:

综合页面报错提示和 URL 的构造规律来看,被查询话费的号码信息确实通过 GET 方式传递到相关脚本。另外,我很惊奇的发现,每次打开 http://www.114mall.cn/ctpay 这个地址所被重定向的 URL 地址都不同,但都类似这样:

除了上面截图中红框中所显示的字符串外,还可能会有类似“qraxw2ih5dw1iuzy0vrzao45”、“eisxsp55xebbz2455xvfllji”、“52jklvayi0zir245cdlspu3s”等等不同的字符串组合,每次随着页面的刷新或者重定向而不同。经过对 URL 参数的筛选,我们可以构造出这样的地址:

http://www.114mall.cn/ctpay/(qraxw2ih5dw1iuzy0vrzao45)/index.aspx?queryNo=85027110&areaId=571

http://www.114mall.cn/ctpay/(eisxsp55xebbz2455xvfllji)/index.aspx?queryNo=88157858&areaId=571

http://www.114mall.cn/ctpay/(52jklvayi0zir245cdlspu3s)/index.aspx?queryNo=88156688&areaId=571

类似这样的地址可以直接打开,并不需要用户登录。对于想查询话费信息的朋友,不需要登录,不需要任何验证,一个地址直接搞定,果然又“方便”了很多。相比上次的情况,只不过被查询的电话号码的户主未被显示罢了。如果发起有针对性的查询,一样可以获得相关信息。感谢中国电信贴心而和谐的服务,让我们鼓掌。

顺便说一下浙江电信的网站。目前所使用的是新版,地址为 http://www.zjtelecom.com.cn,想一睹浙江电信曾经的辉煌历史,敬请访问 http://www.zjtelecom.com.cn:90。请注意,在您浏览的时候,请自觉的发出啧啧的赞叹声。谢谢合作。

中国电信网站或存在设计缺陷 客户隐私无保障

作者:wiLdGoose 发布时间:February 9, 2008 分类:技术 Technology

春节是一个容易让大部分国人变得懒惰的节日。每天好吃好喝之后就犯困,要么睡大觉,要么 KTV、泡吧……总之就是应了一句话:“饱暖思淫欲”。在这样一个节日里,我也明显感受到了生活的无趣。我不是工作狂,但我一直坚信工作、生活密不可分,缺一不可。这几天彻底闲下来,直接导致我的反应能力下降;随之而来的是慵懒,懒得出门、懒得走路、懒得打电话拜年,甚至懒得吃饭、懒得睡觉。

为了避免大脑生锈,这里顺便分析一下“懒得出门”这样的短语,用 lucky说就是“咬文嚼字”。“懒得出门”这个短语最容易产生歧义的地方就是这个“得”字,因为“得”有很多种意思。《南史·陶潜传》中有云“开郑有得,便欣然忘食。”这里的“得”作名词,有“收获、心得”之意。而《史记·项羽本纪》中“君为我呼入,吾得兄事之。”这里的“得”是副词,有“必须、应该”的意思。在某些语境中,“得”还通假“德”;如《荀子》中所述“尚得推贤不失序。”此外,“得”还可以作动词,解释成“得到、获得”。而这里的“得”用在形容词“懒”的后面,连接表示程度或结果的补语“出门”,基本上算一个连接助词。“懒得出门”与“红的发紫”表意不同,前者表示懒惰到不想出门,而不是懒惰到我出门了;后者表示很红,以致于快发紫了。

我终于意识到,在我写下如此知音的标题后,眼看前面又说了这么多废话,几乎快赶上标题党了。马上开始正文。

由于一直懒得出门,所以对于电信的催缴话费的电话通知也置若罔闻。今天白天在睡梦中被这样一个电话活生生吵醒,非常郁闷:眼看青蛙已经变成了王子,正要去吻沉睡的公主,就突然没了下文。不知道公主是苏醒了过来,还是突然变成了青蛙。为了避免以后再发生此类事情,我给 10 的 4 次方去了电话,咨询能否网上支付固话账单。对方的回复是这样的:“尊敬的中国电信用户,您咨询的缴费方式目前暂未开通。您可以选择去您当地就近的营业厅办理缴费或其他业务。给您带来不便,我们深表歉意。中国电信感谢您的理解、关心与支持,祝您新春愉快、万事如意。您若还有其他疑问,欢迎您随时致电中国电信客服一万号,我们将随时恭候您的垂询。再见。”我总结了一下,两个字:不行。

随后我在搜索引擎的结果中找到一个“中国电信网上客服中心”,然后又看到各地的分站。为了确认他的权威性,我找到这个域名的 whois 记录。不出意外的话,这是官方的“网上客服中心”了,不知道电信为何没有人去宣传,甚至有工作人员对此一无所知。

我根据页面上的提示,用电话号码注册了一个帐号,登录后开始寻找为固话交费的地方。在“自助服务”下面,我找到了“话费查询”,然后终于看到“缴费”字眼了:

点击“缴费”按钮居然来到另外一个 URL:http://www.114mall.cn/ctpay/。这让我感觉到一点发现新大陆似的好奇。初步测试了一下,这个地址不能直接访问,否则会提示“参数错误”。由于 URL 后面很干净,看样子数据是 POST 过去的。如果提交的数据正确,这时页面上会显示待缴电话账户的欠费情况。我把欠款结清之后再次看到这个页面,发现是这样的:

我回到“自助服务”,发现左侧栏目中有一项“充值缴费”,试着点击了一下:

填上自家电话号码,提交:

我想了一想,如果填写的是别人的电话号码呢?我试了一下,结果非常骇人:

看来中国电信的业务透明度实在已经达到了一个非常的境界,连自家公司的电话费用都可以查到,而且户主姓名也很精确:

对于小灵通也基本一样,但查询不到号码的户主姓名:

我隐约觉得,这个功能一定是中国电信所有业务中最好、最强大的一个业务。他似乎不仅能查全国(因为查询地区可以切换)的电信固定电话与小灵通账单,还能查到固话号码所对应的户主。简直就是免费的 114,堪比您的私家侦探。且该业务目前处于免费试用期,欢迎广大新老朋友试用:)

YY 广告了一把。

事后我发现在那个叫做“百事通商城”的网站上注册一个帐号,同样也能查询到上述信息:

登录后点击左侧“固话缴费”按钮可以查询到“各种”固话账单,点击“小灵通充值”按钮可以查询到“各种”小灵通余额或欠费信息:

固定电话查询:

小灵通查询:

于是,从现在开始起,我从心底里真心佩服中国电信;无论是他那优质的服务,还是他那无畏的胆量。根据我的主观分析,固话账单也好、小灵通余额也好,都是客户的隐私信息。每一个电信业务,都意味着中国电信以甲方身份与客户签有协约。所谓“言者无意、听者有心”,泄露客户资料对中电信这样的国家级企业来说一定无所谓;但对于最终用户来说,可能有时候就会造成很大的影响。而这一切祸水的来源,都是这个 114mall.cn 的网站。在好奇心的驱使下,我查看了这个域名的 whois 信息,结果又惊讶了一回……

Web 服务器遭受 ARP 欺骗攻击

作者:wiLdGoose 发布时间:January 24, 2008 分类:技术 Technology

一直以来,我以为 ARP 欺骗仅仅只会发生在公司单位、网吧等局域网环境比较复杂的地方。也曾耳闻到某些 IDC 机房也出过这样的事情,但总觉得这事情应该离我很遥远。没想到昨天晚上,一个地级市的电信机房也发生了这样的事情。我有幸亲临了整个事件的始终,中途除了机房的技术人员,还有二位仁兄被迫中止睡眠,起身与我一共奋战。一位是 feelinglucky 同学,另一位是我公司的小刘同学,在此向你们二位表示深切的慰问与诚挚的感谢。

昨天晚上 12 点 30 分(也就是今天零点三十分)左右,我打算进入博客后台取点资料,在登录页面上发现了惊奇的一幕:

刷新了一次之后还是这样,突然有一种不详的预感。然后,事实证明这种预感是准确的。我查看页面源代码,发现了更惊奇的一幕:

很明显,页面被挂马了。但又觉得这代码有点不对劲,于是冒着风险用 IE 访问了一下:

现在,发生了什么事情已经非常确定了。从最后一张图上看,应该是 ARP 欺骗挂马的结果;但也有可能是我的博客程序或者是服务器被挂马了。我一边打机房电话,告诉值班人员发生的事情;一边用 FTP 把博客所在目录的文件拖了下来。经过对博客程序的模板、程序代码的检查,发现并没有隐藏框架的代码存在。

下一步,检查服务器日志。把服务器上的 Apache 日志看了又看,没发现异常。根据 lucky 的建议,kill 掉了一些进程,问题依旧。lucky 又建议我测试一下本机访问本机会怎么样,于是:

#vi /etc/apache/httpd.conf

增加:

Listen 127.0.0.1:80

然后:

#/etc/rc.httpd restart
#vi /etc/hosts

增加:

127.0.0.1    www.xuchao.org

然后:

#cd /root
#wget https://www.xuchao.org/xxx/
#cat index.htm

在这里,我并没有发现有隐藏框架的代码存在。于是我更加坚定了刚才的判断,马上再次致电机房,告诉对方我刚才的测试过程,并指出问题极有可能出在机房里。值班的技术人员迷迷糊糊的从美梦中醒来,然后答应帮我检查。由于已经是后半夜了,他说最迟到上午 8 点就可以搞定。

等待、等待……在漫长的等待过程中,我重新查阅了一些几年没看的有关 ARP 欺骗的资料。唉,早知道就做双向绑定了。失误啊、失误。又看了一下 dmesg 日志:

#cat /var/log/dmesg.today

呵呵,全都是这样的内容:

arp: 122.225.96.1 moved from 00:19:b9:f1:14:1c to 00:11:bb:3e:62:3f on em0
arp: 122.225.96.1 moved from 00:11:bb:3e:62:3f to 00:19:b9:f1:14:1c on em0
arp: 122.225.96.1 moved from 00:19:b9:f1:14:1c to 00:11:bb:3e:62:3f on em0
arp: 122.225.96.1 moved from 00:11:bb:3e:62:3f to 00:19:b9:f1:14:1c on em0

从我一直 ping 服务器的情况看,机房的人重启了 3 次交换机,然后那段该死的隐藏框架代码已经不存在了。几分钟后机房给我打来电话,说问题已经解决。我问他原因,他说我的服务器所在机柜有一台服务器中毒,广播 ARP 欺骗包数据,没有防御能力的机器都倒下了。

由于连续 3 次断网,我们的服务器上服务端已经与数据库失去连接了(又是没有走内网通讯的恶果)。重启服务器,开启游戏服务端。早上 6 点,一切恢复正常。

明天整理一下思路,给出一份防御 ARP 欺骗的方案(针对 FreeBSD 服务器与 Windows 服务器)。

  1. 1