【备份】

  • 目标:每晚一点,将 iptables 规则导出到本地,并备份到 FTP 服务器。

  • config.ini

[config]
;本地备份目录
LocalBakFile=/home/walker/iptables_rules_bak/iptables.rules
;FTP 主机
FtpHost=192.168.30.xx 
;FTP 目录
FtpBakRoot=iptables_bak
;FTP 用户名  
FtpUser=ftpadmin
;FTP 密码
FtpPwd=ftppwd
  • iptablesbak2ftp.py

# encoding: utf-8
# author: walker
# date: 2019-02-22 
# summary: Python3 备份 iptables 规则(本地+FTP) 

import os
import sys
import time
import pprint
import psutil
from configparser import ConfigParser
from ftplib import FTP

cur_dir_fullpath = os.path.dirname(os.path.abspath(__file__))

LocalBakFile = ''   # 本地备份文件
LocalIP = ''

FtpHost = ''        # FTP 主机
FtpBakRoot = ''     # FTP 目录
FtpUser = ''
FtpPwd = ''

def ReadConfig(): 
    r""" 读取配置文件 """
    global LocalBakFile
    global FtpHost, FtpBakRoot, FtpUser, FtpPwd
      
    cfg = ConfigParser()
    # cfg.optionxform = str   # 保持键的大小写
    cfgFile = os.path.join(cur_dir_fullpath, 'config.ini')
    if not os.path.exists(cfgFile):
        input(cfgFile + ' not found')
        sys.exit(-1)
    with open(cfgFile, mode='rb') as f:
        content = f.read()
    if content.startswith(b'\xef\xbb\xbf'):     # 去掉 utf8 bom 头
        content = content[3:]
    cfg.read_string(content.decode('utf8'))
    if not cfg.sections():
        input('Read config.ini failed...')
        sys.exit(-1)          

    LocalBakFile = cfg.get('config', 'LocalBakFile').strip()
    if not os.path.exists(LocalBakFile):
        print('Error: not exists %s' % LocalBakFile)
        sys.exit(-1)

    FtpHost = cfg.get('config', 'FtpHost').strip()
    FtpBakRoot = cfg.get('config', 'FtpBakRoot').strip()
    FtpUser = cfg.get('config', 'FtpUser').strip()
    FtpPwd = cfg.get('config', 'FtpPwd').strip()

    print('LocalBakFile: %s' % LocalBakFile)
    print('FtpHost: %s' % FtpHost)
    print('FtpBakRoot: %s' % FtpBakRoot)
    print('FtpUser: %s' % FtpUser)
    print('FtpPwd: %s' % FtpPwd)
          
    print('Read config.ini successed!')

def GetLocalIPByPrefix(prefix):
    r""" 根据前缀获取IP """
    localIP = ''
    dic = psutil.net_if_addrs()
    for adapter in dic:
        snicList = dic[adapter]
        for snic in snicList:
            if not snic.family.name.startswith('AF_INET'):
                continue
            ip = snic.address
            if ip.startswith(prefix):
                localIP = ip
      
    return localIP
  
def Main():
    filename = '%s_%s.iptables_rules' % (time.strftime('%Y%m%d', time.localtime()), LocalIP)
    cmd = '/sbin/iptables-save > %s' % LocalBakFile
    print('cmd: %s' % cmd)
    rtn = os.system(cmd)
    if 0 != rtn:
        print('Error: 0 != rtn')
        return False

    ftp = FTP()
    ftp.encoding = 'gb18030'
    ftp.set_pasv(False)
    ftp.connect(FtpHost, port=21, timeout=10)
    ftp.login(user=FtpUser, passwd=FtpPwd)

    print(ftp.getwelcome())
    ftp.cwd(FtpBakRoot)
    # 以 sql 服务器 ip 作为子目录名
    if LocalIP not in ftp.nlst():
        ftp.mkd(LocalIP)       # 创建子目录
    ftp.cwd(LocalIP)
    with open(LocalBakFile, mode='rb') as f:
        ftp.storbinary('STOR ' + filename, f)

    return True    
                                          
if __name__ == '__main__':
    ReadConfig()
    LocalIP = GetLocalIPByPrefix('192.168.30.')
    Main()
  • iptables_bak.sh

python3 -u /home/walker/Python3Project/iptablesbak2ftp/iptablesbak2ftp.py > /home/walker/Python3Project/iptablesbak2ftp/log.log 2>&1
  • 定时任务

# m h  dom mon dow   command
# 每晚一点执行
0  1  *  *  *  /home/walker/Python3Project/iptablesbak2ftp/iptables_bak.sh


【还原】

  • 目标:开机自动还原备份的 iptables 规则

  • 创建文件:/etc/systemd/system/rc-local.service

  • 在 rc-local.service 里面添加如下内容

[Unit]
Description=/etc/rc.local Compatibility
ConditionPathExists=/etc/rc.local
After=network.target

[Service]
Type=forking
ExecStart=/etc/rc.local start
TimeoutSec=0
StandardOutput=tty
RemainAfterExit=yes
SysVStartPriority=99

[Install]
WantedBy=multi-user.target
  • 创建文件:/etc/rc.local 并添加如下内容

#!/bin/bash
/sbin/iptables-restore < /home/walker/iptables_rules_bak/iptables.rules
exit 0
  • 给 rc.local 添加可执行权限

sudo chmod 754 /etc/rc.local
  • 启用服务(开机自启动)

sudo systemctl enable rc-local
# 等价于
ln -s /etc/systemd/system/rc-local.service /etc/systemd/system/multi-user.target.wants/
  • 启动服务并检查状态

sudo systemctl start rc-local.service
sudo systemctl status rc-local.service
  • 重启服务器检查是否能够开机启动


【相关链接】

  • Ubuntu Server 18.04 与 OpenVPN 2.x

  • iptables tips

  • ubuntu-18.04 设置开机启动脚本


*** walker ***