From 2de661cfd79bf5519889ae1228e838002bb366e8 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Fri, 16 Jun 2017 19:47:53 -0700 Subject: [PATCH] Start of work on port forwarding --- firewalld/edit_forward.cgi | 83 ++++++++++++++++++++++++++++++++++++++ firewalld/firewalld-lib.pl | 34 ++++++++++++++++ firewalld/index.cgi | 5 ++- firewalld/lang/en | 11 +++++ 4 files changed, 132 insertions(+), 1 deletion(-) create mode 100755 firewalld/edit_forward.cgi diff --git a/firewalld/edit_forward.cgi b/firewalld/edit_forward.cgi new file mode 100755 index 000000000..7a6938240 --- /dev/null +++ b/firewalld/edit_forward.cgi @@ -0,0 +1,83 @@ +#!/usr/local/bin/perl +# Show a form to edit one port forward + +use strict; +use warnings; +require 'firewalld-lib.pl'; +our (%in, %text); +&ReadParse(); + +# Get the zone and rule +my @zones = &list_firewalld_zones(); +my ($zone) = grep { $_->{'name'} eq $in{'zone'} } @zones; +$zone || &error($text{'port_ezone'}); +my ($mode, $ports, $proto, $port, $portlow, $porthigh, + $dstmode, $dstport, $dstportlow, $dstporthigh, $dstaddr); +if (!$in{'new'}) { + &ui_print_header(undef, $text{'forward_edit'}, ""); + ($ports, $proto) = split(/\//, $in{'id'}); + if ($ports =~ /^(\d+)\-(\d+)$/) { + $mode = 1; + ($portlow, $porthigh) = ($1, $2); + } + else { + $mode = 0; + $port = $ports; + } + } +else { + &ui_print_header(undef, $text{'forward_create'}, ""); + $mode = 0; + $dstmode = 0; + $proto = "tcp"; + } + +print &ui_form_start("save_forward.cgi", "post"); +print &ui_hidden("zone", $in{'zone'}); +print &ui_hidden("id", $in{'id'}); +print &ui_hidden("new", $in{'new'}); +print &ui_table_start($text{'forward_header'}, undef, 2); + +# Zone name +print &ui_table_row($text{'forward_zone'}, + "".&html_escape($zone->{'name'}).""); + +# Port number or range +print &ui_table_row($text{'forward_port'}, + &ui_radio_table("mode", $mode, + [ [ 0, $text{'port_mode0'}, + &ui_textbox("port", $port, 6) ], + [ 1, $text{'port_mode1'}, + &ui_textbox("portlow", $portlow, 6)." - ". + &ui_textbox("porthigh", $porthigh, 6) ] ])); + +# Protocol name +print &ui_table_row($text{'port_proto'}, + &ui_select("proto", $proto, + [ [ "tcp", "TCP" ], + [ "udp", "UDP" ] ], 1, 0, 1)); + +# Destination port number or range +print &ui_table_row($text{'forward_dstport'}, + &ui_radio_table("dstmode", $dstmode, + [ [ 0, $text{'port_mode0'}, + &ui_textbox("dstport", $dstport, 6) ], + [ 1, $text{'port_mode1'}, + &ui_textbox("dstportlow", $dstportlow, 6)." - ". + &ui_textbox("dstporthigh", $dstporthigh, 6) ] ])); + +# Destination address +print &ui_table_row($text{'forward_dstaddr'}, + &ui_opt_textbox("dstaddr", $dstaddr, 40, $text{'forward_dstlocal'})); + +print &ui_table_end(); +if ($in{'new'}) { + print &ui_form_end([ [ undef, $text{'create'} ] ]); + } +else { + print &ui_form_end([ [ undef, $text{'save'} ], + [ 'delete', $text{'delete'} ] ]); + } + +&ui_print_footer("index.cgi?zone=".&urlize($zone->{'name'}), + $text{'index_return'}); diff --git a/firewalld/firewalld-lib.pl b/firewalld/firewalld-lib.pl index 50b76d53a..e85738129 100644 --- a/firewalld/firewalld-lib.pl +++ b/firewalld/firewalld-lib.pl @@ -121,6 +121,40 @@ my $out = &backquote_logged("$config{'firewall_cmd'} ". return $? ? $out : undef; } +# create_firewalld_forward(&zone, src-port, src-proto, dst-port, dst-addr) +# Create a new forwarding rule in some zone. Returns undef on success or an +# error message on failure +sub create_firewalld_forward +{ +my ($zone, $srcport, $srcproto, $dstport, $dstaddr) = @_; +my $out = &backquote_logged( + $config{'firewall_cmd'}." ". + "--zone ".quotemeta($zone->{'name'})." ". + "--permanent ". + "--add-forward-port=port=$srcport:proto=$srcproto ". + ($dstport ? ":toport=$dstport " : ""). + ($dstaddr ? ":toaddr=$dstaddr " : ""). + "2>&1"); +return $? ? $out : undef; +} + +# delete_firewalld_forward(&zone, src-port, src-proto, dst-port, dst-addr) +# Deletes a forwarding rule in some zone. Returns undef on success or an +# error message on failure +sub delete_firewalld_forward +{ +my ($zone, $srcport, $srcproto, $dstport, $dstaddr) = @_; +my $out = &backquote_logged( + $config{'firewall_cmd'}." ". + "--zone ".quotemeta($zone->{'name'})." ". + "--permanent ". + "--remove-forward-port=port=$srcport:proto=$srcproto ". + ($dstport ? ":toport=$dstport " : ""). + ($dstaddr ? ":toaddr=$dstaddr " : ""). + "2>&1"); +return $? ? $out : undef; +} + # apply_firewalld() # Make the current saved config active sub apply_firewalld diff --git a/firewalld/index.cgi b/firewalld/index.cgi index d56f5e746..e7488ac27 100755 --- a/firewalld/index.cgi +++ b/firewalld/index.cgi @@ -63,7 +63,10 @@ print &ui_form_end(); my @links = ( &ui_link("edit_port.cgi?new=1&zone=".&urlize($zone->{'name'}), $text{'index_padd'}), &ui_link("edit_serv.cgi?new=1&zone=".&urlize($zone->{'name'}), - $text{'index_sadd'}) ); + $text{'index_sadd'}), + &ui_link("edit_forward.cgi?new=1&zone=".&urlize($zone->{'name'}), + $text{'index_fadd'}), + ); if (@{$zone->{'services'}} || @{$zone->{'ports'}}) { my @tds = ( "width=5" ); unshift(@links, &select_all_link("d", 1), diff --git a/firewalld/lang/en b/firewalld/lang/en index ce490a604..750627efc 100644 --- a/firewalld/lang/en +++ b/firewalld/lang/en @@ -23,6 +23,7 @@ index_tservice=Service index_tport=Port index_padd=Add allowed port. index_sadd=Add allowed service. +index_fadd=Add port forward. index_delete=Delete Selected Rules index_return=list of zones index_ezones=No FirewallD zones found! @@ -50,6 +51,16 @@ serv_header=Allowed service options serv_name=Service to allow serv_err=Failed to save service +forward_edit=Edit Forward +forward_create=Create Forward +forward_header=Port forwarding options +forward_zone=Forward for zone +forward_err=Failed to save forward +forward_port=Source port +forward_dstport=Desintation port +forward_dstaddr=Destination address +forward_dstlocal=This system + check_ecmd=The FirewallD control command $1 was not found on your system delete_err=Failed to delete rules