예제 #1
0
파일: iptables.go 프로젝트: romana/core
// CreateRules creates iptables Rules for the given Romana chain
// to allow a traffic to flow between the Host and Endpoint.
func (fw *IPtables) CreateRules(chain int) error {
	log.Info("In CreateRules() for chain", chain)
	for _, rule := range fw.chains[chain].Rules {
		// First create rule record in database.
		err0 := fw.addIPtablesRule(rule)
		if err0 != nil {
			log.Error("In CreateRules() create db record for iptables rule ", rule.GetBody())
			return err0
		}

		err1 := fw.EnsureRule(rule, EnsureFirst)
		if err1 != nil {
			log.Error("In CreateRules() failed to create install firewall rule ", rule.GetBody())
			return err1
		}

		// Finally, set 'active' flag in database record.
		if err2 := fw.Store.switchIPtablesRule(rule, setRuleActive); err2 != nil {
			log.Error("In CreateRules() iptables rule created, but activation failed ", rule.GetBody())
			return err2
		}
	}
	log.Info("Creating firewall rules success")
	return nil
}
예제 #2
0
파일: store.go 프로젝트: romana/core
// addIPtablesRuleUnsafe is a non thread safe implementation of addIPtablesRule.
// Unsafe implementation is needed for functions which are already managing same mutex.
func (firewallStore *firewallStore) addIPtablesRuleUnsafe(rule *IPtablesRule) error {

	db := firewallStore.DbStore.Db
	// db := firewallStore.GetDb()
	log.Info("In addIPtablesRule() after GetDb")
	if db == nil {
		panic("In addIPtablesRule(), db is nil")
	}

	firewallStore.DbStore.Db.Create(rule)
	log.Info("In addIPtablesRule() after Db.Create")
	if db.Error != nil {
		return db.Error
	}
	firewallStore.DbStore.Db.NewRecord(*rule)
	err := common.MakeMultiError(db.GetErrors())
	if err != nil {
		return err
	}
	if db.Error != nil {
		return db.Error
	}
	return nil

}
예제 #3
0
파일: iptables.go 프로젝트: romana/core
// ProvisionEndpoint creates iptables Rules for given endpoint in given environment
func (fw IPtables) ProvisionEndpoint() error {
	log.Info("In ProvisionEndpoint() with firewall.")

	if !fw.initialized {
		return fmt.Errorf("In ProvisionEndpoint(), can not provision uninitialized firewall, use Init()")
	}

	err := fw.CreateChains(fw.chains)
	if err != nil {
		return err
	}

	log.Info("Firewall: creating rules")
	for chain := range fw.chains {
		if err := fw.CreateRules(chain); err != nil {
			return err
		}
	}

	if err := fw.CreateDefaultDropRule(ForwardOutChainIndex); err != nil {
		return err
	}

	log.Info("Firewall: diverting traffic")
	for _, chain := range fw.chains {
		if err := fw.DivertTrafficToRomanaIPtablesChain(chain, installDivertRules); err != nil {
			return err
		}
	}

	return nil
}
예제 #4
0
파일: iptables.go 프로젝트: romana/core
// CreateU32Rules creates wildcard iptables Rules for the given Romana chain.
// These Rules serve to restrict traffic between segments and tenants.
// * Deprecated, outdated *
func (fw *IPtables) CreateU32Rules(chain int) error {
	log.Info("Creating U32 firewall rules for chain", chain)
	chainName := fw.chains[chain].ChainName
	args := []string{"-w", "-A", chainName, "-m", "u32", "--u32", fw.u32filter, "-j", "ACCEPT"}
	_, err := fw.os.Exec(iptablesCmd, args)
	if err != nil {
		log.Error("Creating U32 firewall rules failed")
		return err
	}
	log.Info("Creating U32 firewall rules success")
	return nil
}
예제 #5
0
파일: listener.go 프로젝트: romana/core
func (l *KubeListener) Initialize(client *common.RestClient) error {
	l.restClient = client

	// TODO, find a better place to initialize
	// the translator. Stas.
	PTranslator.Init(l.restClient, l.segmentLabelName, l.tenantLabelName)
	tc := PTranslator.GetClient()
	if tc == nil {
		log.Critical("Failed to initialize rest client for policy translator.")
		os.Exit(255)
	}

	l.lastEventPerNamespace = make(map[string]uint64)
	log.Infof("%s: Starting server", l.Name())
	nsURL, err := common.CleanURL(fmt.Sprintf("%s/%s/?%s", l.kubeURL, l.namespaceNotificationPath, HttpGetParamWatch))
	if err != nil {
		return err
	}
	log.Infof("Starting to listen on %s", nsURL)
	done := make(chan struct{})
	eventc, err := l.nsWatch(done, nsURL)
	if err != nil {
		log.Critical("Namespace watcher failed to start", err)
		os.Exit(255)
	}

	// events := l.conductor(nsEvents, done)
	l.process(eventc, done)

	ProduceNewPolicyEvents(eventc, done, l)

	log.Info("All routines started")
	return nil
}
예제 #6
0
파일: iptables.go 프로젝트: romana/core
// CreateDefaultRule creates iptables rule for a chain with the
// specified target
func (fw *IPtables) CreateDefaultRule(chain int, target string) error {
	log.Infof("In CreateDefaultRule() %s rules for chain %d", target, chain)
	chainName := fw.chains[chain].ChainName
	body := fmt.Sprintf("%s %s %s", chainName, "-j", target)
	rule := &IPtablesRule{
		Body:  body,
		State: setRuleInactive.String(),
	}

	// First create rule record in database.
	err0 := fw.addIPtablesRule(rule)
	if err0 != nil {
		log.Error("In CreateDefaultRule() create db record for iptables rule ", rule.GetBody())
		return err0
	}

	err1 := fw.EnsureRule(rule, EnsureLast)
	if err1 != nil {
		log.Errorf("In CreateDefaultRule() %s rules failed", target)
		return err1
	}

	// Finally, set 'active' flag in database record.
	if err2 := fw.Store.switchIPtablesRule(rule, setRuleActive); err2 != nil {
		log.Error("In CreateDefaultRule() iptables rule created but activation failed ", rule.GetBody())
		return err2
	}

	log.Info("In CreateDefaultRule() success")
	return nil
}
예제 #7
0
파일: store.go 프로젝트: romana/core
func (firewallStore *firewallStore) addIPtablesRule(rule *IPtablesRule) error {
	log.Info("Acquiring store mutex for addIPtablesRule")
	if rule == nil {
		panic("In addIPtablesRule(), received nil rule")
	}

	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for addIPtablesRule")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for addIPtablesRule")

	err := firewallStore.addIPtablesRuleUnsafe(rule)
	return err
}
예제 #8
0
파일: store.go 프로젝트: romana/core
// listIPtablesRules returns a list of all firewall rules in a database.
func (firewallStore *firewallStore) listIPtablesRules() ([]IPtablesRule, error) {
	log.Info("Acquiring store mutex for listIPtablesRules")
	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for listIPtablesRules")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for listIPtablesRules")

	var iPtablesRule []IPtablesRule
	firewallStore.DbStore.Db.Find(&iPtablesRule)
	err := common.MakeMultiError(firewallStore.DbStore.Db.GetErrors())
	if err != nil {
		return nil, err
	}
	return iPtablesRule, nil
}
예제 #9
0
파일: iptables.go 프로젝트: romana/core
// EnsureRule verifies if given iptables rule exists and creates if it's not.
func (fw IPtables) EnsureRule(rule FirewallRule, opType RuleState) error {
	ruleExists := fw.isRuleExist(rule)

	args := []string{}
	if ruleExists {

		switch opType {
		case EnsureAbsent:
			args = append(args, "-D")
		default:
			log.Info("In EnsureRule - nothing to do ", rule.GetBody())
			return nil
		}
	} else {

		switch opType {
		case EnsureLast:
			args = append(args, "-A")
		case EnsureFirst:
			args = append(args, "-I")
		default:
			log.Info("In EnsureRule - nothing to do ", rule.GetBody())
			return nil
		}
	}

	args = append(args, strings.Split(rule.GetBody(), " ")...)
	cmdStr := iptablesCmd + " " + strings.Join(args, " ")
	out, err := fw.os.Exec(iptablesCmd, args)
	if err != nil {
		log.Errorf("[%s]: %s failed for rule %s with error %v, saying [%s]", cmdStr, opType, rule.GetBody(), err, string(out))
	} else {
		if out != nil && len(out) > 0 {
			log.Infof("%s success %s: [%s]", opType, rule.GetBody(), string(out))
		} else {
			log.Infof("%s success %s", opType, rule.GetBody())
		}
	}

	return err
}
예제 #10
0
파일: store.go 프로젝트: romana/core
// deleteIPtablesRule deletes firewall rules from database.
func (firewallStore *firewallStore) deleteIPtablesRule(rule *IPtablesRule) error {
	log.Info("Acquiring store mutex for deleteIPtablesRule")
	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for deleteIPtablesRule")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for deleteIPtablesRule")

	db := firewallStore.DbStore.Db
	firewallStore.DbStore.Db.Delete(rule)
	err := common.MakeMultiError(db.GetErrors())
	if err != nil {
		return err
	}
	if db.Error != nil {
		return db.Error
	}

	return nil
}
예제 #11
0
파일: store.go 프로젝트: romana/core
// switchIPtablesRule changes IPtablesRule state.
func (firewallStore *firewallStore) switchIPtablesRule(rule *IPtablesRule, op opSwitchIPtables) error {

	// Fast track return if nothing to be done
	if rule.State == op.String() {
		log.Infof("switchIPtablesRule nothing to be done for %s", rule.State)
		return nil
	}

	log.Info("Acquiring store mutex for switchIPtablesRule")
	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for switchIPtablesRule")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for switchIPtablesRule")

	// if toggle requested then reverse current state
	if op == toggleRule {
		if rule.State == setRuleInactive.String() {
			rule.State = setRuleActive.String()
		} else {
			rule.State = setRuleInactive.String()
		}
		// otherwise just assign op value
	} else {
		rule.State = op.String()
	}

	db := firewallStore.DbStore.Db
	firewallStore.DbStore.Db.Save(rule)
	err := common.MakeMultiError(db.GetErrors())
	if err != nil {
		return err
	}
	if db.Error != nil {
		return db.Error
	}

	return nil
}
예제 #12
0
파일: store.go 프로젝트: romana/core
func (firewallStore *firewallStore) findIPtablesRules(subString string) (*[]IPtablesRule, error) {
	log.Info("Acquiring store mutex for findIPtablesRule")
	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for findIPtablesRule")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for findIPtablesRule")

	var rules []IPtablesRule
	db := firewallStore.DbStore.Db
	searchString := "%" + subString + "%"
	firewallStore.DbStore.Db.Where("body LIKE ?", searchString).Find(&rules)
	err := common.MakeMultiError(db.GetErrors())
	if err != nil {
		return nil, err
	}
	if db.Error != nil {
		return nil, db.Error
	}
	return &rules, nil
}
예제 #13
0
파일: store.go 프로젝트: romana/core
// ensureIPtablesRule checks if given rule exists in a database and if not, creates it.
func (firewallStore *firewallStore) ensureIPtablesRule(rule *IPtablesRule) error {
	log.Info("Acquiring store mutex for listIPtablesRules")
	firewallStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for listIPtablesRules")
		firewallStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for listIPtablesRules")

	if firewallStore.DbStore.Db.Where("body = ?", rule.Body).First(rule).RecordNotFound() {
		log.Tracef(trace.Inside, "In ensureIPtablesRule(), rule %s not found in db - creating", rule.Body)
		err0 := firewallStore.addIPtablesRuleUnsafe(rule)
		if err0 != nil {
			log.Errorf("In ensureIPtablesRule() failed to store rule %v", rule)
			return err0
		}
	} else {
		log.Tracef(trace.Inside, "In ensureIPtablesRule(), rule %s already in db - nothing to do", rule.Body)
	}

	return nil
}
예제 #14
0
파일: agent.go 프로젝트: romana/core
// Initialize implements the Initialize method of common.Service
// interface.
func (a *Agent) Initialize(client *common.RestClient) error {
	log.Trace(trace.Public, "Entering Agent.Initialize()")
	err := a.store.Connect()
	if err != nil {
		log.Error("Agent.Initialize() : Failed to connect to database.")
		return err
	}

	log.Info("Agent: Attempting to identify current host.")
	if err := a.identifyCurrentHost(); err != nil {
		log.Error("Agent: ", agentError(err))
		return agentError(err)
	}

	a.client = client
	// Ensure we have all the routes to our neighbours
	log.Info("Agent: ensuring interhost routes exist")
	if err := a.Helper.ensureInterHostRoutes(); err != nil {
		log.Error("Agent: ", agentError(err))
		return agentError(err)
	}
	return nil
}
예제 #15
0
파일: store.go 프로젝트: romana/core
func (agentStore *agentStore) addRoute(route *Route) error {
	log.Info("Acquiring store mutex for addRoute")
	agentStore.mu.Lock()
	defer func() {
		log.Info("Releasing store mutex for addRoute")
		agentStore.mu.Unlock()
	}()
	log.Info("Acquired store mutex for addRoute")

	db := agentStore.DbStore.Db
	agentStore.DbStore.Db.Create(route)
	if db.Error != nil {
		return db.Error
	}
	agentStore.DbStore.Db.NewRecord(*route)
	err := common.MakeMultiError(db.GetErrors())
	if err != nil {
		return err
	}
	if db.Error != nil {
		return db.Error
	}
	return nil
}
예제 #16
0
파일: translate.go 프로젝트: romana/core
// updateCache contacts romana Tenant service, lists
// all resources and loads them into memory.
func (t *Translator) updateCache() error {
	log.Info("In updateCache")

	tenantURL, err := t.restClient.GetServiceUrl("tenant")
	if err != nil {
		return TranslatorError{ErrorCacheUpdate, err}
	}

	tenants := []tenant.Tenant{}
	err = t.restClient.Get(tenantURL+"/tenants", &tenants)
	if err != nil {
		log.Errorf("updateCache(): Error getting tenant information: %s", err)
		return TranslatorError{ErrorCacheUpdate, err}
	}

	if t.restClient == nil {
		log.Critical("REST client is nil")
		os.Exit(255)
	}

	// tenants := []tenant.Tenant{}
	// _ = t.restClient.Find(&tenants, common.FindAll)

	t.cacheMu.Lock()
	defer func() {
		log.Infof("Exiting updateCache with %d tenants", len(t.tenantsCache))
		t.cacheMu.Unlock()
	}()

	t.tenantsCache = nil
	for _, ten := range tenants {
		segments := []tenant.Segment{}
		fullUrl := fmt.Sprintf("%s/tenants/%d/segments", tenantURL, ten.ID)
		err = t.restClient.Get(fullUrl, &segments)
		// ignore 404 error here which means no segments
		// considered to be a zero segments rather then
		// an error.
		if err != nil && !checkHttp404(err) {
			log.Errorf("updateCache(): Error getting segment information for tenant %d: %s", ten.ID, err)
			return TranslatorError{ErrorCacheUpdate, err}
		}

		t.tenantsCache = append(t.tenantsCache, TenantCacheEntry{ten, segments})
	}
	return nil
}
예제 #17
0
파일: iptables.go 프로젝트: romana/core
// DivertTrafficToRomanaIPtablesChain injects iptables Rules to send traffic
// into the ROMANA chain.
// We need to do this for each tenant/segment pair as each pair will have different chain name.
func (fw *IPtables) DivertTrafficToRomanaIPtablesChain(chain IPtablesChain, opType opDivertTrafficAction) error {
	// Should be like that
	// iptables -A INPUT -i tap1234 -j ROMANA-T0S1-INPUT
	log.Infof("In DivertTrafficToRomanaIPtablesChain() processing chain %v with state %s", chain, opType)

	var state RuleState
	switch opType {
	case installDivertRules:
		state = EnsureLast
	case removeDivertRules:
		state = EnsureAbsent
	}

	// baseChain := fw.chains[chain].BaseChain
	for _, directionLiteral := range chain.Directions {
		direction := fmt.Sprintf("-%s", directionLiteral)
		body := fmt.Sprintf("%s %s %s %s %s", chain.BaseChain, direction, fw.interfaceName, "-j", chain.ChainName)
		rule := &IPtablesRule{
			Body:  body,
			State: setRuleInactive.String(),
		}

		// First create rule record in database.
		err0 := fw.addIPtablesRule(rule)
		if err0 != nil {
			log.Errorf("In DivertTrafficToRomanaIPtablesChain() failed to process chain %v", chain)
			return err0
		}

		// Then create actuall rule in the system.
		if err1 := fw.EnsureRule(rule, state); err1 != nil {
			log.Errorf("In DivertTrafficToRomanaIPtablesChain() failed to process chain %v", chain)
			return err1
		}

		// Finally, set 'active' flag in database record.
		if err2 := fw.Store.switchIPtablesRule(rule, setRuleActive); err2 != nil {
			log.Error("In DivertTrafficToRomanaIPtablesChain() iptables rule created but activation failed ", rule.GetBody())
			return err2
		}

	}
	log.Info("DivertTrafficToRomanaIPtablesChain() successfully processed chain number", chain)
	return nil
}
예제 #18
0
파일: translate.go 프로젝트: romana/core
// Kube2RomanaBulk attempts to translate a list of kubernetes policies into
// romana representation, returns a list of translated policies and a list
// of policies that can't be translated in original format.
func (t Translator) Kube2RomanaBulk(kubePolicies []v1beta1.NetworkPolicy) ([]common.Policy, []v1beta1.NetworkPolicy, error) {
	log.Info("In Kube2RomanaBulk")
	var returnRomanaPolicy []common.Policy
	var returnKubePolicy []v1beta1.NetworkPolicy

	err := t.updateCache()
	if err != nil {
		return returnRomanaPolicy, returnKubePolicy, TranslatorError{ErrorCacheUpdate, err}
	}

	for kubePolicyNumber, _ := range kubePolicies {
		romanaPolicy, err := t.translateNetworkPolicy(&kubePolicies[kubePolicyNumber])
		if err != nil {
			log.Errorf("Error during policy translation %s", err)
			returnKubePolicy = append(returnKubePolicy, kubePolicies[kubePolicyNumber])
		} else {
			returnRomanaPolicy = append(returnRomanaPolicy, romanaPolicy)
		}
	}

	return returnRomanaPolicy, returnKubePolicy, nil

}