wafredir/config.go

79 lines
2.8 KiB
Go

package main
import (
"fmt"
"net/url"
)
// config accepts a slice of type Redirect and returns an error
// it organizes the input data in a way that makes sense for FortiOS objects
// then outputs the configuration to stdout
func config(redirects []Redirect) error {
// A map which contains the name of a redirect policy as the key, and a slice of strings as a value.
// The value of the string is the name of the url-rewrite-rule which needs to be referenced by the redirect policy object in FortiOS
redirectPolicies := make(map[string][]string)
// Iterate over all redirects and output url-rewrite-rules
fmt.Printf("\n\n------------------------ COPY BELOW THIS LINE ------------------------\n\n\n")
fmt.Println("config waf url-rewrite url-rewrite-rule")
for _, redirect := range redirects {
// Parse the source URL string into a URL object so we can extract features
sourceURL, err := url.Parse(redirect.sourceURL)
if err != nil {
return fmt.Errorf("unable to parse source URL '%s': %v", redirect.sourceURL, err)
}
var ruleName, action string
if len(redirect.sourceURL) > 63 { // FortiOS only allows up to 63 characters. There is potention for collission here. TBD: Reduce and replace characters in the middle of string with '...' and show characters at the end of the URL to make differentiation easier for operators of the WAF
ruleName = redirect.sourceURL[:62]
} else {
ruleName = redirect.sourceURL
}
if redirect.statusCode == 301 { //translate to fortiOS syntax
action = "redirect-301"
} else {
action = "redirect"
}
// Output FortiOS configuration syntax
fmt.Printf("edit \"%s\"\n", ruleName)
fmt.Printf("set location %s\n", redirect.destinationURL)
fmt.Printf("set action %s\n", action)
fmt.Println("config match-condition")
fmt.Println("edit 0")
fmt.Println("set object http-url")
fmt.Printf("set reg-exp %s$\n", sourceURL.Path)
fmt.Println("set protocol-filter enable")
fmt.Printf("set HTTP-protocol %s\n", sourceURL.Scheme)
fmt.Println("next")
fmt.Println("end")
fmt.Println("next")
// Add this rule to the slice inside the policy map. This is used to organize data for creating the url-rewrite-policy configuration below
redirectPolicies[sourceURL.Host] = append(redirectPolicies[sourceURL.Host], ruleName)
}
fmt.Println("end")
// Output url-rewrite-policy configuration.
// Iterate over values in the policy map and output the policy configuration
fmt.Println("config waf url-rewrite url-rewrite-policy")
for policyName, policyRules := range redirectPolicies {
fmt.Printf("edit \"%s-redirects\"\n", policyName)
fmt.Println("config rule")
for _, ruleName := range policyRules {
fmt.Println("edit 0")
fmt.Printf("set url-rewrite-rule-name %s\n", ruleName)
fmt.Println("next")
}
fmt.Println("end")
fmt.Println("next")
}
fmt.Printf("end\n\n\n")
return nil
}