You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3+OSX 10.13.2获取Facebook IP白名单时subprocess调用报错排查

解决OSX 10.13.2下用Python3调用subprocess获取Facebook ASN路由段的问题

看起来你在构建Facebook Webhook白名单时踩了OSX whois工具和subprocess参数传递的坑,我来帮你一步步理清问题并解决:

问题根源分析

  • OSX whois与Linux的参数差异:你用的-i origin AS32934是Linux系统whois(比如Ubuntu的whois)的专属参数,但OSX自带的whois不支持这个格式,这就是为什么会提示"-i后属性名无效或不支持"的核心原因。
  • whois服务器未返回路由数据:OSX默认的whois服务器不会主动返回ASN对应的路由条目,必须指定专门的路由查询whois服务器才能拿到有效数据。
  • subprocess的管道与退出码问题:当你拆分调用grep时,如果前面的whois输出没有匹配到"route",grep会返回退出码1,而check_output/check_call默认会把非0退出码视为错误抛出CalledProcessError。

分步解决方案

1. 先在终端验证正确的whois命令

在OSX终端里,要获取AS32934(Facebook)的路由段,必须用以下命令:

whois -h whois.radb.net '!gAS32934'

这个命令指定了whois.radb.net(专门的路由查询服务器),用!gAS<ASN>的格式来查询该ASN的所有路由条目。执行后你应该能看到一堆以route:开头的行。

如果要过滤出纯路由条目,可以加上grep:

whois -h whois.radb.net '!gAS32934' | grep -i 'route:'

2. 在Python中用subprocess正确调用

推荐两种实现方式,优先选第一种(更安全,避免shell注入风险):

方式一:不用shell=True,用subprocess管道连接命令

import subprocess

def get_facebook_routes():
    try:
        # 第一步:调用whois获取AS32934的路由数据
        whois_proc = subprocess.run(
            ['whois', '-h', 'whois.radb.net', '!gAS32934'],
            capture_output=True,
            text=True,
            check=True
        )
        # 第二步:用grep过滤route行,设置check=False避免无匹配时报错
        grep_proc = subprocess.run(
            ['grep', '-i', 'route:'],
            input=whois_proc.stdout,
            capture_output=True,
            text=True,
            check=False
        )
        # 提取并整理路由IP段
        routes = [line.split(':')[1].strip() for line in grep_proc.stdout.splitlines() if line.strip()]
        return routes
    except subprocess.CalledProcessError as e:
        print(f"whois命令执行出错: {e.stderr}")
        return []

方式二:用shell=True(简单但仅适合固定命令场景)

import subprocess

def get_facebook_routes():
    try:
        cmd = "whois -h whois.radb.net '!gAS32934' | grep -i 'route:'"
        output = subprocess.check_output(cmd, shell=True, text=True, stderr=subprocess.STDOUT)
        routes = [line.split(':')[1].strip() for line in output.splitlines() if line.strip()]
        return routes
    except subprocess.CalledProcessError as e:
        print(f"命令执行出错: {e.output}")
        return []

3. 构建FACEBOOK_WHITELIST

拿到路由列表后,可以用Python的ipaddress模块处理CIDR格式,方便后续验证请求IP:

import ipaddress

# 获取Facebook路由段并转换为可验证的网络对象
FACEBOOK_ROUTES = get_facebook_routes()
FACEBOOK_WHITELIST = [ipaddress.ip_network(route, strict=False) for route in FACEBOOK_ROUTES]

# 验证示例:检查某个IP是否属于Facebook白名单
def is_facebook_ip(ip_str):
    try:
        ip = ipaddress.ip_address(ip_str)
        return any(ip in network for network in FACEBOOK_WHITELIST)
    except ValueError:
        return False

为什么之前的方法失败?

  • 你用的-i origin AS32934是Linux whois的专属参数,OSX whois不支持,换成指定whois.radb.net服务器和!gAS32934查询格式就解决了路由数据为空的问题。
  • 之前的subprocess调用中,因为whois没有返回有效路由数据,导致grep找不到匹配项返回1,触发了CalledProcessError,现在通过管道传递输入或设置check=False完美规避了这个问题。

内容的提问来源于stack exchange,提问作者joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:09:02