Sunday, June 4, 2017

Getting the last argument passed to a shell script

This is a bit of a hack:
for last; do true; done
echo $last
This one is also pretty portable (again, should work with bash, ksh and sh) and it doesn't shift the arguments, which could be nice.
It uses the fact that for implicitly loops over the arguments if you don't tell it what to loop over, and the fact that for loop variables aren't scoped: they keep the last value they were set to.

Parsing firewall rules in Python

parts = rule.split(" ")
aclName, _, lineNumber, _, action, protocol = parts[:6]
endpoints = parts[6:]

def get_endpoint(eps):
    host, port = "*", "*"
    if eps[0] == "host":
        host = eps[1]
        eps = eps[2:]
    elif eps[0] == "any":
        eps = eps[1:]
    else:
        host = eps[0] + "/" + mask_to_bits(eps[1])
        eps = eps[2:]

    if eps and eps[0] == 'eq':
        port = eps[1]
        eps = eps[2:]
    return host, port, eps

sourceIP, sourcePort, endpoints = get_endpoint(endpoints)
destIP, destPort, endpoints = get_endpoint(endpoints)
https://stackoverflow.com/questions/10196998/parsing-firewall-rules-in-python

FIREWALL RULES HACKING ON 10.0.0.217 HOST FILTER

Translate ip on cidr keys to values


require "logstash/namespace"
require "json"
require "csv"
+require "netaddr"
java_import 'java.util.concurrent.locks.ReentrantReadWriteLock'
@@ -106,10 +107,14 @@ class LogStash::Filters::Translate < LogStash::Filters::Base
# keys as regular expressions. A large dictionary could be expensive to match in this case.
config :exact, :validate => :boolean, :default => true
- # If you'd like to treat dictionary keys as regular expressions, set `exact => true`.
+ # If you'd like to treat dictionary keys as regular expressions, set `regex => true`.
# Note: this is activated only when `exact => true`.
config :regex, :validate => :boolean, :default => false
+ # If you'd like to treat dictionary keys as ip cidr, set `cidr => true`.
+ # Note: this is activated only when `exact => true`.
+ config :cidr, :validate => :boolean, :default => false
+
# In case no translation occurs in the event (no matches), this will add a default
# translation string, which will always populate `field`, if the match failed.
#
@@ -187,6 +192,12 @@ def filter(event)
event[@destination] = lock_for_read { @dictionary[key] }
matched = true
end
+ elsif @cidr
+ key = @dictionary.keys.detect{ |k| NetAddr::CIDR.create(k).matches?(source) }
+ if key
+ event[@destination] = lock_for_read { @dictionary[key] }
+ matched = true
+ end
elsif @dictionary.include?(source)
event[@destination] = lock_for_read { @dictionary[source] }
matched = true
@@ -21,7 +21,7 @@ Gem::Specification.new do |s|
# Gem dependencies
s.add_runtime_dependency "logstash-core-plugin-api", "~> 1.0"
+ s.add_runtime_dependency "netaddr", "~> 1.5"
- s.add_development_dependency 'logstash-devutils'
+ s.add_development_dependency 'logstash-devutils', '~> 0'
end
-
@@ -81,6 +81,141 @@
end
end
+ describe "cidr net translation" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/32", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => true
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "10.0.1.43") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("Net")
+ end
+ end
+
+ describe "cidr host translation" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/32", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => true
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "10.0.0.1") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("Host")
+ end
+ end
+
+ describe "cidr duplicate translation first hit" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/8", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => true
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "10.0.1.43") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("Host")
+ end
+ end
+
+ describe "cidr wrong ip" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/16", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => false,
+ "fallback" => "no match"
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "260.0.1.43") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("no match")
+ end
+ end
+
+ describe "cidr wrong translation" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/33", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => false,
+ "fallback" => "no match"
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "10.0.0.1") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("no match")
+ end
+ end
+
+ describe "cidr fallback" do
+
+ let(:config) do
+ {
+ "field" => "ip",
+ "destination" => "translation",
+ "dictionary" => [ "10.0.0.1/32", "Host",
+ "10.0.1.1/24", "Net" ],
+ "exact" => true,
+ "cidr" => true,
+ "fallback" => "no match"
+ }
+ end
+
+ let(:event) { LogStash::Event.new("ip" => "10.0.0.43") }
+
+ it "return the exact translation" do
+ subject.register
+ subject.filter(event)
+ expect(event["translation"]).to eq("no match")
+ end
+ end
+
describe "fallback value" do
context "static configuration" do https://github.com/logstash-plugins/logstash-filter-translate/pull/31/files

Cielo e terra (duet with Dante Thomas)