1. 实践背景与目标拆解
1.1 为什么选这个实验主题
“2.12 上机实践”这个编号看起来不起眼,但如果你翻过几本正经的Linux教材或者系统管理课程大纲,会发现这类章节往往被安排在基础命令讲完、shell语法刚入门的节点上。这个位置非常讲究——前面学的都是一条条孤立命令,后面即将进入服务配置、网络管理、自动化运维等真实场景,2.12这节实践课就是中间那座桥。
我这次实践的题目是:在一台干净的虚拟机上,从零完成Linux系统的基础环境配置,包括网络调整、用户与权限设置、SSH远程管理、防火墙策略,最后用一段shell脚本把重复性工作自动化。这个组合基本覆盖了日常接手一台新服务器时百分之八十的操作路径,做完一遍,后面再碰真实生成环境心里就有底了。
这个实验适合谁?两类人最需要。一类是刚学完Linux基础命令、但对“整套流程”还没概念的新手,另一类是准备考认证或者面试运维岗位、需要把零散知识点串成体系的同学。你会发现,单看每条命令都懂,但把它们按正确顺序组合起来、还要考虑各种边界情况,完全是另一回事。
1.2 上机实践和理论课的本质区别
说实话,我见过太多人上课听得很明白,一上机就懵。原因很简单:理论课告诉你命令“是什么”,上机实践逼你面对命令“怎么配合”。比如ip addr和ping你都学过,但真到配完网络发现ping不通外网的时候,你需要同时调动路由、DNS、网卡状态、防火墙好几层知识去排查,这已经不是单点知识能解决的了。
另外,上机实践还有一个隐藏价值,就是帮你建立“状态感”。什么是状态感?就是你得时刻清楚自己改了什么、当前系统处于什么状态、下一步操作会不会破坏前面的成果。这种意识在真实运维中比记住一百条命令都重要。我见过有同学做实验全程跟着教程敲,敲完问他系统里现在跑着什么服务,完全答不上来——这就是典型的状态感缺失。
所以这次实践我给自己定了几条规矩:不复制粘贴教程命令,每条命令都先想清楚再敲;每完成一步就验证一步;全程记录操作日志和遇到的问题。这几条规矩在后面几次差点翻车的时刻救了我,具体怎么回事后面细说。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与工具选型
2.1 虚拟机方案与系统镜像选择
上机实践第一步,得先有一台能随便折腾的实验机。我用的是VMware Workstation Player——免费版就够用,不需要破解什么授权。Parallels Desktop我也试过,macOS下体验确实顺滑,但如果是Windows主机,VMware的兼容性和资料丰富程度还是最稳的。
虚拟机配置方面,我的建议是别贪多。2个CPU核心、2GB内存、20GB磁盘,这个规格跑Ubuntu Server或者CentOS Stream都绰绰有余。为什么强调不要给太多资源?一方面宿主机的资源有限,另一方面生产环境的服务器配置也不可能是无限量的,尽早适应资源受限的环境不是坏事。实测下来,Ubuntu Server 22.04 LTS在这个配置下跑系统更新、编译小工具,流畅度完全没问题。
系统镜像我这次选了Ubuntu Server 22.04 LTS。选它的理由有三个:第一,LTS版本五年支持周期,意味着你学的东西在很长一段时间内不会被版本迭代推翻;第二,Ubuntu社区资料量巨大,遇到问题基本都能搜到答案;第三,它的netplan网络配置方式虽然初看不习惯,但逻辑清晰,比直接改/etc/network/interfaces更适合理解“网络配置到底是怎么生效的”。
2.2 网络模式与安装阶段的关键选项
虚拟机的网络模式是个容易忽略但极其重要的选项。VMware提供了桥接、NAT、仅主机三种模式,我建议实验阶段用NAT模式。
NAT模式的好处是虚拟机可以访问外网,但外部网络无法主动连入虚拟机,相当于在虚拟机外面加了一层保护。这样你配置防火墙、测试SSH的时候,即使哪里配错了,风险也局限在虚拟机内部,不会波及宿主机所在局域网里的其他设备。桥接模式虽然更像真实服务器在网络中的位置,但新手阶段用桥接,万一搞出什么网络风暴或者IP冲突,那就是给自己找麻烦。
安装过程中有几个选项值得注意。软件源建议在安装时就换成国内镜像——我用的是清华源,实测速度比默认源快一个数量级,系统更新再也不用干等。LVM逻辑卷管理这个选项我建议开启,虽然会稍微增加一点概念负担,但它让你后续调整分区大小变得非常灵活,这个便利性在以后做存储相关的实验时会体现得淋漓尽致。SSH Server组件也建议在安装时直接勾上,省得后面手工装。
另外,安装时设置的用户名尽量用简单拼写的英文名,不要用带大写字母或特殊符号的组合。我上次图省事给用户名叫ZhangSan_2024,结果后面写脚本、配环境变量时各种莫名其妙的转义问题,排查了半小时才发现是用户名里下划线和数字的组合在某些场景下需要特殊处理。
3. 核心实操环节分步拆解
3.1 网络配置:从DHCP到静态IP
系统装好后第一件事,我习惯先看一眼网络状态。执行ip addr确认网卡名——在Ubuntu Server 22.04上通常是ens33或者ens160这种以en开头的名字,然后确认DHCP是否已经分配了地址。默认情况下安装程序会把网卡设为DHCP自动获取,能上网但地址不固定,这对实验环境来说不够理想。
为什么实验环境要用静态IP?因为后面你要测试SSH连接、配置防火墙规则、搭建web服务,这些操作都依赖一个确定的IP地址。如果DHCP租约到期地址变了,你写好的脚本、配好的客户端全部要跟着改,纯属给自己挖坑。
Ubuntu Server 22.04的网络配置在/etc/netplan/目录下,一般是01-network-manager-all.yaml或者00-installer-config.yaml。我这次改的是后者,内容大致如下:
bash复制network:
version: 2
ethernets:
ens33:
dhcp4: false
addresses:
- 192.168.101.101/24
routes:
- to: default
via: 192.168.101.2
nameservers:
addresses:
- 223.5.5.5
- 119.29.29.29
几个参数解释一下。dhcp4: false明确关闭DHCP,addresses指定IP和子网掩码,routes里的via是网关地址——NAT模式下这个地址一般是192.168.101.2,具体以你的VMware虚拟网络编辑器设置为准。DNS我用的阿里和腾讯的公共DNS,国内访问速度快,也不容易污染。
改完执行sudo netplan apply让配置生效。这里有个多年养成的习惯:先别急着ping外网,先ip addr确认网卡上已经绑定了新IP,再ip route看默认路由是否正确,最后才ping 223.5.5.5测试联通性——逐层验证的好处是出了问题能快速定位在哪一层。
测试DNS解析用nslookup baidu.com或者ping baidu.com都行。如果IP能通但域名不通,百分之九十是DNS配置问题;如果IP都不通,那就回头检查IP和网关是否在同一个子网。
3.2 新建普通用户与sudo权限分配
使用root账号直接操作是Linux运维里的大忌,这点我在实验课上反复强调过。root权限太大,一条rm -rf敲错了连后悔的机会都没有。正确的做法是日常操作使用普通用户,需要提升权限时用sudo。
安装系统时配置的那个用户其实已经是sudo组成员了,但为了模拟真实的多用户管理场景,我习惯再单独建一个用户:
bash复制sudo useradd -m -s /bin/bash devops
sudo passwd devops
sudo usermod -aG sudo devops
-m参数自动创建用户主目录,-s /bin/bash指定登录shell为bash——如果不指定,默认可能是sh,那个提示符和交互体验会让你怀疑人生。passwd设置密码,usermod -aG sudo把用户加到sudo组,-aG两个参数要一起写,-a代表追加,少了它会把用户从其他组里踢出来。
接下来用su - devops切换到这个新用户,验证sudo权限是否正常工作。
验证方式很简单:执行sudo whoami,如果输出root,说明sudo配置正常。这一步不能省,因为曾经有人把用户加错了组,看着配置文件没问题,一执行sudo就报错,排查半天才发现-a参数丢了,用户原来的附加组全被覆盖了。
这里顺带提一句安全习惯:创建用户后我用sudo chage -M 90 devops设置了密码90天有效期,到时间会强制要求修改。实验环境虽然不涉及真实生产,但尽早养成密码策略的习惯没有坏处。
3.3 OpenSSH远程管理配置与密钥登录
作为运维方向的学习者,SSH配置是必须熟练掌握的技能。Ubuntu Server默认已经装了openssh-server,如果没有,执行sudo apt install openssh-server装一下。
先确认服务状态:sudo systemctl status sshd,看到active (running)就说明服务正常。然后我改了一下配置文件/etc/ssh/sshd_config,重点是这几项:
bash复制Port 22
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication yes
初期练习阶段先保留密码登录,方便排查问题,等密钥登录配置好了再把它关掉。PermitRootLogin no这条建议尽早设置——允许root直接SSH登录在任何正规环境里都是高危配置,攻击者拿到用户名就是爆破密码一个环节。
密钥登录的配置流程:
bash复制# 在宿主机(Windows/Mac/Linux都可以)生成密钥对
ssh-keygen -t ed25519 -C "devops-lab-key"
# 查看公钥内容
cat ~/.ssh/id_ed25519.pub
# 在虚拟机上执行,将公钥写入authorized_keys
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "你的公钥内容" > ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
密钥登录的原理是公私钥配对验证,简单理解就是公钥是锁,私钥是钥匙,服务器上只存锁不存钥匙,就算服务器数据泄露,攻击者也拿不到私钥。chmod 700和chmod 600这两个权限设置是硬性要求——如果权限太宽松,sshd会拒绝使用这个文件,这属于安全机制的一部分,不是故意刁难你。
配置完成后从宿主机再开一个终端,执行ssh devops@192.168.101.101,如果直接登录成功说明密钥登录生效。确认无误后再回到sshd_config里把PasswordAuthentication改成no,然后sudo systemctl restart sshd。重启sshd前建议先开着另一个登录会话,防止配置出错把自己锁在外面——这是运维老手的基本素养。
3.4 防火墙配置:只开该开的端口
防火墙是上机实践里最容易翻车的一环。我刚学的时候总觉得防火墙就是“打开它”和“关掉它”两个状态,直到被生产环境里防火墙规则导致服务不可用的故障教育过几次,才明白防火墙真正的讲究是“精确控制”。
Ubuntu自带的防火墙是ufw,它其实是对iptables的封装,目的是简化日常操作。我的配置过程如下:
bash复制sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH service'
sudo ufw enable
sudo ufw status verbose
两条default规则的含义是:默认拒绝所有入站连接,默认允许所有出站连接。这个“白名单”思路是防火墙配置的核心哲学——没有明确放行的流量一律拦下,而不是没有明确拒绝的流量一律放行。前者安全,后者危险,就这么简单。
我只放行了22端口(SSH),因为这台虚拟机目前只需要这一个入站服务。后续如果搭建nginx,再执行sudo ufw allow 80/tcp和sudo ufw allow 443/tcp。这里强调一下:配置防火墙时一定要先添加允许规则再执行ufw enable,顺序反了会导致当前SSH连接直接断掉,而且断了就再也连不回来了——别问我是怎么知道的。
ufw status verbose查看当前规则,确认无误后用ssh从宿主机重新连接一次,验证防火墙生效后一切正常。另外我习惯性加了一条sudo ufw logging on,开启防火墙日志,以后安全相关的实验会用到——但要注意/var/log/ufw.log会产生大量日志,别让它在实验环境里无限增长吃满磁盘。
3.5 自动化部署脚本:把重复性工作封装起来
前面几步全部手工操作完成后,思路要往自动化方向转。这个环节是整节上机实践的高潮,也是最能体现工程思维的部分。
我的需求很简单:把配完一台新虚拟机后要做的基础设置写成一个脚本,下次新开环境直接执行一遍,省去重复劳动。脚本内容如下:
bash复制#!/bin/bash
# 基础环境初始化脚本
set -e
# 更新系统
echo "=== 更新软件源及系统包 ==="
sudo apt update && sudo apt upgrade -y
# 安装常用工具
echo "=== 安装常用工具 ==="
sudo apt install -y curl wget git vim net-tools unzip tree
# 设置时区
echo "=== 设置时区为Asia/Shanghai ==="
sudo timedatectl set-timezone Asia/Shanghai
# 创建日志目录
echo "=== 创建应用日志目录 ==="
sudo mkdir -p /var/log/apps
sudo chmod 755 /var/log/apps
# 优化swap参数(减轻磁盘IO压力)
echo "=== 调整swap使用策略 ==="
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
# 输出完成信息
echo "=== 基础环境初始化完成 ==="
ip addr show | grep -w inet | grep -v 127.0.0.1
脚本开头的set -e是保命符,它表示脚本中任何一条命令执行失败,整个脚本立即终止。这避免了“上一行命令已经报错但脚本继续往下跑,最后出了个四不像的结果还不容易排查”的尴尬局面。每一段命令前加echo输出当前步骤,方便观察脚本执行到哪一步了。
这里有个非常关键的细节:脚本没有包含网络配置和用户创建这两块。为什么?因为网络配置应该用netplan的方式管理,一旦写死反而降低灵活性;用户创建涉及密码输入,在非交互脚本里有安全风险,而且每台服务器的用户需求不同。自动化的边界在哪里——这是这节实践最重要的思考题。真正的自动化不是把能写的全写进去,而是知道什么事该自动化,什么事该保留手工操作。
跑一遍脚本,看到最后的IP输出信息,整个基础环境配置就算完成了。这时候我习惯做一次系统验证——uptime看负载、free -h看内存、df -h看磁盘、sudo systemctl list-units --type=service --state=running | wc -l看一下当前运行服务数量,确认系统状态健康。
4. 踩坑记录与排查技巧实录
4.1 高频问题的原因与解决速查表
这部分是上机实践最值钱的内容——都是我亲测踩过、也看身边同学反复踩过的坑。直接整理成表格,方便你贴在手边对照:
| 现象 | 可能原因 | 排查思路 |
|---|---|---|
ping 223.5.5.5 不通 |
网关错误或网卡未启用 | 先查ip addr确认网卡状态,再ip route查默认路由,最后检查VMware网络模式和虚拟网络编辑器里的网关地址 |
| 域名解析失败但IP能通 | DNS配置错误 | cat /etc/resolv.conf看实际生效的DNS,测试nslookup baidu.com,确认后修改netplan并apply |
| SSH连接被拒绝 | sshd服务未启动或防火墙拦截 | 虚拟机本地systemctl status sshd确认服务,再sudo ufw status确认22端口是否放行,还要留意sshd_config里有没有把端口改掉 |
sudo执行报错user not in sudoers |
用户未加入sudo组或usermod参数错误 | groups devops查看用户当前所在组,如果有误用usermod -aG sudo重新追加 |
脚本执行报Permission denied |
脚本文件无执行权限 | chmod +x script.sh,然后./script.sh执行,注意不要用sh script.sh绕过去 |
netplan apply 报错 |
YAML语法缩进错误 | 用sudo netplan try先试运行,超时自动回滚,比直接apply安全得多 |
| 磁盘空间告急 | 日志文件或软件包缓存堆积 | du -sh /var/log/*排查大文件,sudo apt autoremove清理无用包,必要时清理journal日志 |
4.2 两个典型的排查案例全过程
挑两个有明显技术含量的案例展开说一下。
案例一:netplan配置后网络直接断掉
这个过程非常惊险。我在虚拟机里修改了netplan配置,执行sudo netplan apply后,SSH连接瞬间断开,而且重新连接也连不上。当时第一反应是完了,配错了。但很快冷静下来,想到VMware虚拟机有快照功能——这是课前再三强调过的,改系统关键配置前先打个快照。
恢复快照后重新操作,这次用了sudo netplan try而不是直接apply。这个命令会先试运行新配置,如果60秒内没有收到确认,自动回滚到之前的配置——相当于给网络配置上了一道保险。试运行时依然断了连接,说明配置确实有问题。仔细检查发现是我把网关地址写成了192.168.101.1,而实际NAT网关是192.168.101.2。一个数字之差,网络全断。
这个案例教育我两件事:第一,重要操作前打快照是保命手段,不是可有可无的步骤;第二,netplan try比netplan apply更适合在远程环境里用,它的自动回滚机制可以在你把自己锁在外面之前把门打开。
案例二:SSH免密登录配置后仍需输入密码
这个问题的诡异之处在于,密钥文件权限、公钥写入位置都检查过,完全没问题,但登录时就是提示输入密码。
排查过程:先在虚拟机本地用ssh -vvv devops@localhost查看详细的认证日志,发现客户端发送公钥后,服务端返回”Authentications that can continue“,说明公钥没被接受。再到/var/log/auth.log里查sshd的认证记录,发现一行关键日志:Authentication refused: bad ownership or modes for directory /home/devops。
原因找到了——用户主目录权限是0755,而SSH要求~目录权限不能超过0755且不能对其他用户可写。我执行ls -ld /home/devops一看,果然是drwxr-xr-x,虽然不算违规,但.ssh目录在创建时被我误操作成了0744,这会被sshd判定为不安全配置。执行chmod 700 /home/devops/.ssh后,问题立即解决。
这个案例的教训是:学习阶段不能只盯着“功能能不能用”,还要关注背后的安全机制为什么要这样设计——权限限制看起来麻烦,但它是防止其他用户通过文件权限漏洞读取密钥的最后一道防线。
4.3 几个值得长期坚持的实操习惯
除了具体问题的排查,有几个习惯是我强烈建议在这个阶段就养成的。
第一个是操作前先备份或打快照。快照不是逃避理解的手段,而是给“试错”提供一个安全垫。这个习惯在以后操作生产环境时能救命,虽然生产环境一般不允许随便打快照,但备份配置文件永远是第一位的。
第二个是记录操作日志。我每次上机都会在终端里开一个script命令自动记录所有输入输出,保存到~/lab-log-$(date +%F).log文件里。这样最后写实验报告时不用回忆操作过程,直接回放日志就行,而且排查问题时能清晰地看到当时的操作上下文。
第三个是每次只改一个变量。配置出问题时,如果同时改了三处,你很难说是哪一处导致的。一次只动一个地方,改完立即验证,这种“小步快跑”的节奏看起来慢,实际却是最快的。
第四个是用好“抄作业”的边界。遇到不会的配置,搜索到命令后先别急着粘贴,把每一条命令在文档里查清楚含义再执行——我见过不少同学就是因为粘贴了过时的命令,导致配置文件格式错误,反而耽误更长时间。
5. 实验扩展思路与个人心得
5.1 向上延伸:从基础配置到服务部署
这节上机实践做完,基础环境已经跑通了,但它的价值不应该到此为止。我建议在现有环境上继续做两个扩展实验。
第一个是部署一个nginx服务。配置好80端口允许访问,把/var/www/html下放一个测试页面,然后从宿主机浏览器访问虚拟机的IP,看到页面就说明从网络层、防火墙层到应用层的完整链路都通了。这一步能把本节学的网络配置和防火墙知识串起来用。
第二个是写一个简单的定时备份脚本。用crontab写一个任务,每天凌晨2点把/etc目录打包压缩并加上日期后缀,放到/home/devops/backups/下,保留最近7天的备份。这个脚本贴近真实运维场景,也不复杂,但能帮你熟悉cron的时间表达式和shell脚本的日志处理。
5.2 我的实操体会
做完这节实践,我最大的体会是:配置过程本身不难,难的是建立系统性的思维。你会越来越意识到,服务器上任何一项配置都不是独立存在的——网络配置影响SSH连接,SSH设置关联用户权限,用户权限又牵扯到sudo策略,防火墙则在这些之上做了一层总控。每一条命令都像工具,但怎么组合更考验对系统底层逻辑的理解。
第二点体会是,快照和备份带来的心理安全感会显著提升学习效率。敢折腾、敢试错,才能对系统的容错边界有真实感知。这比跟着教程按部就班地敲一遍有效得多。
最后想说的是,运维和网络方向的技能,靠看不靠练是不可能掌握的。你在B站上看了上百个教程视频,不如亲手把一台虚拟机从零配到能跑服务来得实在。遇到问题、排查问题、解决问题——这个过程才是技能真正内化的时候。现在,打开你的虚拟机,把这篇文章里的命令敲一遍吧。
