Python在Linux环境获取出口IP
- 先使用ifconfig命令查看当前接口IP的信息
- 得到返回的数据str内容,按照" "空格劈开
- “inet”字段后面为出口ip的字段,但是可能会有一些杂文
- 排除docker0的IP
- 使用正则表达式提取出完整的ip,校验ip是否是多播或者回环
- 把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()

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

被折叠的 条评论
为什么被折叠?



