使用 rsync 与 mariadb-dump 备份 freebsd jail 中网站与数据库
1. 使用 rsync 备份网站(适合内网)
为了在不影响宿主机 22 端口的前提下使用 rsync,最标准且高效的做法是:在 web_jail 内部开启一个独立的、仅供备份使用的 rsync 守护进程(Daemon 模式),监听标准的 873 端口。然后通过宿主机 PF 将外部非标端口(如 40873)映射进去。这样可以完全避开 ssh(22 端口)的冲突,且备份速度极快。
- 在 web_jail 内部配置 rsync 守护进程
- 进入 web_jail
1
jexec web_jail csh
- 安装 rsync
1
pkg install rsync
- 创建并编辑 rsync 配置文件 /usr/local/etc/rsync/rsyncd.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17# 运行用户和组,必须是 www 才能读取网站内容
uid = www
gid = www
use chroot = no
max connections = 4
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
# 定义一个备份模块叫 [backup_site]
[backup_site]
path = /usr/local/www/mywebsite
comment = My Website Content
read only = yes ; 备份只需只读,保证安全性
list = yes
auth users = backupuser ; 备份专有虚拟账号
secrets file = /usr/local/etc/rsyncd.secrets
hosts allow = 10.0.0.1 192.168.1.0/24 ; 仅允许宿主机网关和局域网网段访问 - 创建密码文件 /usr/local/etc/rsyncd.secrets(格式为 用户名:密码):
1
backupuser:你的备份密钥明文
- 极其重要: 修改密码文件的权限,rsync 要求该文件必须是 600 权限,否则拒绝启动:
1
chmod 600 /usr/local/etc/rsyncd.secrets
- 开启 rsync 自启并启动它:
1
2sysrc rsyncd_enable=YES
service rsyncd start
- 进入 web_jail
- 在宿主机修改 pf 防火墙映射端口
- 编辑宿主机的 /etc/pf.conf,将局域网的 40873 端口转发给 web_jail 的 873 端口:
1
2# add rsync forward rule, any host's 40873 forward to web jail 873
rdr on $ext_if proto tcp from any to ($ext_if) port 40873 -> $web_jail port 873 - 重载防火墙:
1
service pf restart
- 编辑宿主机的 /etc/pf.conf,将局域网的 40873 端口转发给 web_jail 的 873 端口:
- 局域网内其它电脑执行备份命令
- 在局域网的备份服务器上,你只需要先创建一个密码文件 /etc/rsync.pass
1
echo "你的备份密钥明文" > /etc/rsync.pass
- 必须限制权限(Rsync 客户端规定,如果密码文件权限不是 600,会直接报错拒绝运行):
1
chmod 600 /etc/rsync.pass
- 执行 rsync 备份命令
1
rsync -avz --progress --password-file=/etc/rsync.pass backupuser@your_host_ip_address::backup_site /your_local_backup_path/ --port=40873
- 在局域网的备份服务器上,你只需要先创建一个密码文件 /etc/rsync.pass
2. 使用 mariadb-dump 备份 mariadb 数据库
对于数据库备份,mariadb-dump 本质上是一个数据库客户端工具,它可以通过 tcp 网络远程连接到 mariadb 服务端。我们只需:在宿主机 pf 防火墙上将局域网的非标端口(如 43306)转发到 mariadb_jail 的 3306 端口,并在数据库内授予特定的备份账号远程访问权限。
- 在宿主机修改 PF 防火墙映射端口
- 编辑宿主机的 /etc/pf.conf:
针对限定只能由宿主机网关访问针对整个网段访问1
2
3# 找到原来那句 mariadb 转发规则,修改为如下(注意末尾追加了 nat-to $int_if)
# 这会让所有经过此端口的外部局域网流量,在进入 jail 时其源 ip 都变成宿主机网关 lo1 的 ip (10.0.0.1)
rdr on $ext_if proto tcp from 192.168.1.0/24 to ($ext_if) port 43306 -> $mariadb_jail port 3306 nat-to $int_if1
2# add mariadb forward rule, any host's 43306 forward to mariad jail 3306
rdr on $ext_if proto tcp from any to ($ext_if) port 43306 -> $mariadb_jail port 3306 - 重载防火墙:
1
service pf restart
- 编辑宿主机的 /etc/pf.conf:
- 在 mariadb_jail 内授权局域网备份账号
- 进入 mariadb_jail:
1
jexec mariadb_jail csh
- 登录 mariadb 命令行:
1
mariadb -u root -p
- 创建一个专门用于备份的账号
限定只能由宿主机网关(进行过 NAT 转换后的局域网请求在 jail 看来是由宿主机网关 10.0.0.1 发出的)访问:或者整个网段都可以访问1
2
3
4CREATE USER 'db_backup'@'10.0.0.1' IDENTIFIED BY 'your_maraidb_backup_password';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'db_backup'@'10.0.0.1';
FLUSH PRIVILEGES;
EXIT;1
2
3
4CREATE USER 'db_backup'@'%' IDENTIFIED BY 'your_maraidb_backup_password';
GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON *.* TO 'db_backup'@'%';
FLUSH PRIVILEGES;
EXIT; - 退出 jail:
1
exit
- 进入 mariadb_jail:
- 局域网内其它电脑执行备份命令或者
1
mariadb-dump -h your_host_ip_address -P 43306 -u db_backup -pyour_maraidb_backup_password --all-databases > /your_local_backup_path/all_databases_backup.sql
1
mariadb-dump --skip-ssl --add-drop-database -h your_host_ip_address -P 43306 -u root -pyour_mariadb_backup_password --databases backup_database_name | gzip > hd.sql.gz
3. 使用 rsync 备份网站(适合公网)
要在公网环境下使用 rsync 远程备份 web_jail 中的内容,安全性是首要考虑的问题。由于之前的局域网方案使用的是纯 tcp 协议的 rsync 守护进程(Daemon 模式),其数据在网络上是明文传输的。如果直接暴露到公网,不仅密码容易被拦截,还容易遭受扫描攻击。在公网环境下,最安全、标准的做法是:利用 ssh 隧道技术(或通过 pf 进行非标 ssh 端口转发)在 web_jail 内部署独立的 ssh 服务,实现全加密传输。由于外网的动态 ip 随时会变,我们还需要配合之前配置的 DDNS(动态域名)。以下是完整的公网 rsync 安全备份设置步骤:
- 在 web_jail 内部配置独立的 SSH 备份通道
为了不影响宿主机 22 端口的正常运维,我们直接在 web_jail 内部开启它自己的 sshd 服务,用于接收外网的 rsync 加密流量。- 进入 web_jail:
1
jexec web_jail csh
- 生成 jail 内部的 ssh 密钥对(首次启动 sshd 需要):
1
ssh-keygen -A
- 开启 sshd 自启并启动它:
1
2sysrc sshd_enable=YES
service sshd start - 创建一个用于外网备份的普通用户(绝对不要用 root 跑外网 rsync):
1
2
3# 创建名为 rsync_user 的用户,专门用于外网备份
pw useradd rsync_user -m -s /bin/sh
passwd rsync_user # 为其设置一个极其复杂的强密码 - 退出 jail
1
exit
- 进入 web_jail:
- 在宿主机修改 PF 防火墙(开放外网非标端口)
我们需要在宿主机上挑一个极不容易被扫描到的非标端口(例如 42022),将其映射到 web_jail 内部的 22 端口。- 打开宿主机的 /etc/pf.conf:
1
ee /etc/pf.conf
- 增加一条允许来自任何外网(any)访问 42022 的转发规则:
1
2# add ssh forward rule, any host's 42022 forward to web jail ssh port 22
rdr on $ext_if proto tcp from any to ($ext_if) port 42022 -> $web_jail port 22 - 重载防火墙:
1
service pf restart
- 打开宿主机的 /etc/pf.conf:
- 为外网备份机配置 ssh 密钥登录
把 ssh 端口暴露给外网会面临暴力破解风险。最佳方案是禁用密码,改用公钥认证。- 在您的外网备份机上,生成一对密钥(如果已有则跳过):
1
ssh-keygen -t ed25519
- 将外网备份机的公钥(~/.ssh/id_ed25519.pub 的内容),复制并写入到 web_jail 内部刚刚创建的用户的授权文件中。
在宿主机上快速操作的命令如下:1
2
3
4
5
6
7
8
9
10# 创建目标文件夹
mkdir -p /usr/local/jails/web_jail/home/rsync_ext/.ssh
# 将您的外网机公钥粘贴进该文件
ee /usr/local/jails/web_jail/home/rsync_ext/.ssh/authorized_keys
# 修正权限(SSH 对权限要求极严,否则无法登录)
chown -R 1002:1002 /usr/local/jails/web_jail/home/rsync_ext/.ssh # 如果 rsync_user 的 UID 不是 80 请对应修改
chmod 700 /usr/local/jails/web_jail/home/rsync_ext/.ssh
chmod 600 /usr/local/jails/web_jail/home/rsync_ext/.ssh/authorized_keys
- 在您的外网备份机上,生成一对密钥(如果已有则跳过):
- 在外网备份机上执行公网 rsync
此时,所有的安全链路已经搭建完毕。在外网的备份机上,你不再需要像局域网那样使用双冒号 :: 模式,而是直接使用标准基于 ssh 的 rsync 命令。由于宿主机的 ip 是动态的,这里直接使用您之前做好的 DDNS 域名。在外网备份机上执行以下命令:1
rsync -ae "ssh -p 42022" rsync_user@your_ddns_domain_or_your_ip_address:/usr/local/www/mywebsite/ /your_backup_path/