云服务器配置记录
最近对静态博客比较感兴趣,再加上静态博客相较于动态博客可以减少一大笔性能开销,给其他服务腾出了空间,因此将博客从 WordPress 迁移到了 Hexo 上。既然博客都迁移了,那不如就给服务器也来一次翻新吧!
基础配置
安装系统、配置SSH
我的服务器是阿里云的轻量应用服务器,如果是其他家的服务器,也可以适当参考一下。系统镜像我选择了最新的“CentOS 8.2”。系统安装完成后,首先在控制台配置防火墙。由于我会在服务器上配置 Firewalld 作为防火墙,并不需要用到阿里云的控制台中的防火墙。找到 安全 - 防火墙
,删除自动生成的允许 SSH 的规则,选择 添加规则 - 应用类型 - 全部TCP+UDP
,这样控制台中的防火墙就会允许所有流量通过。结果应该如下图:
配置完防火墙之后,需要设置一下服务器的系统密码。选择 服务器运维 - 远程连接
,打开在线终端。如图:
在终端中,输入如下命令:
sudo su
passwd
配置完密码之后,更改一下主机名:
hostnamectl set-hostname [新的主机名]
再安装几个常用软件:
yum install -y nano screen htop
接下来,需要更改一下 SSH 的端口,以减少被爆破的风险。编辑配置文件:
nano /etc/ssh/sshd_config
找到如下字样:
#Port 22
修改成:
Port 22
Port [SSH 端口]
保存。现在需要重启 SSH 服务使改动生效:
systemctl restart sshd
由于 Firewalld 默认只允许 22 端口,这里保留 SSH 服务的 22 端口的目的,是为了防止 SSH 服务的非 22 端口被 Firewalld 阻挡从而锁死的情况。
要在 nano 中搜索,只需按下 `Ctrl + W`,输入关键字,再按下 `Enter` 即可。再次按下 `Ctrl + W` 会保留上一次输入的关键字,可以直接按下 `Enter` 搜索下一个匹配的目标。
按下 `Ctrl + O`,再按下 `Enter` 即可保存改动。再按下 `Ctrl + X` 即可退出 nano。
配置防火墙
现在可以使用终端软件来连接了!连接到服务器之后,就可以开始配置 Firewalld 了。在默认情况下,Firewalld 是被禁用的状态,需要手工启用:
systemctl start firewalld
systemctl enable firewalld
现在检查一下 Firewalld 服务的状态:
systemctl status firewalld
会得到类似这样的输出:
● firewalld.service - firewalld - dynamic firewall daemon
Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-11-27 12:43:33 CST; 1h 34min ago
Docs: man:firewalld(1)
Main PID: 2704 (firewalld)
Tasks: 2 (limit: 12399)
Memory: 27.1M
CGroup: /system.slice/firewalld.service
└─2704 /usr/libexec/platform-python -s /usr/sbin/firewalld --nofork --nopid
至此,Firewalld 就已经启动了。服务启动后,默认规则就会生效。现在查看一下默认规则:
firewall-cmd --list-all
会得到类似这样的输出:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
可以看到,默认规则仅允许了 SSH 服务,即 22 端口。如果当前 SSH 会话使用的是非 22 端口,仍然可以继续通讯;但是断开连接后将无法再次连接。在完成后续操作前,尽量不要断开连接。如果不小心断开了连接,可以使用 22 端口再次连接。
现在配置防火墙规则:
firewall-cmd --remove-service=cockpit --permanent
firewall-cmd --remove-service=dhcpv6-client --permanent
firewall-cmd --remove-service=ssh --permanent
firewall-cmd --add-port=[SSH 端口]/tcp --permanent
firewall-cmd --reload
检查防火墙规则:
firewall-cmd --list-all
会得到类似这样的输出:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services:
ports: [SSH 端口]/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
同样的,当前的规则已经不再允许 22 端口的通讯。如果当前的 SSH 会话使用了 22 端口,连接不会立即中断;但是断开连接后就无法再次通过 22 端口连接了,只能使用非 22 端口连接。
同时,由于阿里云的控制台中的在线终端使用了 22 端口,将无法使用。
至此,Firewalld 配置完毕。
配置Fail2ban
虽然已经修改了 SSH 的默认端口,但是为了防止被更高阶的扫描器爆破,我选择安装 Fail2ban 来加强防护。
由于系统自带的软件源中不包含 Fail2ban,需要安装新的软件源:
yum install -y epel-release
如果在安装过程中,出现了类似这样的报错:
Error: Failed to download metadata for repo 'epel-modular'
则说明网络存在问题,可以更换阿里云的镜像。编辑配置文件:
nano /etc/yum.repos.d/epel-modular.repo
将 metalink=
一行注释,并在 #baseurl=
一行后新增一行 baseurl=http://mirrors.cloud.aliyuncs.com/epel/8/Everything/$basearch
。修改结果如下:
[epel-modular]
name=Extra Packages for Enterprise Linux Modular $releasever - $basearch
# It is much more secure to use the metalink, but if you wish to use a local mirror
# place its address here.
#baseurl=https://download.example/pub/epel/$releasever/Modular/$basearch
baseurl=http://mirrors.cloud.aliyuncs.com/epel/8/Everything/$basearch
#metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-modular-$releasever&arch=$basearch&infra=$infra&content=$
enabled=1
gpgcheck=1
countme=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-8
保存改动,再次运行命令即可。
安装完软件源之后可以安装 Fail2ban:
yum install -y fail2ban
在默认情况下,Fail2ban 是被禁用的状态,需要手工启用:
systemctl start fail2ban
systemctl enable fail2ban
现在检查一下 Fail2ban 的统计信息:
fail2ban-client status
会得到类似这样的输出:
Status
|- Number of jail: 0
`- Jail list:
可以看到 Fail2ban 默认没有任何规则。现在添加一个规则来保护 SSH 服务。编辑配置文件:
nano /etc/fail2ban/jail.local
输入如下内容:
[sshd]
enabled = true
port = [SSH 端口]
banaction = firewallcmd-rich-rules
bantime = 24h # 封禁时长
保存,重启一下服务:
fail2ban-client reload
再次查看统计信息:
fail2ban-client status
会看到刚刚设置的规则已经被启用了:
Status
|- Number of jail: 1
`- Jail list: sshd
而进一步查看 SSH 服务的封禁情况:
fail2ban-client status sshd
会看到目前没有被封禁的 IP:
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
如果拥有一个以上的公网地址,也可以使用不同的 IP 多次输入错误密码进行测试。失败次数达到 5 次之后,SSH 通讯将被阻断。查看 SSH 服务的封禁情况:
fail2ban-client status sshd
会看到用于测试的 IP 已经被封禁了:
Status for the jail: sshd
|- Filter
| |- Currently failed: 1
| |- Total failed: 6
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 1
|- Total banned: 1
`- Banned IP list: [测试 IP]
而查看 Firewalld 的规则:
firewall-cmd --list-all
也可以看到相关规则已经被添加到 rich rules 中了:
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services:
ports: [SSH 端口]/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" source address="[测试 IP]" port port="[SSH 端口]" protocol="tcp" reject type="icmp-port-unreachable"
如要解封测试 IP,可以输入以下命令:
fail2ban-client unban [测试 IP]
如要解封所有 IP,可以输入以下命令:
fail2ban-client unban --all
在默认的情况下,封禁前允许的最大失败次数由 `/etc/fail2ban/jail.conf` 文件中的 `maxretry` 定义,其值为 5。
由于一次 SSH 会话可能允许多次身份验证尝试,而 Firewalld 不会断开已经建立的连接,因此实际可以尝试的次数可能会大于设置的阈值。
至此,Fail2ban 配置完毕。
删除云盾
如果服务器是不同家的,需要参考对应的官方文档。
执行官方的卸载脚本,并删除相关文件,最后重启即可生效:
wget http://update.aegis.aliyun.com/download/uninstall.sh && chmod +x uninstall.sh && ./uninstall.sh
wget http://update.aegis.aliyun.com/download/quartz_uninstall.sh && chmod +x quartz_uninstall.sh && ./quartz_uninstall.sh
pkill aliyun-service
rm -rf /etc/init.d/agentwatch /usr/sbin/aliyun-service
rm -rf /usr/sbin/aliyun*
rm -rf /usr/local/aegis*
rm -rf /etc/systemd/system/aliyun.service
reboot
配置LNMP
安装
创建一个 screen 的实例:
screen -S lnmp
安装 LNMP 环境:
wget http://soft.vpser.net/lnmp/lnmp1.8.tar.gz -cO lnmp1.8.tar.gz && tar zxf lnmp1.8.tar.gz && cd lnmp1.8 && ./install.sh lnmp
全部选择默认选项即可。
查看所有的 screen 实例:
screen -ls
恢复到某一个 screen 实例(留空则恢复到上一个实例):
screen -r [实例名称]
创建虚拟主机
首先确保相关域名已经解析到服务器的 IP 上,之后就可以创建虚拟主机了。执行以下命令:
lnmp vhost add
根据情况选择选项即可,可根据情况部署 SSL 证书。
配置rewrite规则
如果有 HTTP 跳转 HTTPS,A 域名跳转 B 域名等需求,可以通过 rewrite 规则来实现。编辑配置文件:
nano /usr/local/nginx/conf/vhost/[域名].conf
找到 server {}
句块,加入跳转语句:
rewrite ^(.*)$ https://[目标域名]/$1 permanent;
如果需要条件跳转,则加入语句:
if ($host != '[匹配域名]'){
rewrite ^/(.*)$ https://[目标域名]/$1 permanent;
}
重启 Nginx 即可生效:
lnmp nginx restart
开放端口
LNMP 安装完成后,需要开放 HTTP 和 HTTPS 的端口。执行以下命令:
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --add-port=443/tcp --permanent
firewall-cmd --reload
配置frps
关于 frp 的原理和部署,之前已经在别的文章中讲解过了,因此这里只讲一下部署过程。
安装与配置
首先下载 frps。打开官方发布页 https://github.com/fatedier/frp/releases,根据服务器的架构和系统找到合适的版本。比如我的服务器是 X86-64 架构的,使用的是 CentOS 系统,所以选择 linux_amd64
版本的。右键复制链接地址。在终端中输入以下命令:
wget frp_0.38.0_linux_amd64.tar.gz # 复制的链接地址
tar xzvf frp_0.38.0_linux_amd64.tar.gz # 下载的文件名称
cd frp_0.38.0_linux_amd64 # 解压得到的文件夹名称
cp frps /usr/bin/frps
mkdir /etc/frp
cp frps.ini /etc/frp/frps.ini
编辑 frps 的配置文件:
nano /etc/frp/frps.ini
输入以下内容:
[common]
bind_port = [frps 端口]
token = [frps 口令]
log_file = /var/log/frps.log
dashboard_port = [frps 控制面板端口]
dashboard_user = [frps 控制面板用户名]
dashboard_pwd = [frps 控制面板密码]
解决无日志的问题
默认安装完成后,即便在配置文件中启用了日志功能,也无法看到日志,这是没有权限导致的。现在修改服务项的配置文件:
nano /usr/lib/systemd/system/frps.service
找到 User=nobody
,改为 User=root
,保存并退出即可。
重新加载服务项:
systemctl daemon-reload
最后就可以启动服务:
systemctl start frps
systemctl enable frps
开放端口
执行以下命令:
firewall-cmd --add-port=[frps 端口]/tcp --permanent
firewall-cmd --add-port=[frps 控制面板端口]/tcp --permanent
firewall-cmd --reload
如果有服务通过 frps 进行内网穿透,也要开放对应的端口。
配置Python
安装
执行以下命令:
yum install -y python3
测试是否安装成功:
python3
看见类似这样的输出:
Python 3.6.8 (default, Apr 16 2020, 01:36:27)
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
说明 Python 已经被成功安装了。
配置虚拟环境
首先安装 virtualenv:
pip3 install virtualenv
在当前目录下创建一个虚拟环境:
virtualenv -p python3 [虚拟环境名称]
激活虚拟环境:
source [虚拟环境名称]/bin/activate
退出当前的虚拟环境:
deactivate
使用systemd部署Gunicorn+Flask服务
创建一个新的 systemd 服务项:
nano /usr/lib/systemd/system/[服务名称].service
输入以下内容:
[Unit]
Description=[服务描述]
After=syslog.target network.target
[Service]
WorkingDirectory=[工作目录]
ExecStart=[Gunicorn 路径] [模组名称]:[实例名称] -b [监听地址]:[监听端口]
Restart=on-failure
[Install]
WantedBy=multi-user.target
工作目录:填写 Flask 项目的路径,如 /root/flask_app
。
Gunicorn 路径:填写 Gunicorn 可执行文件的路径,如 /root/flask_venv/bin/gunicorn
。
模组名称和实例名称:填写 Flask 应用的模组名称和实例名称,例如,名为 run.py
的文件中定义了 app = Flask()
,则填写 run:app
。
监听地址:如果希望通过 Nginx 代理给外部访问,则设置 127.0.0.1
;如果希望直接开放端口给外部访问,则设置 0.0.0.0
或服务器地址,并使用以下命令开放端口:
firewall-cmd --add-port=[监听端口]/tcp --permanent
firewall-cmd --reload
重新加载服务项:
systemctl daemon-reload
之后,就可以用 systemd 来管理服务了:
systemctl [start|stop|restart|kill|status] [服务名称]
配置Nginx代理
编辑对应的 Nginx 虚拟主机的配置文件:
nano /usr/local/nginx/conf/vhost/[域名].conf
在 server {}
中,添加代理代码:
location / {
proxy_pass http://[监听地址]:[监听端口];
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
如果有静态资源,也可以在上述代码片段之前加入以下代码:
location ^~ /static/ {
root [静态资源路径];
}
这样所有 /statis/
开头的请求都不会被转发,而会在静态资源路径中直接查找。
注意,如果请求的路径为 `/static/index.html`,则对应文件的位置应该在 `[静态资源路径]/static/index.html`。通常来说,*静态资源路径*不需要包含 `static` 字样。
安装Node.js
运行以下命令:
yum install -y nodejs
运行 node
产生类似这样的输出即为安装成功::
Welcome to Node.js v16.13.1.
Type ".help" for more information.
>
安装Java
运行以下命令:
yum install java-17-openjdk
运行 java --version
产生类似这样的输出即为安装成功:
openjdk 17.0.1 2021-10-19 LTS
OpenJDK Runtime Environment 21.9 (build 17.0.1+12-LTS)
OpenJDK 64-Bit Server VM 21.9 (build 17.0.1+12-LTS, mixed mode, sharing)