实训周收尾那天,我清空两台虚拟机里所有配置,从头重新搭建整套环境。并不是为了完成作业,而是检验自己到底掌握多少内容。结果发现,第一次操作踩过的部分问题,第二次搭建依旧会短暂卡住,只是排查故障的速度明显变快。
这次实训核心任务,是搭建完整的Web服务环境。表面看只是安装并启动Nginx或者Apache,实际包含的内容远不止软件安装。整套部署涵盖域名解析、虚拟主机、权限管控、防火墙、SSL证书、日志管理等多个模块,各个模块拥有独立逻辑,同时又相互关联。
最先卡住我的地方就是配置文件架构。Nginx配置分散在主配置文件、conf.d以及sites-enabled目录,一开始不清楚各个文件作用和加载顺序。我将一个server块写在nginx.conf主配置,另一个放在sites-enabled目录,两个站点表现出现异常。慢慢才弄明白,主配置内http区块属于全局参数,sites-enabled目录下文件依靠include引入,文件加载顺序决定优先级。默认站点能够覆盖新增站点,就是因为它优先被读取。

Apache配置逻辑存在区别,模块化管理粒度比Nginx更细,依靠a2enmod和a2dismod开启关闭功能。rewrite模块未开启的情况下,WordPress固定链接访问全部返回404,这个故障排查花费将近一小时。开启模块之后还需要修改AllowOverride参数,不修改的话.htaccess文件不会生效。两项操作缺一不可,很多教程只介绍其中一步,只有亲身踩坑才能牢牢记住。
权限相关问题贯穿实训全程。Linux文件权限体系和Windows完全不同,划分所有者、所属组、其他用户三类身份,搭配读、写、执行三种权限。网站目录放在/var/www/,文件归属root用户,Web服务进程使用www-data身份运行,不执行chown和chmod调整权限,Nginx或者Apache无法读取网站文件。还有一处细节,目录必须拥有执行权限才能进入,文件只需要读取权限即可访问。目录权限设置成644会触发403报错,给普通文件设置755权限也没有必要。这些规则看着简单,实操阶段很容易混淆。
防火墙是另一个容易被忽略的环节。ufw未开启时访问一切正常,一旦启用,仅开放22端口的情况下,80、443端口全部拦截。浏览器打不开页面,第一反应大多是Web服务器配置存在错误,反复检查配置、查看日志,使用curl本地测试确认服务正常运行,才定位到防火墙规则问题。云服务器还存在独立的安全组策略,和系统防火墙互不干扰,两边端口都要放行。实训之前我完全不了解双层防火墙这套机制。
配置SSL证书的过程,让我对HTTPS有更具象的理解。Let's Encrypt配套的certbot工具能够自动完成大部分工作,修改Nginx配置、填入证书路径、设置证书自动续期。但是自动生成的配置偶尔会和手动编写的内容产生冲突,例如原有80端口跳转规则会被覆盖,需要手动调整。证书本身免费,配置环节有不少细节需要留意,证书链完整性、私钥权限、加密套件选择,都会影响站点安全。
日志管理平时很少受到关注,遇到故障才体现它的价值。Nginx的access.log记录全部访问请求,error.log记录服务端报错。Apache的access.log和error.log分开存放,路径位于/var/log/apache2/。实训期间大部分故障,最终依靠日志找到根源。404大多是文件路径错误,403一般是权限问题,502代表后端服务异常或是端口配置错误。日志记录信息很清晰,只是新手不习惯查看日志,习惯靠猜测排查问题。
虚拟主机配置是本次实训收获最大的部分。单台服务器部署多个域名,服务端依据请求的Host头部匹配对应的server配置块。Nginx匹配优先级为精确域名优先,其次是通配符域名,最后是正则表达式,没有匹配成功就调用default_server。多站点部署时这个优先级规则非常关键,顺序搞错就会出现域名访问串站。Apache虚拟主机配置写法不一样,但底层逻辑相同,依靠请求主机名分发访问请求到不同站点目录。
实训完成之后,我意识到Web服务器管理不能依靠死记硬背命令。不同环境存在差异,系统版本、软件版本、历史配置、网络环境任意一项改变,同样操作可能得到不一样结果。排查故障的能力远比熟记配置参数重要。查看日志、curl本地测试、逐层排查网络链路,这类方法比盲目搜索解决方案效率更高。
还有一个好习惯,修改配置前备份文件,修改完成执行nginx -t或者apachectl configtest校验语法,确认无误之后再reload配置。restart会中断服务,reload属于平滑重载,生产环境优先选用reload。虚拟机操作出错可以重装,真实业务环境没有这种补救机会,实训阶段就要养成规范操作的习惯。