低配 CentOS 服务器初始化:别装宝塔,手动配置 firewalld + fail2ban
先给结论:1G 内存左右的低配服务器,不要装宝塔。 宝塔面板 + Nginx + PHP + MySQL 全家桶常驻,内存随便吃掉 300-500MB,低配机器直接喘不过气;而且面板是闭源的,出过不止一次安全事件。这套配置是我自己反复用的初始化流程:关 SELinux、换阿里云源、装基础工具、手动配 firewalld 开端口、fail2ban 防 SSH 爆破、再配一个 SSH 代理。全部命令贴出来就能用,没有图形界面,没有多余进程,每一行都知道在干什么。
适用对象:CentOS 7 的 VPS、1-2G 内存、跑博客/小服务/爬虫这类轻负载。跑生产大应用的出门右转,这篇文章帮不了你。
一、关 SELinux
SELinux 默认 enforcing 模式管得极严,手动改配置、跑非标准路径的软件,经常被它静默拦截,报错还看不懂。低配个人服务器,关掉最省心。
vim /etc/selinux/config
把这一行:
SELINUX=enforcing
改成:
SELINUX=disabled
保存退出。这个改动要重启才生效。不想重启,先临时关掉:
setenforce 0
用 getenforce 确认当前状态,输出 Disabled 或 Permissive 就对了。
二、换阿里云 yum 源
CentOS 官方源在国外,国内服务器拉包慢到怀疑人生。换阿里云镜像,速度立竿见影。先备份原始源,别裸删:
cp -a /etc/yum.repos.d /etc/yum.repos.d.bak
清掉默认 repo,换成阿里云的:
rm -rf /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
刷新缓存并升级:
yum clean all
yum makecache
yum update -y
一个必须知道的坑:CentOS 7 已于 2024-06-30 停止维护(EOL)。 阿里云的归档镜像目前还能正常拉包(我实测 repomd.xml 返回 200),老机器继续用没问题;但新装系统不要再选 CentOS 7 了——选 Rocky Linux / AlmaLinux 这类 CentOS 7 的直接替代品,或者干脆 Debian / Ubuntu。命令大差不差,架构不用重新学。
三、装基础工具
一套 Web 服务器和运维常用包,一次装齐:
yum -y install gcc gcc-c++ automake make kernel-devel epel-release vim wget curl htop net-tools screen
gcc / gcc-c++ / automake / make:编译源码必备kernel-devel:编译内核模块用(个别情况它匹配的是最新内核版本,和你运行的内核不一致,需要yum install kernel-devel-$(uname -r)精确装)htop:看资源占用,比 top 直观net-tools:提供ifconfig、netstat这些老命令screen:跑长任务断线不丢,后面 oneinstack 安装就用它
四、firewalld 防火墙
CentOS 7 自带 firewalld,不用装额外东西,启动并设为开机自启:
systemctl start firewalld
systemctl enable firewalld
systemctl status firewalld # 确认 active (running)
常用管理命令
systemctl start firewalld # 启动
systemctl stop firewalld # 停止
systemctl restart firewalld # 重启
systemctl status firewalld # 查看状态
systemctl enable firewalld # 开机自启
systemctl disable firewalld # 禁止开机自启
放行端口和服务
# 允许 SSH 服务
firewall-cmd --zone=public --add-service=ssh
# 放行 HTTP/HTTPS/远程桌面端口(--permanent 表示永久生效)
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=3389/tcp --permanent
批量放行,用花括号展开,一次搞定:
firewall-cmd --permanent --add-port={80,443,3389}/tcp
踩坑提醒:网上很多教程写 firewall-cmd --add-ports=80/tcp,443/tcp,这个参数不存在,firewalld 只有单数的 --add-port。 复数写法直接报错。要么写多个 --add-port,要么用上面的花括号。
永久规则 vs 临时规则(最容易踩的坑)
firewall-cmd --add-port=80/tcp # 立即生效,但 reload 或重启后丢失
firewall-cmd --add-port=80/tcp --permanent # 写入永久配置,需要 reload 才生效
firewall-cmd --reload # 重新加载永久配置
规则:改完永久配置必须 --reload;没加 --permanent 的规则只活在当前运行期。 我见过不止一次:加完端口没 reload,重启服务器后服务全连不上,还在那查服务端程序。
查询命令
firewall-cmd --list-all # 当前区域全部规则
firewall-cmd --list-ports # 已放行端口
firewall-cmd --list-services # 已放行服务
firewall-cmd --get-zones # 列出所有区域
firewall-cmd --zone=public --list-ports --permanent # 永久配置里的端口
删除端口:
firewall-cmd --permanent --remove-port=80/tcp
firewall-cmd --reload
另外提一句:system-config-firewall 是 CentOS 6 时代的图形工具,7 上已经没了,不用去找。
五、fail2ban 防 SSH 爆破
firewalld 只负责开门关门,不负责看门。SSH 端口暴露在公网上,一天能被脚本扫几千次密码。fail2ban 干这个:盯日志,连续失败 N 次就封 IP。
安装(EPEL 源里有):
yum -y install fail2ban
写配置,/etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600 # 封禁时长(秒),1 小时
findtime = 600 # 统计窗口(秒),10 分钟
maxretry = 3 # 窗口内失败 3 次就封
banaction = firewallcmd-ipset # 和 firewalld 联动,用 ipset 封 IP
[sshd]
enabled = true
启动并开机自启:
systemctl start fail2ban
systemctl enable fail2ban
验证是否在工作:
fail2ban-client status sshd
看到 Currently banned: 0 是正常的(说明还没人撞你);过几天再看,如果 Total banned 一直在涨,说明它在替你挡子弹。配合前面 SSH 改非默认端口、禁 root 密码登录,爆破基本绝迹。
六、SSH 代理(把服务器当梯子)
服务器在国内有公网 IP 或者中转能力时,可以用 SSH 直接开一个 SOCKS5 代理,零额外软件:
ssh -C -N -D localhost:50001 root@你的服务器IP -p 22222
参数含义:
-C:启用压缩,传输文本数据效率高-N:不执行远程命令,只做端口转发-D localhost:50001:在本机 50001 端口开 SOCKS5 代理-p 22222:指定远程 SSH 端口(改成你自己的)
然后浏览器或系统代理设置里填 socks5://127.0.0.1:50001 就能用。
每次敲一长串 IP 和端口太烦,写进 ~/.ssh/config 用别名:
Host my-server
HostName 你的服务器IP
Port 22222
User root
之后一条命令搞定:
ssh -C -N -D localhost:50001 my-server
Ctrl+C 断开,代理即失效,干净利落。
七、为什么不推荐宝塔
顺手聊聊,因为太多人第一反应就是装宝塔。宝塔 11.x 一键安装命令大概是:
curl -sSO https://download.bt.cn/install/install_panel.sh
bash install_panel.sh ed8484bec
装完确实爽,图形界面点鼠标就能配站点。但低配机器上它是负资产:
- 吃内存:面板常驻 + Nginx + MySQL + PHP,1G 内存的机器装完只剩一半,跑个 WordPress 都卡。
- 闭源:面板本体不开源,你无法审计它在你服务器上做了什么。
- 安全历史:宝塔面板出过不止一次高危漏洞(未授权访问、命令执行),被打的服务器一大把。
- 学习:点鼠标配出来的服务器,你永远不知道底层发生了什么,出了问题无从下手。
如果你不是一定要图形界面:firewalld + fail2ban + 手动装 Nginx/PHP,内存占用比宝塔全家桶少一半以上,而且每行配置都是你亲手写的。 我的博客就是这套手动配置跑着,稳得很。
如果实在不想纯手动,又嫌宝塔重,可以用 oneinstack 这类一键包(LNMP 全家桶,无面板):
wget http://mirrors.oneinstack.com/oneinstack-full.tar.gz
tar xzf oneinstack-full.tar.gz
cd oneinstack
screen -S oneinstack # 用 screen 跑,断线不丢
./install.sh
中间断了就 screen -R oneinstack 重新接上。oneinstack 装完没有面板、没有多余进程,比宝塔干净一个量级。
收尾检查清单
新服务器初始化完,过一遍:
getenforce # 应为 Disabled 或 Permissive
yum makecache # 源能正常刷新
systemctl status firewalld # 防火墙在跑
systemctl status fail2ban # fail2ban 在跑
firewall-cmd --list-all # 端口放行符合预期
这套流程半小时能走完,换来的是一个你知道每一行配置在干什么、内存干净、抗爆破的服务器。低配机器,省下的每一 MB 内存都该花在你的业务上,而不是花在面板上。
© cn-res.vip — Grout
Let's get the conclusion out first: do not install a control panel like Baota (BT Panel) on low-spec servers. A 1 GB VPS running the panel plus its Nginx/PHP/MySQL stack will lose 300-500 MB of RAM before you even deploy anything, and the panel is closed-source with a documented history of critical security holes.
This is the manual initialization routine I actually use on my own servers: disable SELinux, switch to Aliyun mirrors, install base tooling, configure firewalld by hand, lock down SSH with fail2ban, and set up an SSH SOCKS5 proxy when needed. Every command below is copy-paste ready, no GUI, no hidden processes — you know exactly what each line does.
Target audience: CentOS 7 VPS boxes with 1-2 GB RAM running blogs, small services, or crawlers. If you're running production-scale workloads, this article is not for you.
1. Disable SELinux
SELinux in enforcing mode blocks non-standard setups silently, and the error messages are useless when you're debugging. For a personal low-spec server, turning it off is the pragmatic choice.
vim /etc/selinux/config
Change:
SELINUX=enforcing
to:
SELINUX=disabled
This takes effect after reboot. To disable it immediately without rebooting:
setenforce 0
Verify with getenforce — you should see Disabled or Permissive.
2. Switch to Aliyun yum mirrors
The official CentOS repos are painfully slow from China. Back up the originals first — never delete without a backup:
cp -a /etc/yum.repos.d /etc/yum.repos.d.bak
Remove the stock repo files and pull Aliyun's:
rm -rf /etc/yum.repos.d/*.repo
curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
Refresh and upgrade:
yum clean all
yum makecache
yum update -y
One thing you must know: CentOS 7 reached end-of-life on 2024-06-30. Aliyun's archived mirror still serves packages fine (I verified the repomd.xml returns 200), so existing CentOS 7 boxes can keep running. But don't install CentOS 7 on new machines — go with Rocky Linux or AlmaLinux (drop-in replacements) or Debian/Ubuntu. The commands are nearly identical; you don't need to relearn anything.
3. Install base tooling
yum -y install gcc gcc-c++ automake make kernel-devel epel-release vim wget curl htop net-tools screen
gcc/gcc-c++/automake/make: compilation toolchainkernel-devel: kernel modules (if the version mismatches your running kernel, useyum install kernel-devel-$(uname -r))htop: resource monitor, better than topnet-tools: provides legacyifconfig/netstatscreen: keep long tasks alive across disconnects
4. firewalld
firewalld ships with CentOS 7 — nothing extra to install:
systemctl start firewalld
systemctl enable firewalld
systemctl status firewalld
Service management
systemctl start firewalld # start
systemctl stop firewalld # stop
systemctl restart firewalld # restart
systemctl enable firewalld # enable on boot
systemctl disable firewalld # disable on boot
Opening ports and services
firewall-cmd --zone=public --add-service=ssh
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --zone=public --add-port=3389/tcp --permanent
Batch open with brace expansion:
firewall-cmd --permanent --add-port={80,443,3389}/tcp
Pitfall: there is no --add-ports parameter. Firewalld only has the singular --add-port. The plural form you see in many tutorials simply errors out. Use multiple --add-port flags or brace expansion.
Permanent vs runtime rules (the #1 gotcha)
firewall-cmd --add-port=80/tcp # effective immediately, lost on reload/reboot
firewall-cmd --add-port=80/tcp --permanent # written to persistent config, needs reload
firewall-cmd --reload # apply persistent config
Rule of thumb: after editing permanent rules you must run --reload; rules without --permanent only live in the current session. I've watched people add ports, skip the reload, reboot the box, and then debug their application instead of the firewall.
Inspection
firewall-cmd --list-all
firewall-cmd --list-ports
firewall-cmd --list-services
firewall-cmd --get-zones
firewall-cmd --zone=public --list-ports --permanent
Removing a port:
firewall-cmd --permanent --remove-port=80/tcp
firewall-cmd --reload
Note: system-config-firewall is a CentOS 6-era GUI tool; it doesn't exist on CentOS 7.
5. fail2ban for SSH brute-force protection
firewalld opens and closes doors; it doesn't watch them. A public-facing SSH port gets thousands of password attempts per day. fail2ban watches the logs and bans IPs after N consecutive failures.
yum -y install fail2ban
Create /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 3600 # ban duration in seconds
findtime = 600 # observation window in seconds
maxretry = 3 # ban after 3 failures in the window
banaction = firewallcmd-ipset # integrate with firewalld via ipset
[sshd]
enabled = true
Start it:
systemctl start fail2ban
systemctl enable fail2ban
Check it's working:
fail2ban-client status sshd
Currently banned: 0 is normal at first. Check again in a few days — if Total banned keeps climbing, it's taking hits for you. Combined with a non-default SSH port and disabling password login for root, brute force basically stops.
6. SSH as a SOCKS5 proxy
If your server has a public IP and bandwidth to spare, SSH alone can give you a SOCKS5 proxy — zero extra software:
ssh -C -N -D localhost:50001 root@YOUR_SERVER_IP -p 22222
-C: enable compression-N: no remote command, port forwarding only-D localhost:50001: open a SOCKS5 proxy on local port 50001-p 22222: remote SSH port (change to yours)
Then point your browser or system proxy at socks5://127.0.0.1:50001.
Tired of typing the IP and port? Put it in ~/.ssh/config:
Host my-server
HostName YOUR_SERVER_IP
Port 22222
User root
Then:
ssh -C -N -D localhost:50001 my-server
Ctrl+C kills the proxy instantly. Clean.
7. Why not Baota (BT Panel)?
Most people's first instinct is installing a panel because the GUI makes site management trivial. On a low-spec box, it's a liability:
- RAM hunger: panel daemon + Nginx + MySQL + PHP leaves a 1 GB VPS with barely half its memory free.
- Closed source: you can't audit what the panel does on your server.
- Security record: the panel has had multiple critical vulnerabilities (unauthorized access, command execution) and plenty of compromised servers to show for it.
- Learning: a server configured by clicking is a server you don't understand. When something breaks, you have nowhere to start.
If you don't need a GUI: firewalld + fail2ban + manually installed Nginx/PHP uses less than half the RAM of the panel stack, and every config line is yours. My blog runs on exactly this manual setup and it's rock solid.
If you want less manual work but still hate panels, oneinstack gives you an LNMP stack without a panel:
wget http://mirrors.oneinstack.com/oneinstack-full.tar.gz
tar xzf oneinstack-full.tar.gz
cd oneinstack
screen -S oneinstack
./install.sh
Reconnect after a disconnect with screen -R oneinstack. No panel, no extra daemons — an order of magnitude cleaner than Baota.
Final checklist
getenforce # should be Disabled or Permissive
yum makecache # mirrors working
systemctl status firewalld # firewall running
systemctl status fail2ban # fail2ban running
firewall-cmd --list-all # ports as expected
Half an hour gets you a server you fully understand, with clean RAM and brute-force protection. On a low-spec machine, every MB of memory should go to your business — not to a control panel.
© cn-res.vip — Grout