AI 摘要（由 ChatGPT 总结生成）：文章介绍了Linux系统下DNS解析流程，重点分析了`/etc/nsswitch.conf`、`/etc/hosts`、`/etc/resolv.conf`、`/etc/host.conf`等关键配置文件的作用与相互关系。文中还解释了网络配置文件如`/etc/sysconfig/network-scripts/ifcfg-xxxx`对DNS解析的影响，并通过命令行示例展示了如何查看与修改DNS配置。此外，文章还对`ping`和`host`命令在DNS解析中的差异进行了深入探讨，并通过实验验证了配置修改对这些命令行为的影响。前段时间蜜罐捕获到了一个攻击事件，黑客修改了蜜罐的 /etc/resolv.conf 文件中的内容以此操控相关的 DNS 解析行为，在 Linux 系统下，DNS 的解析也是一个复杂的过程。结合上次的事件，本文就简单介绍一下 Linux 系统下的 DNS 解析过程（以 CentOS 系统为例），如有错误，欢迎指正。此处不讨论浏览器、递归解析等因素。相关文件介绍在 Linux 系统下，一个域名的解析，是受到多个文件、多个流程去完成的，也是多个文件的配合过程。在系统中，有这几个关键文件： /etc/nsswitch.conf 、 /etc/hosts 、 /etc/resolv.conf 、 /etc/host.conf ；实际情况下，网卡的配置文件 /etc/sysconfig/network-scripts/ifcfg-xxxx 中的 DNS 字段可能也会对 DNS 的解析过程有一些影响，下面就简单分析一下上述几个文件的作用。nsswitch.conf 文件在Linux系统下， /etc/nsswitch.conf 文件，即（name service switch configuration，名字服务切换配置）规定通过哪些途径以及按照什么顺序通过这些途径来查找特定类型的信息。还可以指定某个方法奏效或失效时系统将采取什么动作。当需要提供 nsswitch.conf 文件所描述的信息的时候，系统将检查含有适当 info 字段的配置行。它按照从左向右的顺序开始执行配置行中指定的方法。在默认情况下，如果找到期望的信息，系统将停止搜索。如果没有指定 action，那么当某个方法未能返回结果时，系统就会尝试下一个动作。有可能搜索结束都没有找到想要的信息。在这个文件里，我们主要关注是如下 hosts 的一行：………… #hosts: db files nisplus nis dns hosts: files dns myhostname …………对于上述信息 hosts 字段的配置行，下面列出了该文件控制搜索信息类型的方法，对于每一种信息类型，都可以指定下面的一种或多种方法：Info字段方法说明files搜索本地文件，如/etc/passwd和/etc/hosts等。nis搜索NIS数据库，nis还有一个别名，即yp。dns查询DNS（只查询主机）。compatpasswd、group和shadow文件中的±语法。根据上述表格，可知 nsswitch.conf 文件说明了 DNS 查找将首先调查 /etc/hosts 文件来解析域名，然后查看 /etc/resolv.conf 文件配置来解析主机名。这也说明了文件 /etc/hosts 优先级大于 /etc/resolv.conf 的。请注意：DNS 查找指令（如 nslookup 和 dig ）将忽略 /etc/nsswitch.conf 文件，并始终使用 /etc/resolv.conf 引用DNS服务器。下面会说明。关于最后一个 myhostname，它一般出现在该文件 hosts: 字段的末尾，以确保优先使用传统的基于 DNS 与 /etc/hosts 文件的解析方法。只有当前面两个都解析不通时，myhostname 就起作用了，它可以把 hostname，解析成自己范围内的 IP 地址。我们可以通过下面命令查看 hostname 对应的 IP 地址：[root@localhost ~]# getent ahosts `hostname` ::1 STREAM localhost ::1 DGRAM ::1 RAW 127.0.0.1 STREAM 127.0.0.1 DGRAM 127.0.0.1 RAW [root@localhost ~]# 注：修改 nsswitch.conf 中的选项顺序不影响已运行的程序的解析顺序。hosts 文件这个文件想必大家都很熟悉，它和 Windows 系统目录的 C:\Windows\System32\drivers\etc\hosts 文件相类似，也是最早用于实现“域名”这个概念的文件。它是一个没有扩展名的系统文件，其基本作用就是将一些常用的主机名、主机名别名或域名与其对应的 IP 地址建立一个关联“数据库”。它的配置也很简单，直接在里面写上名称与 IP 的对应映射列表即可，比如我们最熟悉的 localhost 在该文件中就被映射指向 127.0.0.1 回本地址：[root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 [root@localhost ~]# 注：修改此文件立即生效。运行的程序也会受此影响，长连接除外。resolv.conf 文件这是 Linux 操作系统中的另一个重要文件，是 resolver 类库使用的配置文件， 它帮助计算机将域名转换为 IP 地址的信息。每当一个程序需要通过域名来访问 internet 上面的其它主机时，需要利用该类库将域名转换成对应的 IP，然后才可进行访问。它的格式很简单，每行以一个关键字开头，后接一个或多个由空格隔开的参数。它的关键字主要有四个，说明如下：nameserver：它的作用即定义 DNS 服务器的 IP 地址，可以配置多个 nameserver 指定多个 DNS 地址。search：定义域名的搜索列表，中间用空格或 tab 键隔开。当要查询没有域名的主机，主机将在由 search 声明的域中分别查找。这么说可能不太理解，通过如下的一个示例演示一下：[root@localhost ~]# ping www ping: www: Name or service not known # 此处找不到www域 [root@localhost ~]# [root@localhost ~]# vim /etc/resolv.conf [root@localhost ~]# cat /etc/resolv.conf # Generated by NetworkManager search baidu.com # 新增了一个搜索域 nameserver 119.29.29.29 nameserver 223.5.5.5 [root@localhost ~]# [root@localhost ~]# ping -c 1 www # www在搜索域中查找，其查找方式就变成了www.baidu.com PING www.a.shifen.com (36.152.44.96) 56(84) bytes of data. 64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=1 ttl=49 time=22.8 ms --- www.a.shifen.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 22.876/22.876/22.876/0.000 ms [root@localhost ~]# [root@localhost ~]# ping -c 1 www.baidu.com # 对照上述结果 PING www.a.shifen.com (36.152.44.96) 56(84) bytes of data. 64 bytes from 36.152.44.96 (36.152.44.96): icmp_seq=1 ttl=49 time=21.5 ms --- www.a.shifen.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 21.542/21.542/21.542/0.000 ms [root@localhost ~]# 原来，当访问的域名不能被 DNS 解析时，resolver 会将该域名加上 search 指定的参数，重新请求 DNS，直到被正确解析或试完 search 指定的列表为止。domain：定义本地域名。当为没有域名的主机进行 DNS 查询时，也要用到。如果没有域名，主机名将被使用，删除所有在第一个点( .)前面的内容。[root@localhost ~]# hostname localhost.localdomain [root@localhost ~]# domain 和 search 不能共存，如果同时存在，后面出现的关键字将会被使用。sortlist：允许将得到域名结果进行特定的排序。它的参数为网络/掩码对，允许任意的排列顺序。其中，上述最主要是 nameserver 关键字，如果没指定 nameserver 就找不到 DNS 服务器，其它关键字是可选的。nameserver 表示解析域名时使用该地址指定的主机为域名服务器。其中域名服务器是按照文件中出现的顺序来查询的，且只有当第一个 nameserver 没有反应时才查询下面的 nameserver。Red Hat 中没有提供缺省的 /etc/resolv.conf 文件，它的内容是根据在安装时给出的选项动态创建的。下面会说明。host.conf 文件这是解析器查询顺序配置文件。功能和 /etc/nsswitch.conf 文件中的 hosts 字段类似，指定相关主机名的查找方法。它每行含一个配置关键字，其后跟着合适的配置信息，其系统识别的关键字如下：order：这个关键字确定了主机查询是如何执行的。它后面应该跟随一个或者更多的查询方式，这些查询方式用逗号分隔，有效的方式有：bind、hosts 和 nis。trim：这个关键字可以多次出现。每次出现其后应该跟随单个的以句点开头的域名。如果设置了它，resolv+ 库会自动截去任何通过 DNS 解析出来的主机名后面的域名。这个选项用于本地主机和域。(相关信息: trim 对于通过 NIS 或者 hosts 文件获取的主机名无效。需要注意的是要确保在 hosts 文件中的每条记录的第一个主机名是全名或者非全，以适合于本地安装。)multi：有效的值为: on 和 off。如果设置为 on，resolv+ 库会返回一台主机在 /etc/hosts 文件中出现的所有有效地址，而不只是第一个。这个标志对 DNS 或 NIS 请求是没有作用的。nospoof：有效的值为：on 和 off。如果设置为 on，resolv+ 库会尝试阻止主机名欺骗以提高使用 rlogin 和 rsh 的安全性。它是如下这样工作的：DNS 通过使用 in-addr.arpa 域，允许你找到属于一个IP地址的主机名。名字服务器提供一个假主机名的企图被称为“哄骗（ spoofing ）”。为了防止这个做法，解析器在执行了一个主机地址的查询之后，resolv+ 会对该地址执行一次主机名的查询。如果两者不匹配，查询即失败。spoofalert：如果该选项设为 on 同时也设置了 nospoof 选项，resolv+ 会通过 syslog 设施记录错误报警信息。reorder：有效的值为：on 和 off。如果设置为 on, resolv+ 会试图重新排列主机地址，以便执行 gethostbyname(3) 时，首先列出本地地址（即在同一子网中的地址）。重新排序适合于所有查询方式。[root@localhost ~]# cat /etc/host.conf multi on [root@localhost ~]# ifcfg-xxxx 文件这个里面的文件就比较特殊，它存放的是网卡配置相关的文件。例如众所周知的 ifcfg-eth0，则默认表示第一个网卡。以 ifcfg-eth0 文件配置为例，它存放了网卡的相关行为信息，除了可以设置网卡的 IP 信息外，还能设置 DNS 服务器，如下所示：…… DEVICE="eth0" ONBOOT="yes" IPADDR="192.168.0.189" PREFIX="24" GATEWAY="192.168.0.1" DNS1="119.29.29.29" DNS2="223.5.5.5" ……网卡的配置，也间接影响了 /etc/resolv.conf 文件，当在 eth接口 启用 DHCP 后，本地 /etc/resolv.conf 文件将被修改，此时 /etc/resolv.conf 文件中的 DNS 地址将被改为从 DHCP 获取到的地址。这种从 DHCP 获得的 DNS 又称 Peer DNS。即使这个时候你修改了 /etc/resolv.conf 文件中的 nameserver 字段，可能在下次网络重启就又恢复成了原样。这也说明了上述在介绍 /etc/resolv.conf 文件时的结尾处，Red Hat中没有提供缺省的 /etc/resolv.conf 文件，它的内容是在系统安装时根据网卡的配置动态创建的。也就是在系统安装过程中，若你的网络启用的为 DHCP（默认），那么 /etc/resolv.conf 文件中的 nameserver 即 DHCP 提供的 DNS 地址；若你使用静态的 IP 地址，那么此时则需要配置 DNS 解析地址，这时候配置的 DNS 解析地址就会被写入到 /etc/resolv.conf 文件的 nameserver 字段中，配置了多少个 DNS 就有多少个 nameserver。这儿若使用 DHCP 服务，且不让 /etc/resolv.conf 文件中自定义的 nameserver 字段恢复默认，可在网卡配置文件中增加一条 PEERDNS=no 参数，然后重启网络即可。nsswitch.conf 与 host.conf 区别根据上述相关文件的介绍，我们可以看出 /etc/nsswitch.conf 与 /etc/host.conf 文件在域解析过程中都存在可以指定解析顺序方式，若两者指定的解析顺序不同，系统又如何去解析域呢？或者系统该使用哪个文件去解析域呢？其实，在有关 /etc/host.conf 的帮助文档中也说明了，/etc/nsswitch.conf 是控制主机查找顺序的现代方式。如下图：同时，若 host.conf 配置了 order 行字段，那么该 order 行仅由旧版本的 C 库使用，且现在的主流 Linux 上，host.conf 的配置也基本为 multi on 字段。在域解析的过程中，Linux 上并没有一个单独的方法去完成域查询工作，没有一个有这样的明确接口的核心，即 Linux 并没有名为“DNS 查询”的系统调用，那么 Linux 系统又是如何完成域解析的？Linux 处理域解析在 Linux 系统中，绝大多数程序依赖系统库函数来完成域解析，整个解析过程包含多个操作，有些操作信息在启动程序时确定，有些操作信息则在程序运行时确认，Linux 也提供了一些网络函数（由 glibc 提供）来控制这些操作，下图所示为一个比较典型的应用程序，域名解析及域名服务器之间的关系图：程序在运行后通过 glibc 提供的网络函数（ gethostbyname，getaddrinfo 等）来调用解析器（ resolver code，比如 nsswitch 等）, 解析器则读取一些配置文件（比如 /etc/nsswitch.conf，/etc/hosts，/etc/resolv.conf）来决定使用什么域名服务器（nameserver）以什么选项（超时时间，重试次数），什么优先级（先 hosts 还是先 dns）对指定的域名进行处理。当然也可以使用 dns 缓存类的工具加速请求的处理，这些工具可以是 bind（当缓存用），nscd（由 glibc 提供），systemd-resolved（由 systemd 提供）。函数说明glibc 的解析器(revolver code) 提供了 gethostbyname 和 getaddrinfo 两个函数实现域名称到 IP 地址的解析。gethostbyname 函数以同步阻塞的方式提供服务，没有超时等选项，仅提供 IPv4 的解析。getaddrinfo 则没有这些限制，同时支持 IPv4、IPv6，也支持 IPv4 到 IPv6 的映射选项。包含 Linux 在内的很多系统都已废弃 gethostbyname 函数，使用 getaddrinfo 函数代替，但也不是所有程序或应用都使用该函数！在 Linux 手册中，对上述两个函数进行查找发现，gethostbyname 函数会依赖 nsswitch.conf 文件（不是使用了这个文件就是该函数在使用），如下图：而 getaddrinfo 函数说明如下：下面通过常用的两个网络命令来对自己的域解析一下：Ping：[root@localhost ~]# ping -c 1 www.isisy.com PING nm.aicdn.com (36.248.208.247) 56(84) bytes of data. 64 bytes from 36.248.208.247 (36.248.208.247): icmp_seq=1 ttl=128 time=24.9 ms --- nm.aicdn.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 24.945/24.945/24.945/0.000 ms [root@localhost ~]# host：[root@localhost ~]# host www.isisy.com www.isisy.com is an alias for blog-yjs.b0.aicdn.com. blog-yjs.b0.aicdn.com is an alias for nm.aicdn.com. nm.aicdn.com has address 36.248.208.247 [root@localhost ~]# 由上可见，对于同一个域名，两个命令得到的 IP 地址是相同的；那么它们是使用同样的方式得到结果吗？调用跟踪上述两个不同的命令得到的 IP 是相同的，此处可能会认为他们是通过相同的方法得到的 IP，然而事实却并非如此，例如我们使用 strace 命令跟踪一下这两个命令的系统调用，先来看下 ping 命令的 DNS 相关的系统调用：[root@localhost ~]# strace -e trace=open -f ping -c 1 www.isisy.com open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libcrypto.so.10", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/etc/pki/tls/legacy-settings", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3 open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 4 open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 4 open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 4 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libnss_files.so.2", O_RDONLY|O_CLOEXEC) = 4 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4 PING nm.aicdn.com (36.248.208.247) 56(84) bytes of data. open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libnss_myhostname.so.2", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/librt.so.1", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libdw.so.1", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 4 open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 4 open("/usr/lib64/elfutils/tls/x86_64/libelf.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib64/elfutils/tls/libelf.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib64/elfutils/x86_64/libelf.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib64/elfutils/libelf.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libelf.so.1", O_RDONLY|O_CLOEXEC) = 4 open("/usr/lib64/elfutils/liblzma.so.5", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 4 open("/usr/lib64/elfutils/libbz2.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libbz2.so.1", O_RDONLY|O_CLOEXEC) = 4 64 bytes from 36.248.208.247 (36.248.208.247): icmp_seq=1 ttl=128 time=23.3 ms --- nm.aicdn.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 23.329/23.329/23.329/0.000 ms +++ exited with 0 +++ [root@localhost ~]# 可以看到整个过程依次调用了 libresolv 等动态库，再访问 nsswitch.conf 以确定解析是先访问 hosts 文件还是先通过 dns server。而 host.conf 包含解析器的配置，系统中默认为 multi on，表示 libresolv 会返回解析到的所有 IP（单域名可能对应多条 A 记录）。resolv.conf 包含指定的 nameserver，解析器会连接这些 nameserver 获取域名对应的 A 记录。后面的 /etc/hosts 和 /lib64/libnss_dns.so 则表示先访问 hosts 文件，然后再发起 DNS 到 nameserver 的请求。如果我们绑定了域名到 /etc/hosts，则会忽略 /lib64/libnss_dns.so 的步骤；如果 nsswitch.conf 中 DNS 优先，则先通过 /lib64/libnss_dns.so 来请求，找到记录则忽略 /etc/hosts 步骤。由上面的 open("/lib64/libnss_dns.so.2", O_RDONLY|O_CLOEXEC) = 4 下面的一行给出了 PING 结果可知，最终是通过连接 resolv.conf 指定的 dns server 获取到了域名对应的 A 记录 36.248.2xx.xx7，接下来程序再通过该 A 记录再发起进行功能性的操作请求。综上，由此可知 ping 命令是通过配置文件 /etc/nsswitch.conf 的相关指定来完成选择。那么 host 命令也是如此吗？下面我们依旧来跟踪一下看看：[root@localhost ~]# strace -e trace=open -f host www.isisy.com open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/tls/x86_64/libdns.so.1102", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/tls/libdns.so.1102", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/x86_64/libdns.so.1102", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libdns.so.1102", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/tls/liblwres.so.160", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/liblwres.so.160", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/tls/libbind9.so.160", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libbind9.so.160", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/tls/libisccfg.so.160", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libisccfg.so.160", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/tls/libisc.so.169", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib64/libisc.so.169", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libgssapi_krb5.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libkrb5.so.3", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libk5crypto.so.3", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libcom_err.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libcrypto.so.10", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libidn.so.11", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libcap.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libGeoIP.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libxml2.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libz.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libkrb5support.so.0", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libkeyutils.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libattr.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/liblzma.so.5", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libselinux.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libpcre.so.1", O_RDONLY|O_CLOEXEC) = 3 open("/proc/filesystems", O_RDONLY) = 3 open("/etc/pki/tls/legacy-settings", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US.UTF-8/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/libdns.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US.UTF-8/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory) open("/usr/share/locale/en/LC_MESSAGES/libisc.cat", O_RDONLY) = -1 ENOENT (No such file or directory) strace: Process 8474 attached [pid 8473] open("/proc/self/task/8474/comm", O_RDWR) = 3 strace: Process 8475 attached [pid 8473] open("/proc/self/task/8475/comm", O_RDWR) = 3 strace: Process 8476 attached [pid 8473] open("/proc/self/task/8476/comm", O_RDWR) = 6 [pid 8473] open("/usr/share/locale/en_US.UTF-8/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8473] open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8473] open("/usr/share/locale/en/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8473] open("/usr/share/locale/en/LC_MESSAGES/libdst.cat", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8473] open("/etc/pki/tls/openssl.cnf", O_RDONLY) = 6 [pid 8473] open("/etc/resolv.conf", O_RDONLY) = 6 [pid 8473] open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 6 [pid 8474] open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = 7 [pid 8474] open("/usr/share/locale/en_US.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8474] open("/usr/share/locale/en_US.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8474] open("/usr/share/locale/en_US/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8474] open("/usr/share/locale/en.UTF-8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8474] open("/usr/share/locale/en.utf8/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) [pid 8474] open("/usr/share/locale/en/LC_MESSAGES/libc.mo", O_RDONLY) = -1 ENOENT (No such file or directory) www.isisy.com is an alias for blog-yjs.b0.aicdn.com. blog-yjs.b0.aicdn.com is an alias for nm.aicdn.com. nm.aicdn.com has address 36.248.208.247 [pid 8473] --- SIGTERM {si_signo=SIGTERM, si_code=SI_TKILL, si_pid=8473, si_uid=0} --- [pid 8474] +++ exited with 0 +++ [pid 8476] +++ exited with 0 +++ [pid 8475] +++ exited with 0 +++ +++ exited with 0 +++ [root@localhost ~]# 这个过程和上述的 ping 命令又不相同了，可见它一开始依次调用了 libdns.so、libbind9.so 等库，但是该命令的调用过程中并没有去访问 nsswitch.conf，而是去访问 resolv.conf 以确定解析，最终通过 resolv.conf 包含指定的 nameserver 完成获取域名对应的 A 记录并进行接下来的功能性操作。可见 host 命令是通过配置文件 /etc/resolv.conf 的指定来完成相关选择。而上述在 /etc/nsswitch.conf 配置文件介绍中说明的 DNS 查找指令（nglookup 和 dig）将忽略 /etc/nsswitch.conf 文件，并始终使用 /etc/resolv.conf 引用 DNS 服务器，也即是该情况。此处若有兴趣的话，读者可自主跟踪下这些命令的调用观察一下。对比修改 .conf 文件由于上述两个命令的跟踪调用过程中都使用到了 /etc/resolv.conf 文件，ping 命令使用到了 /etc/nsswitch.conf 文件，那么我们对这两个文件进行修改来对比操作。修改 nsswitch.conf，hosts 行仅保留 files[root@localhost ~]# vim /etc/nsswitch [root@localhost ~]# cat /etc/nsswitch.conf …… hosts: files …… [root@localhost ~]#此时我们使用两个命令观察一下结果：Ping：[root@localhost ~]# ping -c 1 www.isisy.com ping: www.isisy.com: Name or service not known [root@localhost ~]# [root@localhost ~]# ping -c 1 localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.024 ms --- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.024/0.024/0.024/0.000 ms [root@localhost ~]# host[root@localhost ~]# host www.isisy.com www.isisy.com is an alias for blog-yjs.b0.aicdn.com. blog-yjs.b0.aicdn.com is an alias for nm.aicdn.com. nm.aicdn.com has address 36.248.208.247 [root@localhost ~]# 此时， ping 无法获取 www.isisy.com 对应的 IP 地址，但 localhost 的解析不受影响；此外，host 命令则是正常返回，这也和上述所分析，host 命令不受 nsswitch.conf 影响。修改 nsswitch.conf，hosts 行仅保留 dns[root@localhost ~]# vim /etc/nsswitch [root@localhost ~]# cat /etc/nsswitch.conf …… hosts: dns …… [root@localhost ~]#此时我们使用两个命令观察一下结果：Ping[root@localhost ~]# ping -c 1 www.isisy.com PING nm.aicdn.com (36.248.208.247) 56(84) bytes of data. 64 bytes from 36.248.208.247 (36.248.208.247): icmp_seq=1 ttl=128 time=24.1 ms --- nm.aicdn.com ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 24.155/24.155/24.155/0.000 ms [root@localhost ~]# [root@localhost ~]# ping -c 1 localhost ping: localhost: Name or service not known [root@localhost ~]# host[root@localhost ~]# host www.isisy.com www.isisy.com is an alias for blog-yjs.b0.aicdn.com. blog-yjs.b0.aicdn.com is an alias for nm.aicdn.com. nm.aicdn.com has address 36.248.208.247 [root@localhost ~]# 此时， ping 无法获取 localhost 对应的 IP 地址，但 www.isisy.com 的解析不受影响；此外，host 命令则还是正常返回。此时，我们将 /etc/nsswitch.conf 文件恢复成默认状态，对 /etc/resolv.conf 文件进行修改。修改 resolv.conf，删除所有 nameserver[root@localhost ~]# vim /etc/resolv.conf [root@localhost ~]# cat /etc/resolv.conf # Generated by NetworkManager #nameserver 223.5.5.5 #nameserver 119.29.29.29 [root@localhost ~]# 此时我们使用两个命令观察一下结果：Ping：[root@localhost ~]# ping -c 1 www.isisy.com ping: www.isisy.com: Name or service not known [root@localhost ~]# [root@localhost ~]# ping -c 1 localhost PING localhost (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.021 ms --- localhost ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.021/0.021/0.021/0.000 ms [root@localhost ~]# host：[root@localhost ~]# host www.isisy.com ;; connection timed out; no servers could be reached [root@localhost ~]# 此时，ping 命令无法获取 www.isisy.com 的 IP，但 localhost 的解析依旧不受影响；反观 host 命令，则无法获取 www.isisy.com 的 IP 了。总结由上述相关文件介绍以及 Ping 命令和 host 命令的跟踪调用，说明 Linux 系统中并不存在“DNS 查询”这个系统调用，而是依赖系统库函数来完成解析，且不同程序可能采用不同的策略获取域对应的 IP 地址，例如 ping 使用了 nsswitch，host使用 /etc/resolv.conf 得到解析结果，且绝大部分程序都依赖并使用到了 /etc/resolv.conf 文件。下面对 NSSwitch 中 hosts 行对应的查询逻辑总结如图：参考文章Linux DNS 查询剖析（第一部分）linux-系统如何处理名称解析nsswitch.conf versus host.confgethostbyname(3) — Linux manual pagegetaddrinfo(3) — Linux manual page以及 Linux 相关文献，Red hat 相关文献和互联网其它资源借鉴。
今天日常打开博客，突然发现博客已经打开了，但是浏览器上的小圈圈仍在转，仍然有东西在加载，过了几十秒才停，这时候就有了个大大的问号，是什么资源这么严重拖慢了我的访问呢？于是按下F12打开调试窗口，发现是gravatar头像链接请求失败了，如图：而我的博客也设置了该镜像源地址为https://secure.gravatar.com/avatar或https://cdn.v2ex.com/gravatar，这两者镜像源在国内访问延时不仅普遍较高，甚至有时候会出现访问失败的情况。于是本文带大家使用自建CDN来加速你的Gravatar头像。注：本文使用的博客站点为Typecho，模板为Handsome。什么是Gravatar头像Gravatar 是Globally Recognized Avatar的缩写，意为 “全球通用头像”。如果在 Gravatar 的服务器上放置了你自己的头像，那么在任何支持 Gravatar 的 blog 或者留言本上留言时，只要提供你与这个头像关联的 email 地址，就能够显示出你的 Gravatar 头像。自建CDN加速Gravatar头像本文使用的CDN服务提供商为又拍云，下面教程开始1、首先进入又拍云 cdn 创建服务，服务名称随意，加速地址填写你想要加速的域名，源站地址填写secure.gravatar.com, 端口号填443。如图：2、创建完成后在域名解析处添加一条 cname 解析地址3、申请域名证书，绑定域名证书（这一步必须要做，否则浏览器会判定不安全）4、缓存控制中添加一条缓存规则，天数自定义。开启智能压缩以及webp自适应为可选开启，其他可无需设置。5、直接进入Handsome模板后台，在速度优化里设置 Gravatar 镜像源地址，将前面部分填写你自己的加速域名即可(后缀最好根据你加速的域名填写一致)若您的模板不是Handsome且后台不能设置，但博客系统为Typecho，也可在站点目录下找到config.inc.php配置文件，将以下代码加到文件末尾即可。（镜像源地址替换成自己的）/** 定义Gravatar头像源 */ define('__TYPECHO_GRAVATAR_PREFIX__', 'https://您的加速域名/avatar/');6、清除浏览器缓存并刷新下网页，此时自己配置的源加速处理Gravatar头像了小科普：此处采用CDN内容分发，第一次请求还是要回源访问，然后资源才会缓存到您的CDN节点上，当您下次访问相同资源时就会直接从您的CDN节点拿取，在一定意义上是解决了一点访问速度不理想与部分地域访问资源慢情况，但在回源途中若源站访问异常慢的话，那么您还是需要等待较长的时间去等待资源获取（在实际体验中该两处源站有时候访问速度也确实并不理想），故再次建议将CDN缓存时间设置的尽量久一些，减少频繁回源。
AI 摘要（由 ChatGPT 总结生成）：文章讲解了在PHP配置中，特别是`php.ini`中的`cgi.fix_pathinfo`参数对网站访问权限的影响。当将该参数设置为0时，可能导致网站出现Access denied错误。文章提到了该参数与`$SERVER['PATH_INFO']`的获取相关，以及`PATH_INFO`在CGI服务器中传递参数的作用。在Nginx中，默认不设置`PATH_INFO`，需要通过正则匹配设置`SCRIPT_FILENAME`，但这可能带来安全隐患，因此建议将`cgi.fix_pathinfo`设置为0。文章还给出了在Nginx中配置`cgi.fix_pathinfo=0`的解决方法，包括修改`location`配置以支持pathinfo。最后，强调了将`cgi.fix_pathinfo`设置为0的作用，即禁止解析非法PHP文件，以增强网站安全性。今天在进行PHP相关参数配置优化时，将cgi.fix_pathinfo=0后网站出现的Access denied字样及排解方法。参数说明PHP里经常要获取当前请求的URL路径信息。一般可以通过环境变量$SERVER[‘PATH_INFO’]获取，而配置文件中的cgi.fix_pathinifo选项则与这个值的获取相关。而$SERVER[‘PATH_INFO’]中的key PATH_INFO是一个CGI 1.1的标准，经常用来做为传递参数给后端的CGI服务器。 PHP的以前的行为是将PATH_TRANSLATED设置为SCRIPT_FILENAME，并且不要弄清PATH_INFO是什么。设置cgi.fix_pathinfo=1后，cgi设置完整的路径信息PATH_TRANSLATED的值为SCRIPT_FILENAME，并且设置PATH_INFO信息；如果设为cgi.fix_pathinfo=0则只设置绝对路径PATH_TRANSLATED的值为SCRIPT_FILENAME。在php.ini文件中cgi.fix_pathinfo的默认值是1。Nginx默认是不会设置PATH_INFO环境变量的的值，需要通过正则匹配设置SCRIPT_FILENAME，但这样会带来安全隐患，需要把cgi.fix_pathinfo设置为0。但是一旦关闭这个选项，PHP就获取不到PATH_INFO信息，那些依赖PATH_INFO的程序就失效了，甚至网站也会出现Access denied字样，如下：[root@localhost ~]# curl -i http://192.168.17.130:8090/7.html HTTP/1.1 403 Forbidden Server: nginx/1.19.6 Date: Wed, 24 Feb 2021 12:16:30 GMT Content-Type: text/html; charset=UTF-8 Transfer-Encoding: chunked Connection: keep-alive Vary: Accept-Encoding Access denied. [root@localhost ~]# 可造成的危害我们配置php时将cgi.fix_pathinfo参数设置为0的主要作用是禁止解析非法php文件，如/a.jpg/1.php这样的图片下的一个php文件属于非法的，设置为0就是禁止执行。这种将木马伪装成图片上传的文件攻击方式存在已久，禁止这类文件运行，即使被上传了文件木马，由于设置了不允许运行，所以就没有用了。关于该安全隐患的问题，可参考这篇文章：https://www.laruence.com/2010/05/20/1495.htmlNginx支持pathinfo实现在将cgi.fix_pathinfo参数设置为0后，为解决网站正常运作而不出现Access denied的问题，遂就在网上查阅了大量资料并结合自己所测试，现给出如下的nginx解析php的代码location ~ [^/]\.php(/|$) { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; #增加 fastcgi_split_path_info指令，将URI匹配成PHP脚本的URI和pathinfo两个变量 #即$fastcgi_script_name 和$fastcgi_path_info fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; # 正则解析路径，使用set指令产生nginx变量并赋值 set $real_script_name $fastcgi_script_name; # 正则匹配URI，若能匹配将产生两个子组 if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { #将两个子组赋值给刚生成的nginx变量 set $real_script_name $1; set $path_info $2; } # 将可能匹配到的$path_info值通过fastcgi_param指令设置进去 fastcgi_param PATH_INFO $path_info; # 覆盖fastcgi_params文件中默认的SCRIPT_NAME配置项 fastcgi_param SCRIPT_NAME $real_script_name; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; # 加载默认的fastcgi配置项 include fastcgi_params; }这样cgi.fix_pathinfo参数为0也可以正常解析了，此处建议在cgi.fix_pathinfo=1时可将上述参数fastcgi_split_path_info ^(.+?\.php)(/.*)$;和fastcgi_param PATH_INFO $fastcgi_path_info;将其注释，保留其它即可，可能此处也有自己理解错误的地方，若有错误，还望各位大佬指正！
作为一个站长，有时候给网站弄一份SSL证书是有必要的。目前阿里云、腾讯云、又拍云等都可以申请免费的SSL证书，给你的网站使用https加密协议，其中可以申请免费的证书主要有看个渠道，一个是TrustAsia、一个是Let's enercy。TrustAsia申请的免费证书为单域名证书，而Let's enercy不仅可以申请单域名证书，也可以申请通配符证书。本教程就教大家如何使用Let's enercy申请通配符证书，此方法也同样适用单域名证书的申请。KeyManager下载由于申请证书过程中会使用KeyManager软件，本文以windows申请证书，去官网下载对应的windows版本。KeyManager下载地址：https://keymanager.org下载后将软件安装并设置一个进入密码，密码设置成功后会生成一个访问秘钥，请务必将此访问秘钥保存好，此访问秘钥是你遗忘密码后找回密码的关键！申请教程1、本教程以博客域名申请泛域名证书教程，打开https://freessl.cn，在输入框中填写你要申请的单域名，或者泛域名的域名，若你申请的单域名证书，只需要填写你的申请证书的对应域名，泛域名则在该域名前加上*.即可。如图所示：2、点击“创建免费的证书”，这儿就应用默认的即可，输入邮箱后点击创建。3、此时会打开KeyManager软件并生成一份CSR文件，此时我们返回浏览器继续操作。这时候就会要求我们验证DNS，即验证域名的所有权4、前往你的域名提供商处，将TXT记录和记录值填写在你的域名底下5、添加成功后返回，等待几分钟后即可，此时点击一下下方的验证，等得TXT记录验证成功后即可颁发证书。然后我们点击保存到KeyManager，此时将会见你申请的证书保存到KeyManager中托管到此你的泛域名证书即申请成功，你可以在KeyManager中将其导出，用于部署你的网站，使得你的网站也拥有https协议。在证书申请成功之后，你可以前往将用于验证域名所有权的TXT记录值删除。
查看打包成exe程序的批处理并提取代码
今天找批处理（.bat）打包成exe的更好地工具，结果误打误撞找到了查看打包成exe程序的批处理并提取代码教程，测试后发现确实可以查看到打包成exe的批处理代码。本文就给大家分享一下该教程。首先我们先运行一下exe程序，判断一下是否是类批处理程序，基本看窗口是不是批处理窗口就行了，黑乎乎的DOS界面框基本可以确定了。打包成exe程序的批处理脚本，通常在运行的时候会在临时目录释放bat批处理文件。我们只需要找到释放时候的对应文件即可。下面教程开始：1、打开CMD，输入cd %temp% 切换到临时文件存储目录，先打上代码dir /a /s *.bat2、接下来运行该exe程序，然后切换到cmd 按回车 这个时候就会扫描临时目录下释放的bat程序，得到文件名（如果搜索不到可以改下后缀可能是.cmd的后缀）3、打开对应的文件目录，即可得到临时目录下释放的bat批处理文件了。
现在使用智能手机的人越来越多了。众多的手机及平板厂商为了争取市场份额纷纷刷新着智能手机的硬件配置，而在众多参数中RAM和ROM这两个就是重要参数之一。RAM、ROM 一直是困扰不少用户的两个概念。很多手机用户不知道 RAM 和 ROM 到底有什么区别，今天博主告诉您有何区别。RAM和ROM是什么？RAM是什么？RAM全称“Random Access Memory”即随机存储器，也就是所说的运行内存，在手机里，它支撑的是手机软件的运行，存放手机软件运行后进行的数据交换等工作，作用就好比我们在算数学题的时候，需要一个草稿纸来记下我们计算的每一个步骤，而手机或平板电脑中的RAM也是这样的，现在智能手机、平板电脑越来越强大了，其配置基本上可以说就是一台超便携电脑，手机、平板电脑的计算任务也多了所以它也需要“打草稿”，这个“草稿纸”的大小决定了你能打多少草稿。而草稿打完了那面纸就没用了，或者可以擦去。而RAM也是这样关机后RAM芯片没电了里面的内容也会自动丢失。所以将其称为随机存储器。RAM是不能保存数据的，因为断电后里面就空白了，即使开机也无法恢复。ROM是什么？ROM全称是“Read-Only Memory”即只读存储器，我们通过这么名字就可以发现它与RAM的区别了。只读存储器意味着里面的数据是只可读取而不让写入的。当然，虽然说ROM是只读的，但是我们可以通过大家所说的“刷机、刷ROM”来修改ROM里面的数据。我们的智能手机以及平板电脑里面的储操作系统以及随机软件都存储在ROM当中，ROM的作用我们可以看做是大家电脑里面操作系统盘（比如C盘）。因为ROM是只读的，所以我们无法删除里面的软件也无法对系统进行修改，这在一定程度上保证了系统的安全。那么，为什么现在我们可以在里面存储照片呢？其实，现在ROM的概念也包含了可以“写”（删除、修改文件）的概念，因为随着技术的发展延伸出了很多种类的ROM,后来出现的一些ROM是可擦除的，如EPROM、EEPROM。在电脑上，电脑的硬盘如果是机械硬盘HDD的话不是ROM,它属于外部存储器，但是现在的固态硬盘SSD使用的闪存技术其实是从EEPROM的基础上改进而来的,广义上来说属于ROM。在安卓系统中，ROM包含了一部分手机系统占据的空间，剩余的空间您就可以用来存储您的视频、照片、音乐等，并且可以随意删除和修改。RAM和ROM在安卓手机中，ROM包含了安卓系统、手机软件、用户文件（照片、视频等）。而用户存储的文件只占据ROM空间，是不影响RAM空间的。其次，ROM空间的大小对系统运行速度的影响是微乎其微的；影响手机运行速度的最主要因素是RAM，所以，RAM越大，手机运行的应用程序就越多（包括前台和后台），应用之间的切换也就更顺畅，使用者的体验感就越好。同理电脑也是如此，不过如今电脑上有设虚拟内存，用于临时在ROM中缓存部分数据，需要时会同内存交换或被读取，因此电脑最好在系统盘ROM预留电脑内存大小的1.5倍~3倍即可。
http是什么？https又是什么？对于http相信大家很不陌生，在接触网络的时候就知道一个完整的网站地址就是http://www.xxx.com，但有时我们也会发现有的网站是https://www.xxx.com，对此可能有所疑问，这两种类型的网站有什么区别吗？同时你也会发现大多数的网站网址为http类型，这又是为什么？今天博主就给大家介绍一下。1、基本概念HTTP：超文本传输协议（HyperText Transfer Protocol）。是互联网上应用最为广泛的一种网络协议，所有的www文件都必须遵守这个标准。是一个客户端和服务器端请求和应答的标准（TCP），用于从www服务器传输超文本到本地浏览器的传输协议，它可以使浏览器更加高效，使网络传输减少。它不仅保证计算机正确快速地传输超文本文档，还确定传输文档中的哪一部分，以及哪部分内容首先显示（如文本先于图形）等。HTTPS：安全套接字层超文本传输协议（Hyper Text Transfer Protocol over Secure Socket Layer），是以安全为目标的HTTP通道，简单讲是HTTP的安全版，即HTTP下加入SSL层，HTTPS的安全基础是SSL，因此加密的详细内容就需要SSL。HTTPS协议的主要作用可以分为两种：一是建立一个信息安全通道，来保证数据传输的安全;另一种就是确认网站的真实性。2、具体区别HTTP协议传输的数据都是未加密的，也就是明文的，因此运用HTTP协议传输隐私信息非常不安全，为了保证这些隐私数据能加密传输，于是网景公司规划了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密，从而就诞生了HTTPS。简单来说，HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议，要比http协议更加的安全。HTTPS和HTTP的区别主要如下： 1、https协议需要到CA申请证书，一般免费证书较少，因而需要一定费用。 2、http是超文本传输协议，信息是明文传输，https则是具有安全性的ssl加密传输协议，信息是密文传输。 3、http和https用的端口不一样，前者是80，后者是443。 4、http的连接很简单，是无状态的，https协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议，比http协议安全。3、https的工作原理我们都知道HTTPS能够加密信息，以免敏感信息被第三方获取，所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。HTTPS在连接时，服务器要求有公钥和签名的证书。使用HTTPS连接，服务器响应初始连接，并提供它所支持的加密方法，作为回应，客户端选择一个连接方法，并且客户端和服务器端交换证书验证彼此身份，完成后在确保使用相同密钥的情况下传输加密信息，然后关闭连接，为了提供HTTPS连接支持，服务器必须有一个公钥证书，该证书包含经过证书机构认证的密钥信息，大部分证书都是通过第三方机构授权的以保证证书是安全的。HTTPS其实具体工作跟HTTP一样，只不过增加了SSL。1、HTTP包含如下动作：（1）浏览器打开一个TCP连接（2）浏览器发送HTTP请求到服务器端（3）服务器发送HTTP回应信息到浏览器（4）TCP连接关闭2、SSL包含如下动作：（1）验证服务器端；（2）允许客户端和服务器端选择加密算法和密码，确保双方都支持（3）验证客户端（可选）（4）使用公钥加密技术来生成共享加密数据（5）创建一个加密的SSL连接（6）基于该SSL连接传递HTTP请求4、https加密传输密文过程1、客户端发起HTTPS请求用户在浏览器里输入一个https网址，然后连接到server的443端口2、服务端的配置采用HTTPS协议的服务器必须要有一套数字证书，可以自己制作，也可以向组织申请，区别就是自己颁发的证书需要客户端验证通过，才可以继续访问，而使用受信任的公司申请的证书则不会弹出提示页面。这套证书其实就是一对公钥和私钥，如果你对公钥和私钥不太理解，可以想象成一把钥匙和一个带有锁头的盒子，只是全世界只有你一个人有这把钥匙，你可以把带有锁头的盒子给别人，别人可以用这个锁把重要的东西放进盒子里锁起来，然后发给你，因为只有你一个人有这把钥匙，所以只有你才能看到被锁起来的盒子里面的东西。3、传送证书这个证书其实就是公钥，只是包含了很多信息，如证书的颁发机构，过期时间等等。4、客户端解析证书这部分工作是有客户端的TLS来完成的，首先会验证公钥是否有效，比如颁发机构，过期时间等等，如果发现异常，则会弹出一个警告框，提示证书存在问题。如果证书没有问题，那么就生成一个随机值，然后用证书对该随机值进行加密，就好像上面说的，把随机值用锁锁起来，这样除非有钥匙，不然看不到被锁住的内容。5、传送加密信息这部分传送的是用证书加密后的随机值，目的就是让服务端得到这个随机值，以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。6、服务端解密信息服务端用私钥解密后，得到了客户端传过来的随机值(私钥)，然后把内容通过该值进行对称加密，所谓对称加密就是，将信息和私钥通过某种算法混合在一起，这样除非知道私钥，不然无法获取内容，而正好客户端和服务端都知道这个私钥，所以只要加密算法够强，私钥够复杂，数据就够安全。7、传输加密后的信息这部分信息是服务段用私钥加密后的信息，可以在客户端被还原。8、客户端解密信息客户端用之前生成的私钥解密服务段传过来的信息，于是获取了解密后的内容，整个过程第三方即使监听到了数据，也束手无策。5、https的优缺点优点：（1）使用HTTPS协议可认证用户和服务器，确保数据发送到正确的客户机和服务器；（2）HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议，要比http协议安全，可防止数据在传输过程中不被窃取、改变，确保数据的完整性。（3）HTTPS是现行架构下最安全的解决方案，虽然不是绝对安全，但它大幅增加了中间人攻击的成本。（4）谷歌曾在2014年8月份调整搜索引擎算法，并称“比起同等HTTP网站，采用HTTPS加密的网站在搜索结果中的排名将会更高”。缺点：（1）HTTPS协议握手阶段比较费时，会使页面的加载时间延长近50%，增加10%到20%的耗电；（2）HTTPS连接缓存不如HTTP高效，会增加数据开销和功耗，甚至已有的安全措施也会因此而受到影响；（3）SSL证书需要钱，功能越强大的证书费用越高，个人网站、小网站没有必要一般不会用。（4）HTTPS协议的加密范围也比较有限，在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的，SSL证书的信用链体系并不是绝对的安全，特别是在有些国家可以控制CA根证书的情况下，中间人攻击一样可行。
很多小伙伴在搞机的过程中可能经常会听到BL锁，大多数可能都知道怎样解BL锁来娱乐的搞机。但是我相信很多小伙伴不清楚为啥要解BL锁，不解以及解了会有啥影响。所以呢，本文就给大家科普下BL锁。什么是BL锁？BL锁全称为Bootloader锁，其中Bootloader中文名称为“启动加载”。在嵌入式操作系统中，BootLoader是在操作系统内核运行之前运行，它可以初始化硬件设备、建立内存空间映射图，从而将系统的软硬件环境带到一个合适状态，为运行操作系统做好准备，以便为最终调用操作系统内核准备好正确的环境。这样描述是比较抽象的，但是它的任务确实不多，终极目标就是把操作系统拉起来运行。在嵌入式系统中，通常并没有像BIOS那样的固件程序（注，有的嵌入式CPU也会内嵌一段短小的启动程序），因此整个系统的加载启动任务就完全由BootLoader来完成。对于ARM处理器的实际硬件系统（手机处理器架构大多基于ARM架构），系统在上电或复位时，通常都从并口NAND Flash 芯片中的0x00000000地址处开始执行，而在这个地址处安排的通常就是系统的BootLoader程序。再简单点来说就类似于电脑上的引导程序。Bootloader从字面上来看就是启动加载的意思。了解电脑的都知道，Windows在开机时会首先加载Bios，然后是系统内核，最后启动完毕。那么Bootloader就相当于电脑的Bios，它在手机启动的时候根据基带初始化硬件，然后引导系统内核，直到系统启动。手机上的Bootloader锁归根结底就是限制用户刷第三方ROM和第三方Recovery以及限制Root的“锁”（也并不是所有的手机Root都需要解BL锁，例如提权漏洞）。举个例子：如果一部手机上了BootLoader锁，就不能使用Recovery刷第三方rom包（每个刷机包都有签名，官方rec只会识别官方的刷机包），官方自带的Recovery也不允许用户刷入第三方rom包，需将BootLoader解了并用第三方Recovery替换官方Recovery才行。所以一般来说手机厂商都会给自己的手机加上这个所谓的BL锁，防止因为刷机不当而导致手机损坏。归根结底BL锁就是锁住手机的Recovery和Fastboot，防止刷入非官方签名的系统而损坏手机的一个保护机制（同时也为用户资料提供了一定的保护）。故现在的手机商家都会给自家的手机系统上一道BL锁并逐步停止解锁服务，例如华为在2018年6月就宣布关闭BL解锁码的申请通道，在此之前，也有一些厂商就关闭了BL锁解锁通道，这也使得现在手机获取Root或使用第三方Rom更加困难，那么解锁BootLoader有什么利弊呢？BL锁作用作用：1.对于一般用户，Bootloader锁定根本没有影响。2.对于简单刷机来说，Bootloader锁定可以大大减小手机变砖（即手机无法开机）的几率。3.保护手机厂商的利益，因为你一旦解锁就没保修了嘛。4.防止JS肆意篡改手机信息的作用。5.保护手机里的个人资料。6.保障了手机定位查找功能。解锁的好处：1.大量的第三方ROM支持。2.更高质量的民间系统优化。3.在新系统出来时ROOT更方便。4.强大的扩展性。5.可以自由调度精简系统。6.获取Root后可玩更多“不可思议”的操作。总结1.BL锁就是锁住Recovery和Fastboot以及保护用户隐私的一道锁。2.解BL锁现一般会用官方解锁工具，而且有可能会丧失保修。3.解BL锁的好处要小于所带来的坏处（深度搞机的玩家可以忽略该点）。4.普通用户不建议解开BL锁，即使解开，有能力尽量锁住Data分区。5.解开BL锁后账户锁形容虚设，查找手机的功能基本报废。6.高通9008模式下可以进行绕过BL锁（这里便不详细介绍）。
QQ伴随着我们从童年走到现在，但是你对QQ真的了解么？QQ还有很多冷知识，相信你们到现在也还有不知道的吧，下面我就分享一下QQ你所不知道的冷知识和预防盗号的小知识！1. 空间小游戏在空间里，QQ也隐藏着一个小游戏，就像每代安卓新系统发布后隐藏的小彩蛋一样，让你自己探索，那么QQ空间的小游戏在哪儿呢？首先，我们进入QQ空间，随便点开一条说说详情，然后再把说说详情页使劲向下拉，这时候你就会发现空间的“拔河”小游戏了，手速慢的人可要慎玩~2. 消息小表情在QQ 8.0.0版本上线后，QQ的UI界面发生了很大的改变，其中在消息界面也有一个你所不知道的小彩蛋。那么它在哪儿呢？没错，就是这个！大家不妨去长按住这个小表情，然后拖动一下试试，看看这个表情前后对比一下有什么变化？3. “神秘的代码”登录QQ先上图：这段神秘的代码其实是一段你QQ账号的十六进制数值，其原理是近年以来腾讯登录界面采用了新的前端代码，推测为JS的parseInt()函数，可以同时将十进制字符串和十六进制字符串类型数据转换为十进制整型。话不多说，直接上教程：打开进制转换器转换数字处选择十进制填你的QQ转换结果选择十六进制即可（因账号输入框输入字符有限，故二进制和八进制字符太长了无法输入）登录账号用0x加你QQ的十六进制代码使用此方法在电脑上QQ和电脑上的TIM版QQ有效，Mac和手机QQ测试时是没有效果的。4. QQ内隐藏网址举报按钮有的小伙伴把链接发到某个群里，一开始还能打开，但是过了一段时间后发现链接因举报而打不开了。这个方法可以让你在QQ内打开网址时无举报选项。其实方法也很简单，只需要在你要分享的链接后面加上?_wv=2即可。例如：http://www.baidu.com变成http://www.baidu.com?_wv=2即可如果你想在你的QQ内全屏打开网页的话，只需要在网页链接后面加上?_wv=16777223&_bid=3354即可5. 强制QQ窗口聊天有的小伙伴可能因为某些原因有一个人的QQ，却不能和他聊天，下面这个方法让你和他（她）强制打开会话窗口聊天。我们打开浏览器，复制粘贴如下代码：http://wpa.qq.com/msgrd?v=3&uin=**********&site=qq&menu=yes或tencent://Message/?Uin=**********&websiteName=www.oicqzone.com&Menu=yes把代码中的*号换成对方的QQ回车即可，前提是你的QQ要登录，且对方没有把你拉黑或屏蔽你6. QQ盗号事件畅谈根据我多天的资料搜集，发现盗号大多数是密码爆破、获取你的cookie或skey、木马程序盗号以及钓鱼链接或DNS劫持等密码爆破：顾名思义，就是用跑字典方法不断去尝试登录你的QQ账号，这个在以前弱密码泛滥的时候还是有点儿用处的，当今的QQ措施已经做得相对完善，而且密码在多次输错后都需要一段验证码来核实是否机器操作，此类方法现在已不在适用。获取cookie或skey：根据搜狗百科释义,Cookie指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据，由卢·蒙特利于1993年3月发明。Cookie基于Internet的各种服务系统应运而生，是由 Web服务器保存在用户浏览器上的小文本文件，它可以包含有关用户的信息，是用户获取、交流、传递信息的主要场所之一，无论何时用户链接到服务器，Web站点都可以访问 Cookie 信息。有的骗子盗取了某个账号之后，会向好友里发送一个二维码，声称自己的一个账号被盗了，要求申诉，这个时候的你一定要谨慎再谨慎！因为骗子很可能就是发来一个获取cookie或skey的二维码，如果你扫描了，骗子就很有可能取得了你的cookie或skey信息，有了这个，骗子就可以利用一段伪链接骗取系统，让系统误以为是你“本人”操作。当然也不排除骗子直接发来一个某快捷登录的二维码，这个二维码很可能是更改你账号密码或密保的关键操作二维码。大家请在有遇到此类的人先用QQ语音或QQ视频核实对方是不是本人，确定是本人后再操作。木马程序：顾名思义，通过木马来获取你的账号密码，通常此类木马是截获你的操作信息，比如记录你的键盘操作，然而此类木马也很难让人发现察觉。所以，为了你的QQ账号安全，不要使用第三方修改版QQ，或者在你输入密码的时候通过鼠标将光标选到指定的位置再输入，这样木马程序记录的你的密码就不是真实的密码。例如账号密码是：123456。你可以输入12356，然后用鼠标将光标置在3和5之间再输入4，这样程序记录的你的密码就是123564。钓鱼链接或DNS劫持：（1）、钓鱼链接：钓鱼链接就是用网址伪造一个页面，诱使你去访问，而这个页面做的却又很逼真，这就导致很多小伙伴深陷其中，误以为这是官方网站，从而在该网站里一步步的泄露你的信息，而这类网站大家仔细想想或看看也能看出很多破绽，举个例子，例如正规淘宝的网页链接是：https://ai.taobao.com，有的骗子用域名伪装成：https://ai.taibao.com或https://ai.ta0bao.com。这时候你不容易发现网页链接的问题，而且网页里面呈现出来的和淘宝却又大差无几，这时候你就很可能在这个钓鱼网站里交出你的个人信息，其实，我们进入钓鱼链接不可怕，只要我们不在钓鱼网页里面输入密码或扫描二维码，不法分子还是很难获取你的账号密码的。（2）、DNS劫持：根据搜狗百科给出的释义：DNS劫持又称域名劫持，是指在劫持的网络范围内拦截域名解析的请求，分析请求的域名，把审查范围以外的请求放行，否则返回假的IP地址或者什么都不做使请求失去响应，其效果就是对特定的网络不能访问或访问的是假网址。此类通常在局域网内发生的比较多，因为局域网内利用DNS劫持的操控性及其方便，也不排除有的是利用木马程序植入你的设备使其更改你的设备DNS，当DNS被劫持时，你的一举一动就暴露在了别人的眼皮底下，别人可以通过DNS劫持让你的访问请求指向某钓鱼网站，又或者窃取你的cookie信息达到账号无声无息的被盗。因此在某些公共场合若发现有一些没有密码的公共WIFI请不要链接，或者链接了也请建立一个VPN加密隧道上网，让别人即使取得你的数据也无计可施。这些是我自己搜集有关盗号的一些知识并将其总结，还有一些更“高级”的盗号方法博主可能还有不知晓的，但是不管如何，大家只要对自己的QQ多加保护，多弄一些高强度的密码，不乱下载第三方软件以及不轻信一眼就能看破的“超值腾讯送会员”等活动（小声哔哔：腾讯什么性格大家还不知道吗，哪有这等好事）就可以很好地预防盗号了。还有很多很多的QQ冷知识就不一一报出来啦，小伙伴们可以自己多多去发掘哦~
今天为大家介绍一款神奇的 Android 第三方接口 —— Magisk1. Root —— 玩家与厂商间的博弈Android 从诞生之日起就高举着开源的大旗，这也是它成功的原因之一。而它的开放性也成功的吸引到了一大批爱折腾的人，从而诞生出了 root（此处特指 Android 中的 root）。根据维基百科的释义，root 指的是使用户取得 Android 操作系统的超级用户（Super User）许可权的技术。用户通过 root，可以越过手机制造商的限制，卸载手机制造商预装在手机中某些应用，以及运行一些需要超级用户权限的应用程序。同时,root 也可能会让手机变得“不安全”（并不是说 root 使手机变得不安全，而是一些用户的使用习惯会使 root 后的手机变得危险）。但是从棉花糖（Android 6.0）开始，Google 基本阻止了以前版本中最流行的 root 方法 —— 即，将 su守护程序 放置到 /system 分区，并在启动时取得所需的权限。道高一尺，魔高一丈，于是就出现了 systemless 的 root 方式，因为它不采取任何方式修改 /system 分区。出于增加安全性的考虑，Google 推出了 SafetyNet 这样的检测，以确保 Android Pay 等一些 App 的安全运行，玩家不得不在 root 权限和一些有价值的 App 之间作出选择。这个时候 Magisk 诞生了。2. 什么是 MagiskMagisk 是出自一位台湾学生 @topjohnwu 开发的 Android 框架，是一个通用的第三方 systemless 接口，通过这样的方式实现一些较强大的功能。看似很简单的一个框架，甚至与大名鼎鼎的 Xposed 框架在功能性上有点重复。很多人批评 Magisk的模块太少了，想替代 Xposed 根本不可能（在那个 Xposed Framework for Android 7.0 难产的时代，很多人将 Magisk 看是做是 Xposed 的替代品）。这是不正确的，因为 Magisk 从来没有想过要代替 Xposed ，Magisk 与 Xposed 是可以互相兼容的，你甚至可以通过 Magisk 来安装 Xposed（安装 Xposed 后就不能绕过 SafetyNet 了）。Magisk 的厉害之处在于它实现了一种绕过 SafetyNet 使用 root 的方法。实现原理：由于它是通过启动时在 boot 中创建钩子，把 /data/magisk.img 挂载到 /magisk，构建出一个在 system 基础上能够自定义替换，增加以及删除的文件系统，所有操作都在启动的时候完成，实际上并没有对 /system 分区进行修改（即 systemless 接口，以不触动 /system 的方式修改 /system）。3. Magisk 是如何工作的？在一些用户眼里，Magisk 与另一款名为 Xposed 的神器有着高度的相似性，部分群体当中甚至还存在着「Magisk 框架」这样的说法。的确，二者的工作机制都是「拦截」。Xposed 通过劫持 Android 系统的 zygote 进程来加载自定义功能，这就像是半路截杀，在应用运行之前就已经将我们需要的自定义内容强加在了系统进程当中。Magisk 则另辟蹊径，通过挂载一个与系统文件相隔离的文件系统来加载自定义内容，为系统分区打开了一个通往平行世界的入口，所有改动在那个世界（Magisk 分区）里发生，在必要的时候却又可以被认为是（从系统分区的角度而言）没有发生过。Magisk 的实现方式就像是一种魔法，当被挂载的 Magisk 分区被隐藏甚至被取消挂载时，原有系统分区的完整性丝毫未损，玩需要 root 验证的游戏、运行对设备认证状态有要求的应用甚至进行需要验证系统完整性的 OTA 更新都没有任何问题。因此严格来说 Magisk 可以被看作是一种文件系统，这种文件系统通过巧妙的实现方式避开了对系统文件的直接修改，从稳定性上来看要优于以往任何一种系统框架，这也是当前它在玩机社区广受认可和好评的原因所在。4. 它的魔力不止于 root很多人对 Magisk 的初步认识可能是 root ——在 SuperSU 销声匿迹之后，它自然而然就成为了当前 Android 社区用来获取 root 权限的主流方式。不过 Magisk 特殊的运作机制还赋予了它相较于 Android 平台其他定制工具而言独一无二的特质——systemless。这种 systemless 特质让 Magisk 拥有了获取 root 权限之外的诸多优势：一方面，得益于独特的挂载机制，使用 Magisk 时我们可以有针对性地隐藏 root，甚至暂时隐藏 Magisk 本身。如此一来，不仅「root 模式下使用特定应用」成为了可能，就连无缝 OTA 更新这种「魔改党」们想都不敢想的事也变得不再遥远。在 Magisk Manager 应用的设置中，我们甚至还可以用随机包名对 Magisk 进行重新安装，让它从其他应用的眼皮底下彻底消失——多么具有魔法特质的高明手段！另一方面，挂载系统的存在，也让 Magisk 拥有了多样的模块化生态系统。既然用了「开外挂」的实现方式，那不妨就多挂载一些额外的东西，字体、音效、驱动……甚至 Xposed 本身。Magisk 提供了一个独立于系统分区以外的、可以随时隐形的「沙盒」，那自然不能将其才华禁锢于 root 这一件事上。在 Magisk 的模块仓库里，我们可以找到各式各样的模块（modules）来满足自己的定制化需求，借助这些模块，我们在 root 之后能做的事情其实也还有很多。在这里的讨论语境下，Magisk 如何给人们留下「框架」这一认知误区的原因就浮出水面了。只是功能方面好不逊色的 Magisk，稳定性和上手门槛对大部分用户来说都更加友好。5. 如何安装 Magisk作为一套复杂的文件系统，Magisk 的安装步骤却是十分简单。在电脑上配置好adb 环境并解开 Bootloader 锁后，如果你的设备有来自TWRP的官方支持，只需在打开 USB 调试后将手机与电脑相连，然后打开电脑端的命令行窗口：执行adb reboot bootloader进入 Bootloader 界面执行fastboot boot TWRP.img进入临时 TWRP在 TWRP 中刷入你下载的 Magisk 安装包没有官方 TWRP 支持的设备安装 Magisk 的步骤要稍微复杂一些：从你的刷机包中提取当前固件的 boot.img 文件，将它传入到安装了 Magisk Manager 的手机中进入 Magisk Manager —— 安装（install）—— install —— 修补 boot 镜像文件然后选择传入的 boot.img 文件进行生成，并将生成后的 Patchedboot.img （姑且这么命名） 传输到电脑上。随后我们使用 Magisk 应用对 boot.img 进行重新打包：打开命令行窗口执行adb reboot bootloader进入 Bootloader 界面执行fastboot boot Patchedboot.img来加载生成后的 boot 分区文件获取临时 root此时进入系统，你会发现你已经成功安装了 Magisk（如果显示没有安装则为获取失败，请检查操作过程重新尝试），但这还不够，我们还得进入 Magisk Manager，选择安装（install）——install——Direct Install（直接安装）才能将临时 root 转换为永久 root。三星、华为等特殊机型的 Magisk 安装方法参见 Magisk 官方帮助文档。安装完 Magisk 后，我们就可以通过 TWRP 或者 Magisk Manager 刷入获取到的模块了。模块的获取方式可以是 Magisk Manager 自带的模块仓库，也可以是其他第三方论坛获取等。卸载 Magisk 最为彻底的方式就是在 Magisk Manager 中点击「卸载」、「完全卸载」，应用会自动下载刷完 uninstall.zip 卸载包、自动卸载它自己、自动重启。如果你无法进入系统，在 TWRP 中手动刷入 uninstall.zip 卸载包即可。至于哪些模块值得刷，就是完全看个人需求了。6. 结语Magisk 的设计包含了许多奇妙的构想，呈现到功能上来让人惊呼 Magic。如果想要最大程度地对 Magisk 魔法般的功能善加利用，必须足够熟悉 Magisk Manager。大胆尝试、谨慎操作，补全系统的特性，或是增加自己想要的功能，让手中的设备成为一台梦想机，享受美好的数字生活。部分内容选自：每个 Android 玩家都不可错过的神器：Magisk 初识与安装