* Making good progress of speeding up firewalld stuff. Still room for improvement.

Signed-off-by: Digimer <digimer@alteeve.ca>
main
Digimer 7 years ago
parent 31dddf95b0
commit d7fd0c564f
  1. 2
      AN/Tools.pm
  2. 116
      AN/Tools/System.pm

@ -643,6 +643,7 @@ sub _set_paths
# Executables # Executables
$an->data->{path} = { $an->data->{path} = {
configs => { configs => {
'firewalld.conf' => "/etc/firewalld/firewalld.conf",
'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf", 'pg_hba.conf' => "/var/lib/pgsql/data/pg_hba.conf",
'postgresql.conf' => "/var/lib/pgsql/data/postgresql.conf", 'postgresql.conf' => "/var/lib/pgsql/data/postgresql.conf",
ssh_config => "/etc/ssh/ssh_config", ssh_config => "/etc/ssh/ssh_config",
@ -654,6 +655,7 @@ sub _set_paths
directories => { directories => {
backups => "/usr/sbin/striker/backups", backups => "/usr/sbin/striker/backups",
'cgi-bin' => "/var/www/cgi-bin", 'cgi-bin' => "/var/www/cgi-bin",
firewalld_services => "/usr/lib/firewalld/services",
html => "/var/www/html", html => "/var/www/html",
skins => "/var/www/html/skins", skins => "/var/www/html/skins",
tools => "/usr/sbin/striker", tools => "/usr/sbin/striker",

@ -394,6 +394,7 @@ This can be c<< tcp >> or C<< upd >> and is used to specify what protocol to use
=cut =cut
### TODO: This is slooooow. We need to be able to get more data per system call. ### TODO: This is slooooow. We need to be able to get more data per system call.
### - Getting better...
sub manage_firewall sub manage_firewall
{ {
my $self = shift; my $self = shift;
@ -421,7 +422,7 @@ sub manage_firewall
if (not $active_zone) if (not $active_zone)
{ {
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-active-zones"; my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-active-zones";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my $output = $an->System->call({shell_call => $shell_call}); my $output = $an->System->call({shell_call => $shell_call});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
@ -437,12 +438,21 @@ sub manage_firewall
} }
} }
# What is the default zone? # What is the default zone? Read the config file, if possible, as it is several times faster than
my $default_zone = ""; # invoking 'firewall-cmd'.
my $default_zone = "";
my $firewalld_conf = $an->Storage->read_file({file => $an->data->{path}{configs}{'firewalld.conf'}});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { firewalld_conf => $firewalld_conf }});
if ($firewalld_conf =~ /^DefaultZone=(.*)$/m)
{
$default_zone = $1;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { default_zone => $default_zone }});
}
# If we didn't get the default zone from the file, try with the 'firewall-cmd' command.
if (not $default_zone) if (not $default_zone)
{ {
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-default-zone"; my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-default-zone";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my $output = $an->System->call({shell_call => $shell_call}); my $output = $an->System->call({shell_call => $shell_call});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
@ -468,8 +478,10 @@ sub manage_firewall
my $open_services = []; my $open_services = [];
if ($active_zone) if ($active_zone)
{ {
### TODO: Read /etc/firewalld/zones/${active_zone}.xml with XMLin and for each
### '<service name="foo"/>', read in '$an->data->{path}{directories}{firewalld_services}/foo.xml'.
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --zone=".$active_zone." --list-all"; my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --zone=".$active_zone." --list-all";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my $output = $an->System->call({shell_call => $shell_call}); my $output = $an->System->call({shell_call => $shell_call});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
@ -520,7 +532,7 @@ sub manage_firewall
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }});
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --info-service ".$service; my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --info-service ".$service;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my $output = $an->System->call({shell_call => $shell_call}); my $output = $an->System->call({shell_call => $shell_call});
my $this_port = ""; my $this_port = "";
@ -1404,7 +1416,10 @@ sub reload_daemon
my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service"; my $say_daemon = $daemon =~ /\.service$/ ? $daemon : $daemon.".service";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { daemon => $daemon, say_daemon => $say_daemon }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { daemon => $daemon, say_daemon => $say_daemon }});
my $output = $an->System->call({shell_call => $an->data->{path}{exe}{systemctl}." reload ".$say_daemon."; ".$an->data->{path}{exe}{'echo'}." return_code:\$?"}); my $shell_call = $an->data->{path}{exe}{systemctl}." reload ".$say_daemon."; ".$an->data->{path}{exe}{'echo'}." return_code:\$?";
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { shell_call => $shell_call }});
my $output = $an->System->call({shell_call => $shell_call});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { output => $output }});
foreach my $line (split/\n/, $output) foreach my $line (split/\n/, $output)
{ {
@ -1524,7 +1539,8 @@ This is the port number to match.
This is the protocol to match, either C<< tcp >> or C<< udp >>. If this is not specified, C<< tcp >> is used. This is the protocol to match, either C<< tcp >> or C<< udp >>. If this is not specified, C<< tcp >> is used.
=cut =cut
### TODO: This is slooooow... # NOTE: We read the XML files instead of use 'firewall-cmd' directly because reading the files is about 30x
# faster.
sub _match_port_to_service sub _match_port_to_service
{ {
my $self = shift; my $self = shift;
@ -1541,58 +1557,62 @@ sub _match_port_to_service
my $service_name = ""; my $service_name = "";
my $services = []; my $services = [];
# Get a list of services on this machine. # Read in the firewall
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --get-services"; my $directory = $an->data->{path}{directories}{firewalld_services};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); $an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 2, key => "log_0018", variables => { directory => $directory }});
if (not -d $directory)
my $output = $an->System->call({shell_call => $shell_call});
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }});
foreach my $service (split/\s/, $output)
{ {
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service => $service }}); # Missing directory...
push @{$services}, $service; return("!!error!!");
} }
local(*DIRECTORY);
foreach my $service (sort {$a cmp $b} @{$services}) opendir(DIRECTORY, $directory);
while(my $file = readdir(DIRECTORY))
{ {
my $shell_call = $an->data->{path}{exe}{'firewall-cmd'}." --info-service ".$service; next if $file !~ /\.xml$/;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { shell_call => $shell_call }}); my $full_path = $directory."/".$file;
my $service = ($file =~ /^(.*?)\.xml$/)[0];
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
full_path => $full_path,
service => $service,
}});
my $output = $an->System->call({shell_call => $shell_call}); my $xml = XML::Simple->new();
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { output => $output }}); my $body = "";
foreach my $line (split/\n/, $output) eval { $body = $xml->XMLin($full_path, KeyAttr => { language => 'name', key => 'name' }, ForceArray => [ 'port' ]) };
if ($@)
{ {
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { line => $line }}); chomp $@;
if ($line =~ /ports: (.*)$/) my $error = "[ Error ] - The was a problem reading: [$file]. The error was:\n";
$error .= "===========================================================\n";
$error .= $@."\n";
$error .= "===========================================================\n";
$an->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, priority => "err", raw => $error});
}
else
{
#print Dumper $body;
my $name = $body->{short};
foreach my $hash_ref (@{$body->{port}})
{ {
my $ports = $an->Words->clean_spaces({ string => $1 }); my $this_port = $hash_ref->{port};
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { ports => $ports }}); my $this_protocol = $hash_ref->{protocol};
foreach my $port_string (split/\s/, $ports) $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
this_port => $this_port,
this_protocol => $this_protocol,
}});
if (($this_port eq $port) && ($this_protocol eq $protocol))
{ {
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { port_string => $port_string }}); # Found it!
if ($port_string =~ /^(\d+)\/(.*)$/) $service_name = $service;
{ $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }});
my $this_port = $1; last;
my $this_protocol = $2;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => {
this_port => $this_port,
this_protocol => $this_protocol,
}});
if (($this_port eq $port) && ($this_protocol eq $protocol))
{
# Found it!
$service_name = $service;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 3, list => { service_name => $service_name }});
last;
}
}
last if $service_name;
} }
} }
last if $service_name;
} }
last if $service_name; last if $service_name;
} }
closedir DIRECTORY;
$an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service_name => $service_name }}); $an->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { service_name => $service_name }});
return($service_name); return($service_name);

Loading…
Cancel
Save