diff options
author | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:05:14 +0100 |
---|---|---|
committer | Stefan Wintermeyer <stefan.wintermeyer@amooma.de> | 2012-12-17 12:05:14 +0100 |
commit | eaad37485fe59d0306c37cc038dda6d210052910 (patch) | |
tree | 072c4b0e33d442528555b82c415f5e7a1712b2b0 /misc/freeswitch/scripts/event/perimeter.lua | |
parent | 3e706c2025ecc5523e81ad649639ef2ff75e7bac (diff) | |
parent | b80bd744ad873f6fc43018bc4bfb90677de167bd (diff) |
Merge branch 'develop'
Diffstat (limited to 'misc/freeswitch/scripts/event/perimeter.lua')
-rw-r--r-- | misc/freeswitch/scripts/event/perimeter.lua | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/misc/freeswitch/scripts/event/perimeter.lua b/misc/freeswitch/scripts/event/perimeter.lua new file mode 100644 index 0000000..3babba6 --- /dev/null +++ b/misc/freeswitch/scripts/event/perimeter.lua @@ -0,0 +1,106 @@ +-- Gemeinschaft 5 module: cdr event handler class +-- (c) AMOOMA GmbH 2012 +-- + +module(...,package.seeall) + + +function handler_class() + return Perimeter +end + + + +Perimeter = {} + +MALICIOUS_CONTACT_COUNT = 20; +MALICIOUS_CONTACT_TIME_SPAN = 2; +BAN_FUTILE = 2; + +function Perimeter.new(self, arg) + arg = arg or {} + object = arg.object or {} + setmetatable(object, self); + self.__index = self; + self.log = arg.log; + self.class = 'cdrsave' + self.database = arg.database; + self.domain = arg.domain; + + self.ip_address_table = {} + self:init(); + + return object; +end + + +function Perimeter.event_handlers(self) + return { CUSTOM = { ['sofia::pre_register'] = self.sofia_pre_register } } +end + + +function Perimeter.init(self) + local config = common.configuration_file.get('/opt/freeswitch/scripts/ini/perimeter.ini'); + if config and config.general then + self.malicious_contact_count = tonumber(config.general.malicious_contact_count) or MALICIOUS_CONTACT_COUNT; + self.malicious_contact_time_span = tonumber(config.general.malicious_contact_time_span) or MALICIOUS_CONTACT_TIME_SPAN; + self.ban_futile = tonumber(config.general.ban_futile) or BAN_FUTILE; + self.execute = config.general.execute; + end + + self.log:info('[perimeter] PERIMETER - setup perimeter defense - config: ', self.malicious_contact_count, '/', self.malicious_contact_time_span, ', execute: ', self.execute); +end + + +function Perimeter.sofia_pre_register(self, event) + local ip_address = event:getHeader('network-ip'); + self:check_ip(ip_address); +end + + +function Perimeter.check_ip(self, ip_address) + local event_time = os.time(); + + if not self.ip_address_table[ip_address] then + self.ip_address_table[ip_address] = { last_contact = event_time, contact_count = 0, start_stamp = event_time, banned = 0 } + end + + local ip_record = self.ip_address_table[ip_address]; + ip_record.last_contact = event_time; + ip_record.contact_count = ip_record.contact_count + 1; + + if ip_record.contact_count > MALICIOUS_CONTACT_COUNT then + if (event_time - ip_record.start_stamp) <= MALICIOUS_CONTACT_TIME_SPAN then + self.log:warning('[', ip_address, '] PERIMETER - too many registration attempts'); + ip_record.start_stamp = event_time; + ip_record.contact_count = 0; + if ip_record.banned < BAN_FUTILE then + ip_record.banned = ip_record.banned + 1; + self:ban_ip(ip_address); + else + self.log:error('[', ip_address, '] PERIMETER - ban futile'); + end + end + end +end + + +function Perimeter.ban_ip(self, ip_address) + self.ip_address = ip_address; + + if self.execute then + local command = self:expand_variables(self.execute); + self.log:debug('[', ip_address, '] PERIMETER - execute: ', command); + local result = os.execute(command); + if tostring(result) == '0' then + self.log:warning('[', ip_address, '] PERIMETER - IP banned'); + end + end +end + + +function Perimeter.expand_variables(self, line) + return (line:gsub('{([%a%d_-]+)}', function(captured) + return self[captured]; + end)) +end |