Python在Linux环境获取出口IP

该代码段展示了如何在Linux环境中使用Python获取出口IP,并过滤出非docker0和lo接口的IP。通过正则表达式提取IP,再进行有效性校验,确保不是多播或回环地址。最后,将有效IP写入geo配置白名单文件。

Python在Linux环境获取出口IP

  1. 先使用ifconfig命令查看当前接口IP的信息
  2. 得到返回的数据str内容,按照" "空格劈开
  3. “inet”字段后面为出口ip的字段,但是可能会有一些杂文
  4. 排除docker0的IP
  5. 使用正则表达式提取出完整的ip,校验ip是否是多播或者回环
  6. 把ip写入geo配置白名单文件中

代码如下:

# -*- coding: utf-8 -*-
import re
import ipaddress
from subprocess import Popen, PIPE

geo_file_path = '/etc/nginx/geo.conf'

re_ipv4 = r'(?:(?:1[0-9][0-9]\.)|(?:2[0-4][0-9]\.)|(?:25[0-5]\.)|' \
          r'(?:[1-9][0-9]\.)|(?:[0-9]\.)){3}(?:(?:1[0-9][0-9])|' \
          r'(?:2[0-4][0-9])|(?:25[0-5])|(?:[1-9][0-9])|(?:[0-9]))'


def _exec_ip_cmd(cmd):
    """
    执行查询IP命令
    :param cmd: 查询IP的命令
    :return:
    """
    p = Popen(cmd, shell=True, stdout=PIPE, universal_newlines=True)
    data_str = p.stdout.read()
    if not data_str:
        return ""
    data_str_list = data_str.split(" ")
    ip_str_list = []

    # 排除docker0和lo口
    is_docker0 = False
    for i in range(len(data_str_list)):
        if "docker0:" in data_str_list[i]:
            is_docker0 = True

        if data_str_list[i] == 'inet':
            if not is_docker0:  # 出口ip
                ip_str_list.append(data_str_list[i + 1])
            else:
                # 排除掉docker0和lo口,遇到inet则恢复状态
                is_docker0 = False
    return ip_str_list


def _get_valid_ipv4(use_cmd="ip address"):
    """
    :param use_cmd: 使用查询IP的命令
    :return:
    """
    ip_str_list = _exec_ip_cmd(cmd=use_cmd)
    ret_data = []
    for ip_str in ip_str_list:
        if not isinstance(ip_str, str):
            return []
        result = re.findall(re_ipv4, ip_str)
        if result:
            ret_data.extend(result)
    return list(set(ret_data))


def check_uincast_ip(value):
    """
    检查IP是否是一个可用IP
    :param value:
    :return:
    """
    if not isinstance(value, unicode):
        value = unicode(value)
    try:
        ip_verison = ipaddress.ip_address(value).version
    except Exception as msg:
        return False
    if int(ip_verison) == 4:
        if int(value.split('.')[0]) == 0 or int(value.split('.')[0]) == 255:
            return False
        elif ipaddress.IPv4Network(value).is_multicast:
            return False
        elif ipaddress.IPv4Network(value).is_loopback:
            return False
    return True


def _get_ip_list(ip_data):
    ip_list = []
    for row in ip_data:
        if not check_uincast_ip(row):
            continue
        ip_list.append(row)
    return ip_list


def get_ip_by_ifconfig():
    try:
        ip_data = _get_valid_ipv4("ifconfig")
        return _get_ip_list(ip_data)
    except Exception as e:
        traceback.print_exc()
        return []


def get_ip_by_ip_addr():
    try:
        ip_data = _get_valid_ipv4("ip -f inet addr")
        return _get_ip_list(ip_data)
    except Exception as e:
        traceback.print_exc()
        return []


def write_geo_conf_file():
    """
    把出口IP写到nginx的geo里
    :return: 
    """
    ip_list = get_ip_by_ifconfig()
    ip_write_str = []
    for ip in ip_list:
        ip_write_str.append("{0} 1;\n".format(ip))
    ip_write_str = "".join(ip_write_str)
    with open(geo_file_path, 'wb') as f:
        f.write(ip_write_str)

    print("=========> write nginx geo config success!")
    print("=========> iplist %s" % str(ip_list))
    print("=========> end! ")


if __name__ == '__main__':
    write_geo_conf_file()

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值