Created
July 26, 2012 23:08
-
-
Save justincjahn/3185160 to your computer and use it in GitHub Desktop.
FortiGate: Generate NAT configuration from given parameters.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env perl -w | |
| use strict; | |
| use Getopt::Long; | |
| use Pod::Usage; | |
| # Configuration | |
| my %config = ( | |
| 'name' => undef, | |
| 'externalIp' => undef, | |
| 'internalIp' => undef, | |
| 'internalInet' => 'zInternal', | |
| 'externalInet' => 'port40' | |
| ); | |
| # VARIABLES | |
| ## ADDRESS_NAME: The name of the firewall address rule. | |
| ## POOL_NAME: The name of the VIP Pool to create. | |
| ## VIP_NAME: The name of the VIP configuration. | |
| ## INTERNAL_INTERFACE: The internal interface of the client. | |
| ## EXTERNAL_INTERFACE: The name of the external interface. | |
| ## EXTERNAL_IP: The external IP address to assign to the user. | |
| ## INTERNAL_IP: The internal IP address of the client. | |
| my $sTemplate = <<END; | |
| config firewall address | |
| edit "{ADDRESS_NAME}" | |
| set associated-interface "{INTERNAL_INTERFACE}" | |
| set subnet {INTERNAL_IP} 255.255.255.255 | |
| end | |
| config firewall ippool | |
| edit "{POOL_NAME}" | |
| set endip {EXTERNAL_IP} | |
| set startip {EXTERNAL_IP} | |
| end | |
| config firewall vip | |
| edit "{VIP_NAME}" | |
| set extip {EXTERNAL_IP} | |
| set extintf "{EXTERNAL_INTERFACE}" | |
| set mappedip {INTERNAL_IP} | |
| end | |
| config firewall policy | |
| edit 0 | |
| set srcintf "{EXTERNAL_INTERFACE}" | |
| set dstintf "{INTERNAL_INTERFACE}" | |
| set srcaddr "any" | |
| set dstaddr "{VIP_NAME}" | |
| set action accept | |
| set ippool enable | |
| set poolname "{POOL_NAME}" | |
| set schedule "always" | |
| set service "ANY" | |
| set nat enable | |
| next | |
| edit 0 | |
| set srcintf "{INTERNAL_INTERFACE}" | |
| set dstintf "{EXTERNAL_INTERFACE}" | |
| set srcaddr "{ADDRESS_NAME}" | |
| set dstaddr "any" | |
| set action accept | |
| set ippool enable | |
| set poolname "{POOL_NAME}" | |
| set schedule "always" | |
| set service "ANY" | |
| set nat enable | |
| end | |
| END | |
| # Attempt to fetch options from the command line. If they aren't set, then the | |
| # code below will interactively prompt the user. | |
| my $bHelp, my $bError = 0; | |
| my $iOptions = GetOptions( | |
| 'external|x=s' => \$config{'externalIp'}, | |
| 'internal|i=s' => \$config{'internalIp'}, | |
| 'name|n=s' => \$config{'name'}, | |
| 'if-internal=s' => \$config{'internalInet'}, | |
| 'if-external=s' => \$config{'externalInet'}, | |
| 'help|?' => \$bHelp | |
| ) or pod2usage(1); | |
| # Handle required options | |
| $bError = 1 if (!defined $config{'externalIp'}); | |
| $bError = 1 if (!defined $config{'internalIp'}); | |
| $bError = 1 if (!defined $config{'name'}); | |
| # If the user requested the help, or there was an error, let's display info | |
| pod2usage(-exitstatus => 0, -verbose => 2) if ($bHelp); | |
| pod2usage(1) if ($bError); | |
| # | |
| # NAME | |
| # | |
| chomp($config{'name'}); | |
| $config{'name'} =~ s/[\s,\.;:_`]+//g; | |
| $config{'name'} = ucfirst($config{'name'}); | |
| # | |
| # EXTERNAL IP | |
| # | |
| chomp($config{'externalIp'}); | |
| if (!($config{'externalIp'} =~ m/\d{2,}\.\d{1,}\.\d{1,}\.\d{1,}/)) { | |
| print STDERR "External IP Address was invalid.\n"; | |
| exit(1); | |
| } | |
| # | |
| # INTERNAL IP | |
| # | |
| chomp($config{'internalIp'}); | |
| if (!($config{'internalIp'} =~ m/\d{2,}\.\d{1,}\.\d{1,}\.\d{1,}/)) { | |
| print STDERR "Internal IP Address was invalid.\n"; | |
| exit(1); | |
| } | |
| # | |
| # EXTERNAL INTERFACE | |
| # | |
| chomp($config{'externalInet'}); | |
| if (!($config{'externalInet'} =~ m/[a-zA-Z0-9]+/)) { | |
| print STDERR "Invalid external interface or zone supplied.\n"; | |
| exit(1); | |
| } | |
| # | |
| # INTERNAL INTERFACE | |
| # | |
| chomp($config{'internalInet'}); | |
| if (!($config{'internalInet'} =~ m/[a-zA-Z0-9]+/)) { | |
| print STDERR "Invalid internal interface or zone supplied.\n"; | |
| exit(1); | |
| } | |
| # Start replacing placeholders | |
| my $sAddressName = 'n' . $config{'name'}; | |
| my $sPoolName = 'pool' . $config{'name'}; | |
| my $sVIPName = 'v' . $config{'name'}; | |
| $sTemplate =~ s/{ADDRESS_NAME}/$sAddressName/g; | |
| $sTemplate =~ s/{POOL_NAME}/$sPoolName/g; | |
| $sTemplate =~ s/{VIP_NAME}/$sVIPName/g; | |
| $sTemplate =~ s/{INTERNAL_INTERFACE}/$config{'internalInet'}/g; | |
| $sTemplate =~ s/{EXTERNAL_INTERFACE}/$config{'externalInet'}/g; | |
| $sTemplate =~ s/{EXTERNAL_IP}/$config{'externalIp'}/g; | |
| $sTemplate =~ s/{INTERNAL_IP}/$config{'internalIp'}/g; | |
| # Print to STDOUT so that we can use output redirection | |
| print STDOUT $sTemplate; | |
| # | |
| # DOCUMENTATION | |
| # | |
| __END__ | |
| =head1 NAME | |
| nat.pl - NAT and SNAT Generator | |
| =head1 SYNOPSIS | |
| nat.pl -x I<ExternalIP> -i I<InternalIP> >> output.txt | |
| Options: | |
| --help Display additional information. | |
| =head1 DESCRIPTION | |
| nat.pl generates FortiOS NAT and SNAT configuration. | |
| =head2 Parameters | |
| =over 8 | |
| =item -n|--name | |
| A name that describes the rule's purpose. Eg. lunchbox, justinsLaptop. | |
| =item -x|--external | |
| The external IP address to give the server. Should be a publically routable IP. | |
| =item -i|--internal | |
| The internal IP address of the server. Should be a private IP address. | |
| =item --if-internal | |
| The internally facing interface or zone. Defaults to zInternal. | |
| =item --if-external | |
| The WAN interface or zone. Defaults to port40. | |
| =back |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment