在配置自己的个人网站的过程中,我学到了许多编程以外的知识,下面就来逐一说一说吧。
CloudFlare
由于我的网站是托管在 OpenShift 上面,而 OpenShift 提供的默认域名 xxx-xxx.rhcloud.com
在国内由于某些特殊原因无法访问,经过再三的搜索,我决定使用 CloudFlare 来在国内加速我的网站。CloudFlare(下文简称 CF)是一个可以帮助提升网站加载速度、阻止网络攻击的公司,原理是将域名的 NS 记录(后续会讲到)修改为 CF 的记录,所有走这个域名的流量都会经过 CF 的服务器处理。所以其实 CF 对于我的网站来说就是个代理,只不过功能多了点,我用到的大概有:配置 DNS、使用 Flexible SSL 实现 HTTPS、Web 防火墙、缓存、压缩静态资源。
CF 对我来说最有帮助的就是 Flexible SSL 了,因为我比较懒,不想管理证书,因此就全部交给了 CF,这样用户通过 HTTPS 连接到 CF,CF 通过 HTTP 连接到 OpenShift,普通用户并不能感受到与直连 HTTPS 网站有什么区别。
DNS 简述和配置
刚才提到了 NS 记录,这个其实是 DNS 的内容。NS 是 Name Server 的简称。说到这儿,该讲一讲 DNS 的原理了。
助记符与电话簿
举个例子(样例来源:POJ 1002),假设我的号码是 487-3279
,那么有一个好记的方法就是:在九宫格键盘上输入 ITS-EASY
就可以了。在玩“勿忘我”这个游戏的时候,也多次提到“助记符”的概念,就是用一段话来记住一个口令(虽说我觉得游戏中 H3O
这个口令本身就很好记嘛)。但是这个并不能每次都奏效。例如一个网站的服务器 IPv4 地址由四个 0~255 的数字组成,正常人的脑子里一般记不住那么多的 IPv4 地址(更何况现在的 IPv6 更凶残),于是人们就想到了类似于电话簿的方法。就像刚才的例子,你只需要翻一下自己的电话簿,找到 REX
这一条,发现后面的值就是 4873279
,再打电话就可以了。早期的互联网就是这样发展起来的,只不过你打电话变成了浏览器要访问网站,REX
变成了 www.rexskz.info
,4873279
变成了 104.27.166.43
而已。在现在的操作系统中依旧保留了这个电话簿文件,关键是这玩意居然还能用。Windows 中的位置在 %windir%/System32/drivers/etc/hosts
,Linux 中的位置在 /etc/hosts
。以 Windows 为例看一下里面默认的内容吧:
# Copyright (c) 1993-2009 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
# localhost name resolution is handled within DNS itself.
# 127.0.0.1 localhost
# ::1 localhost
每一行有两个字段,第一个是 IPv4 或者 IPv6,第二个是对应的域名,允许一个 IP 对应多个域名(多个 IP 对应一个域名的事情我没干过,毕竟从逻辑上来说不行,你总不能让浏览器随机选一个吧,但是不知道 Windows 允不允许这样写)。有两个例外:127.0.0.1
和 ::1
是被硬编码在 DNS 解析器里的,你不能通过设置 211.65.101.15 localhost
来将 localhost
修改成其它网站。当然,特殊的设备和程序也许可以,如果直接修改了 IP 报文的话。
至于这个文件为什么依旧被保留,原因之一是为了兼容一些古老的程序,当然对于我们开发者来说也很有用,例如你可以设置 127.0.0.1 rexskz.com
,这样你访问 rexskz.com
就是访问本地网站了。当然,你也可以通过设置 127.0.0.1 xxx.baidu.com
来屏蔽百度的一些服务。
DNS 服务
早期互联网主机非常少,以至于一个文件就能存下了,但是现在的网站已经多到不知道多少个了,每个网站都可能会有很多很多域名(例如我的网站就有 blog.rexskz.info
、terminal.rexskz.info
等五六个二级域名,还有 rexskz.cn
这样的域名),这种规模,一个文件肯定存不下,于是聪明的前辈们把这玩意单独摘了出来,形成了现在的 DNS 服务(还记得之前被 Mirai 搞掉的 Dyn 公司么?它就是提供 DNS 服务的,只不过恰好 某个不存在的网站 使用了它的 DNS 服务,因此美国的吃瓜群众们上不去了)。
我们以 CF 为例,看一下我的域名 rexskz.info
是如何配置的(截取了部分记录):
可以看到 A 记录、CNAME 记录等,比较常见的有这么几个:
A:指向一个确定的 IPv4 地址
AAAA:指向一个确定的 IPv6 地址
CNAME:告诉你应该到哪个地方继续寻找
MX:指定域名的接收邮件服务器
SPF:指定域名的发送邮件服务器
TXT:该域名的说明文字
A 和 AAAA 没什么好说的,就是告诉你“这个域名的 IP 就是这个”;CNAME 的作用相当于别名,例如你访问 blog.rexskz.info
就相当于访问了后面的 xxx-xxx.rhcloud.com
;MX 的作用是,如果你给 [email protected] 发邮件,那么邮件会被发送到 MX 所指定的邮件服务器,你也可以为不同的子域名指定不同的邮件服务器;SPF 和 TXT 常用于反垃圾邮件,例如我在邮件中声明我是 [email protected],你可以查一下看看发送这封邮件的服务器是否在 rexskz.info 的 SPF 列表中,如果不是,那肯定是假的了,当然也有把信息写在 TXT 里面的,例如网易的免费域名邮箱。
所以域名绑定就是先配置好 OpenShift,让 OpenShift 准备好接收这样的请求(其实相当于在 OpenShift 内部又新建了一条 DNS 记录,因为我们最终需要的是 IP,所以查询肯定会终止于某条 A 或者 AAAA 的记录),然后在 CloudFlare 配置好 CNAME 就可以啦!如果需要使用 CF 的服务(例如 Flexible SSL),则需要激活右边的那朵云,表示流量会先经过 CF 处理。
TTL
顺便提一下 TTL 好了,TTL 表明这个记录过多久就需要更新一次,有点像 Web 里面的 Cache control
。对于一般的网站,一个域名配置好之后,可能很久都不会再改动了,增大 TTL 有助于降低 DNS 查询的频率,但是如果有了修改,生效的时间也会很长。所以具体取什么值也是一门学问。当然,CF 直接帮我选了“自动”……
Nginx 多域名配置
提示:下文与 OpenShift 无关。
其实关于 Nginx 的多网站配置还是相当简单的,在配置文件中多写几个 server
命令就可以了。但是如果是同一网站的多个子域名,感觉写好多个 server
不太好,而且我希望有个更方便的方式:在网站根目录下建立若干文件夹,xxx
文件夹就对应着 xxx.rexskz.info
。搜索了一下,可以这么写:
server {
listen 80;
server_name ~^(?<subdomain>.+)\.rexskz\.info$;
root /data/www/$subdomain;
index index.php index.html index.htm;
}
server_name
中 '.rexskz.info'
之前的部分会被提取出来,可以用专门的 $subdomain
变量访问。这解决了我一开始的问题。然而随着网站规模的扩大(其实是我有强迫症),有时候我需要设置一些优雅链接,例如除夕夜的抢红包的网站 https://hongbao.rexskz.info/first
,其实真正的网址应该是 https://hongbao.rexskz.info/index.php?code=first
。对于这个需求,一般的 Nginx 配置文件倒也好写:
location ~ ^/([^_][0-9A-Za-z_]+)$ {
rewrite ^/([^_][0-9A-Za-z_]+)$ /index.php?code=$1 last;
}
然后就有了一系列需求,例如我正在做的解谜网站 https://riddles.rexskz.info/first
也需要这样的链接,之前写的每日打卡的网站 https://withu.rexskz.info/day/63
也需要这样的链接……但是这几个网站都属于不同的域名,Nginx 的 if
命令又不能嵌套,于是很长一段时间我不知道该怎么办,直到有一天突然一开窍,发现 location ~
后面的东西其实可以不用和 rewrite
后面的那一坨相同!于是索性把这几个整合成了一个 location
:
location ~ ^/(.+)$ {
if ($host = hongbao.rexskz.info) {
rewrite ^/([^_][0-9A-Za-z_]+)$ /index.php?code=$1 last;
}
if ($host = riddles.rexskz.info) {
rewrite ^/([^.]+)$ /index.php?level=$1 last;
}
if ($host = withu.rexskz.info) {
rewrite ^/day/([-\.\d]+)$ /day/index.php?day=$1 last;
}
}
大功告成!
Update 2019.01.07
由于 OpenShift 也不提供免费服务了,于是我的网站现在挂在了 Vultr 上;此外 CF 也提供了 Domain Registrar,于是我又把域名从 Godaddy 转移到了 CF;最后是我在 CF 中开启了 Full SSL,安装了 CF 的自签证书,服务器上关掉了 80 端口并开了 443 端口,算是提高了一些安全性吧。
版权声明:除文章开头有特殊声明的情况外,所有文章均可在遵从 CC BY 4.0 协议的情况下转载。