Class: LogStash::Filters::Forwarded
- Inherits:
-
Base
- Object
- Base
- LogStash::Filters::Forwarded
- Defined in:
- lib/logstash/filters/forwarded.rb
Overview
The forwarded filter extracts the client ip from a list of ip adresses. The client ip might be at any position in the list, since not every x-forwarded-for header comes in the correct ordering. It adds two new fields to the event:
- forwarded_client_ip : string
- forwarded_proxy_list : string[]
Instance Method Summary collapse
-
#analyse(ip) ⇒ Object
def filter.
- #filter(event) ⇒ Object
-
#get_client_ip(ip_array) ⇒ Object
def analyse.
- #is_private_ipv4(ipo) ⇒ Object
- #is_private_ipv6(ip) ⇒ Object
- #register ⇒ Object
-
#remove_port_number(ip) ⇒ Object
get_client_ip.
Instance Method Details
#analyse(ip) ⇒ Object
def filter
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/logstash/filters/forwarded.rb', line 66 def analyse(ip) return nil, nil if ip.nil? # convert the x-forwarded-for string into an array of its comma separated value, if it isn't already. ip_list = ip.is_a?(Array) ? ip : ip.downcase.split(",") # remove some well-known invalid values ip_list = ip_list.map { |x| x.strip }.reject { |x| ["-", "unknown"].include? x} # the IpAddr library cannot handle ips with port numbers ip_list = ip_list.map { |x| remove_port_number(x) } # get the first public ip in the list client_ip = get_client_ip(ip_list) # remove the public / client ip from the list and use the remainder as the list of proxies involved. proxies = ip_list.nil? ? nil : ip_list - [client_ip] return client_ip, proxies end |
#filter(event) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/logstash/filters/forwarded.rb', line 46 def filter(event) return unless filter?(event) begin forwarded = event.get(@source) return unless forwarded and !forwarded.empty? client_ip, proxies = analyse(forwarded) event.set(@target_client_ip, client_ip) if client_ip event.set(@target_proxy_list, proxies) if proxies filter_matched(event) rescue Exception => e @logger.debug("Unknown error while looking up GeoIP data", :exception => e, :field => @source, :event => event) # raise e end # begin end |
#get_client_ip(ip_array) ⇒ Object
def analyse
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/logstash/filters/forwarded.rb', line 86 def get_client_ip(ip_array) ip_array.each do | ip | begin next if !IPAddress.valid? ip ipo = IPAddr.new(ip) is_private = ipo.ipv6? ? is_private_ipv6(ip) : is_private_ipv4(ipo) return ip if !is_private rescue => e # not a valid ip, moving on. # @logger.debug("get_client_ip() failed", :exception => e, :field => @source, :ip_array => ip_array) next end end # each nil end |
#is_private_ipv4(ipo) ⇒ Object
113 114 115 116 117 118 119 120 121 122 |
# File 'lib/logstash/filters/forwarded.rb', line 113 def is_private_ipv4(ipo) begin @private_ipv4_ranges.each do | ip_range | return true if ip_range.include?(ipo) end # each false rescue => e @logger.debug("Couldn't check if ip is private.", :input_data => ip, :exception => e) end # begin end |
#is_private_ipv6(ip) ⇒ Object
108 109 110 |
# File 'lib/logstash/filters/forwarded.rb', line 108 def is_private_ipv6(ip) ip.start_with?("fd") || ip.start_with?("fc") end |
#register ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/logstash/filters/forwarded.rb', line 33 def register @private_ipv4_ranges = @private_ipv4_prefixes.collect do | adress | begin IPAddr.new(adress) rescue ArgumentError => e @logger.error("Register: invalid IP network, skipping", :adress => adress, :exception => e) raise e end end @private_ipv4_ranges.compact! end |
#remove_port_number(ip) ⇒ Object
get_client_ip
103 104 105 106 |
# File 'lib/logstash/filters/forwarded.rb', line 103 def remove_port_number(ip) tokens = ip.split(":") if tokens.size <=2 then tokens[0] else ip end end |