Logstash - IP 与 CIDR

问题描述 投票:0回答:3

我使用 CIDR 过滤器来检查 IP 是否在某些子网内。 我需要:

cidr {
                id => "netflow-postproc-cidr-src_addr"
                address => [ "%{[@metadata][netflow][src_addr]}" ]
                network => [ "0.0.0.0/32", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fc00::/7", "127.0.0.0/8", "::1/128", "169.254.0.0/16", "fe80::/10", "224.0.0.0/4", "ff00::/8", "255.255.255.255/32", "::" ]
                add_field => { "[@metadata][netflow][src_locality]" => "private" }
            }

我需要的是获取哪个子网具有匹配的IP,而不仅仅是“至少一个”。

例如,如果我有 172.16.0.10,我需要用 172.16.0.0/12 填写新字段

举例说明我需要什么

cidr {
     id => "netflow-cidr-src_addr"
     address => [ "%{[@metadata][netflow][src_addr]}" ]
     network_path => "/etc/logstash/dictionaries/internal_subnet.yml"
     add_field => { "[@metadata][netflow][src_subnet]" => "<subnet_that_match>" }
      }
logstash
3个回答
0
投票

如果您需要对 13 个网络中的每一个进行不同的标记,那么您将需要使用 13 个不同的 cidr 过滤器。


0
投票

似乎没有解决方案,所以我找到了解决方法。 了解每个 CIDR,我编写了一个 python 程序来为每个子网中的每个 IP 创建一个 memcached 条目。

all_su = Subnet.objects.all()
for iss in all_su:
    net = ip_network(iss.cidr)
    ## ITERATING ALL IP INSIDE CIDR
    for i in net:
       #creating memcached entry

所以在 memcahced 中我有这样的东西:

subnet-namespace:172.16.0.10-subnet-cidr = 172.16.0.0/12
subnet-namespace:172.16.0.11-subnet-cidr = 172.16.0.0/12
subnet-namespace:172.16.0.12-subnet-cidr = 172.16.0.0/12
[...]

然后在logstash中我可以使用默认过滤器签入memcached:

memcached {
                hosts => ["localhost:11211"]
                namespace => "subnet-namespace"
                get => {
                    "%{[source][ip]}-subnet-cidr"           => "[source][subnet]                
                }
                add_tag => ["source_subnet_cached"]
    }

0
投票

您可以尝试使用 ruby 过滤器。

我这里有一个类似的用例,我需要使用有关源网络的信息来标记事件。

我们的域中有数百个范围,这些解决方案在我的环境中表现非常好。

我使用 CIDR 过滤器来识别 IP 是否属于任何内部网络 cidrs,然后使用 ruby 过滤器查看 json 文件 由使用 CIDR 作为密钥的单个对象组成。

如果您有子网地理位置数据,您甚至可以包含地理定位数据。

JSON 文件是这样的:

{
"10.0.0.0/24": {
    "network_name": "network_of_division_1",
    "network_region": "SouthWest",
    "city": "some_city_name",
    "latitude": 10,
    "longitude": 20,
    "province": "some_province_name"
},
"10.0.120.0/24": 
    "network_name": "network_of_division_2",
    "network_region": "North",
    "city": "some_city_name",
    "latitude": 10,
    "longitude": 20,
    "province": "some_province_name"
},
...

}

过滤器代码如下:

filter{
# remove field if IP is not valid
if [source_ip] !~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ {
    mutate{
        remove_field => ["source_ip"]
    }
} else {
    # Tag for IPs in internal ranges
    cidr{
        address =>  "%{source_ip}"
        network => [  "10.0.0.0/8", "172.0.0.0/12", "192.168.0.0/16" ]
        add_field => { "[CIP]" => "1" }
    }
    # Tag if IP is localhost
    cidr{
        address => "%{source_ip}"
        network => ["0.0.0.0/32","127.0.0.0/8"]
        add_field => {"[LOOPBACK]" => 1 }
    }
}

if [source_ip] and ![LOOPBACK]{
    # If IP is in internal ranges
    if [CIP] {
        ruby {
            # Load the hash with network information
            init => "
                require 'json'
                require 'ipaddr'
                # Load json with information about the networks the structure is an object with the cidr as keys
                networks = File.read('networks.json')
                # Transform keys into strings - so you can use it
                @@data_hash = JSON.parse(networks).transform_keys(&:to_s)
                # Transform keys into IPAddr to perform the matching with CIDR
                @@networks = @@data_hash.keys.map do |net_string|
                    IPAddr.new(net_string)
                end
            "
            code => "
            # Get source IP and transform it into an IPAddr obj
            source_ip_string = event.get('source_ip')
            source_ip_obj = IPAddr.new(source_ip_string)
            # Set a variable to stop the loop immediatly once the network has been found
            found = false
            # Loop through the hash of networks
            for net in @@networks do
                break if found != false
                if net === source_ip_obj
                    found = true
                    # Get a pointer to the network object
                    net_string = net.to_s + '/' + net.prefix.to_s
                    net_data = @@data_hash[net_string]
                    # Insert the data accordinglly ie.:
                    event.set('source_network', net_string)
                    event.set('source_network_name', net_data['network_name'])
                    event.tag(net_string)
                end
            end
            "
        }
    }
}

}

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.