-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate in smaller files. Bussiness, config, connections
- Loading branch information
1 parent
800178b
commit 7f4921e
Showing
20 changed files
with
876 additions
and
610 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package actor | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/softonic/ip-blocker/app/utils" | ||
"gopkg.in/yaml.v2" | ||
) | ||
|
||
// ActorConfig is the configuration for the actor | ||
type ActorConfig struct { | ||
Project string | ||
Policy string | ||
TTLRules int | ||
ExcludeIPs string | ||
} | ||
|
||
// GCPArmorRulesConf is the configuration for the Armor rules | ||
type GCPArmorRulesConf struct { | ||
preview bool `yaml:"preview"` | ||
action string `yaml:"action"` | ||
} | ||
|
||
func (c *GCPArmorRulesConf) Parse(data []byte) error { | ||
return yaml.Unmarshal(data, c) | ||
} | ||
|
||
var conf utils.MapConf | ||
|
||
func (c *GCPArmorRulesConf) LoadConfig() error { | ||
configPath := os.Getenv("CONFIG_PATH") | ||
if configPath == "" { | ||
configPath = "/etc/config/gcp-armor-config.yaml" // valor por defecto | ||
} | ||
|
||
return utils.GetConf(configPath, &conf) | ||
|
||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package actor | ||
|
||
import ( | ||
"context" | ||
|
||
compute "cloud.google.com/go/compute/apiv1" | ||
"k8s.io/klog" | ||
) | ||
|
||
// GCPArmorConnection is a struct to connect to GCP Armor | ||
type GCPArmorConnection struct { | ||
Client *compute.SecurityPoliciesClient | ||
Ctx context.Context | ||
} | ||
|
||
func NewGCPArmorConnection() (*GCPArmorConnection, error) { | ||
ctx := context.Background() | ||
client, err := compute.NewSecurityPoliciesRESTClient(ctx) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return nil, err | ||
} | ||
|
||
return &GCPArmorConnection{ | ||
Client: client, | ||
Ctx: ctx, | ||
}, nil | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package actor | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
"k8s.io/klog" | ||
) | ||
|
||
// Build the query to Add a Rule to the Security Policy | ||
func buildArmorQueryAddRule(blockStringArray []string, project string, policy string, action string, description string, priority int32, preview bool) *computepb.AddRuleSecurityPolicyRequest { | ||
|
||
versioned := computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
match := &computepb.SecurityPolicyRuleMatcher{ | ||
Config: &computepb.SecurityPolicyRuleMatcherConfig{ | ||
SrcIpRanges: blockStringArray, | ||
}, | ||
VersionedExpr: versioned, | ||
} | ||
|
||
req := &computepb.AddRuleSecurityPolicyRequest{ | ||
|
||
Project: project, | ||
SecurityPolicy: policy, | ||
SecurityPolicyRuleResource: &computepb.SecurityPolicyRule{ | ||
Action: &(action), | ||
Description: &description, | ||
Priority: &priority, | ||
Preview: &(preview), | ||
Match: match, | ||
}, | ||
} | ||
|
||
return req | ||
|
||
} | ||
|
||
// Execute the query to add a rule to the armor policy | ||
func (g *GCPArmorActor) executeArmorQueryAddRule(ips []string, priority int32, action, description string, preview bool) error { | ||
|
||
client := g.Connection.Client | ||
ctx := g.Connection.Ctx | ||
|
||
req := buildArmorQueryAddRule(ips, g.ActorConfig.Project, g.ActorConfig.Policy, action, description, priority, preview) | ||
|
||
_, err := client.AddRule(ctx, req) | ||
if err != nil { | ||
if strings.Contains(err.Error(), "Cannot have rules with the same priorities") { | ||
// reexecute the query with prio + 1 if the prio is already used | ||
priority++ | ||
req := buildArmorQueryAddRule(ips, g.ActorConfig.Project, g.ActorConfig.Policy, action, description, priority, preview) | ||
_, err := client.AddRule(ctx, req) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return err | ||
} | ||
} else { | ||
klog.Error("\nError: ", err) | ||
return err | ||
} | ||
} | ||
|
||
if err != nil { | ||
return fmt.Errorf("error executing add armor query: %v", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// Execute the query to remove a rule from the armor policy | ||
func (g *GCPArmorActor) executeArmorQueryRemoveRule(priority int32) error { | ||
client := g.Connection.Client | ||
ctx := g.Connection.Ctx | ||
|
||
req := &computepb.RemoveRuleSecurityPolicyRequest{ | ||
Project: g.ActorConfig.Project, | ||
SecurityPolicy: g.ActorConfig.Policy, | ||
Priority: &priority, | ||
} | ||
|
||
_, err := client.RemoveRule(ctx, req) | ||
|
||
if err != nil { | ||
return fmt.Errorf("error executing remove armor query: %v", err) | ||
} | ||
|
||
return nil | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
package actor | ||
|
||
import ( | ||
"github.com/softonic/ip-blocker/app/utils" | ||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
|
||
"k8s.io/klog" | ||
) | ||
|
||
type IPGetter struct { | ||
actor *GCPArmorActor | ||
} | ||
|
||
func NewIPGetter(actor *GCPArmorActor) *IPGetter { | ||
return &IPGetter{actor: actor} | ||
} | ||
|
||
func (g *IPGetter) GetBlockedIPs() ([]string, error) { | ||
|
||
var sourceIps computepb.SecurityPolicyRuleMatcherConfig | ||
|
||
var ips []string | ||
|
||
RulesGetter := NewRulesGetter(g.actor) | ||
rules, err := RulesGetter.GetSecurityRules() | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return nil, err | ||
} | ||
|
||
for _, singleRule := range rules { | ||
|
||
sourceIps = computepb.SecurityPolicyRuleMatcherConfig{ | ||
SrcIpRanges: singleRule.Match.Config.SrcIpRanges, | ||
} | ||
|
||
ips = append(ips, sourceIps.SrcIpRanges...) | ||
|
||
} | ||
|
||
return ips, nil | ||
|
||
} | ||
|
||
// getLastPriority: this function will get the last priority of the rules | ||
func getLastPriority(rules []*computepb.SecurityPolicyRule) int32 { | ||
|
||
var lastPriority int32 | ||
|
||
for _, singleRule := range rules { | ||
|
||
if *singleRule.Priority > lastPriority { | ||
lastPriority = *singleRule.Priority | ||
} | ||
|
||
} | ||
|
||
if lastPriority == 0 { | ||
lastPriority = 1000 | ||
} | ||
|
||
return lastPriority | ||
|
||
} | ||
|
||
func getCandidateIPsToBlock(sourceIPs, actorIPs, excludedIPs []string) []string { | ||
candidateIPsToBlock := utils.UniqueItems(sourceIPs, actorIPs) | ||
candidateAfterExcluded := utils.UniqueItems(candidateIPsToBlock, excludedIPs) | ||
candidateAfterExcluded = utils.RemoveDuplicateStr(candidateAfterExcluded) | ||
|
||
var candidateWithCidr []string | ||
for _, k := range candidateAfterExcluded { | ||
candidateWithCidr = append(candidateWithCidr, k+"/32") | ||
} | ||
return candidateWithCidr | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package actor | ||
|
||
import ( | ||
"strconv" | ||
"time" | ||
|
||
actorUtils "github.com/softonic/ip-blocker/app/actor/utils" | ||
globalUtils "github.com/softonic/ip-blocker/app/utils" | ||
|
||
"k8s.io/klog" | ||
|
||
"regexp" | ||
|
||
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1" | ||
) | ||
|
||
type RulesGetter struct { | ||
actor *GCPArmorActor | ||
} | ||
|
||
func NewRulesGetter(actor *GCPArmorActor) *RulesGetter { | ||
return &RulesGetter{actor: actor} | ||
} | ||
|
||
// GetSecurityRules: get Rules that were created by IPBlocker | ||
func (g *RulesGetter) GetSecurityRules() ([]*computepb.SecurityPolicyRule, error) { | ||
req := &computepb.GetSecurityPolicyRequest{ | ||
Project: g.actor.ActorConfig.Project, | ||
SecurityPolicy: g.actor.ActorConfig.Policy, | ||
} | ||
|
||
resp, err := g.actor.Connection.Client.Get(g.actor.Connection.Ctx, req) | ||
if err != nil { | ||
klog.Error("\nError: ", err) | ||
return nil, err | ||
} | ||
|
||
var ipBlockerRules []*computepb.SecurityPolicyRule | ||
|
||
for _, singleRule := range resp.Rules { | ||
|
||
match := false | ||
match, _ = regexp.MatchString("ipblocker:[0-9]{10}", *singleRule.Description) | ||
|
||
if !match { | ||
continue | ||
} | ||
|
||
// && singleRule.Match.VersionedExpr == computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
if *singleRule.Action != "allow" && *singleRule.Match.VersionedExpr == 70925961 { | ||
|
||
ipBlockerRules = append(ipBlockerRules, singleRule) | ||
|
||
} | ||
|
||
} | ||
|
||
return ipBlockerRules, nil | ||
} | ||
|
||
// GetBlockedIPsFromActorThatCanBeUnblocked: return IPs that has been blocked for more than ttlRules min | ||
func getBlockedIPsFromActorThatCanBeUnblocked(rules []*computepb.SecurityPolicyRule, ttlRules int) []string { | ||
|
||
now := time.Now() | ||
secs := now.Unix() | ||
|
||
var ips, restIps []string | ||
|
||
for _, singleRule := range rules { | ||
|
||
// && singleRule.Match.VersionedExpr == computepb.SecurityPolicyRuleMatcher_SRC_IPS_V1.Enum() | ||
|
||
unixTimeStampFromDescString := actorUtils.ExtractFromDescription(*singleRule.Description) | ||
n, err := strconv.ParseInt(unixTimeStampFromDescString, 10, 64) | ||
if err != nil { | ||
continue | ||
} | ||
if (secs - n) > int64(ttlRules*60) { | ||
|
||
restIps = singleRule.Match.Config.SrcIpRanges | ||
|
||
ips = append(ips, restIps...) | ||
} else { | ||
klog.Infof("This rule with priority %d is still valid", *singleRule.Priority) | ||
} | ||
|
||
} | ||
|
||
return ips | ||
|
||
} | ||
|
||
func GetRuleFromIP(rules []*computepb.SecurityPolicyRule, ips []string) ([]int32, error) { | ||
|
||
var prios []int32 | ||
|
||
for _, singleRule := range rules { | ||
|
||
for _, k := range singleRule.Match.Config.SrcIpRanges { | ||
for _, m := range ips { | ||
if k == m { | ||
found := globalUtils.Find(prios, *singleRule.Priority) | ||
// check if prio already exists in array []prio | ||
// so the ip is in the rule, you can get the prio of this rule | ||
if !found { | ||
prios = append(prios, *singleRule.Priority) | ||
} | ||
|
||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
return prios, nil | ||
|
||
} |
Oops, something went wrong.