Search in sources :

Example 1 with FirewallRuleVO

use of com.cloud.network.rules.FirewallRuleVO in project cloudstack by apache.

the class FirewallManagerImpl method revokeAllFirewallRulesForNetwork.

@Override
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
public boolean revokeAllFirewallRulesForNetwork(long networkId, long userId, Account caller) throws ResourceUnavailableException {
    List<FirewallRule> rules = new ArrayList<FirewallRule>();
    List<FirewallRuleVO> fwRules = _firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall);
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("Releasing " + fwRules.size() + " firewall rules for network id=" + networkId);
    }
    for (FirewallRuleVO rule : fwRules) {
        // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
        // need to send them one by one
        revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
    }
    // now send everything to the backend
    List<FirewallRuleVO> rulesToApply = _firewallDao.listByNetworkAndPurpose(networkId, Purpose.Firewall);
    boolean success = applyFirewallRules(rulesToApply, true, caller);
    // Now we check again in case more rules have been inserted.
    rules.addAll(_firewallDao.listByNetworkAndPurposeAndNotRevoked(networkId, Purpose.Firewall));
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("Successfully released firewall rules for network id=" + networkId + " and # of rules now = " + rules.size());
    }
    return success && rules.size() == 0;
}
Also used : ArrayList(java.util.ArrayList) FirewallRule(com.cloud.network.rules.FirewallRule) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) ActionEvent(com.cloud.event.ActionEvent)

Example 2 with FirewallRuleVO

use of com.cloud.network.rules.FirewallRuleVO in project cloudstack by apache.

the class FirewallManagerImpl method applyRules.

@Override
public boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException {
    boolean success = true;
    if (rules == null || rules.size() == 0) {
        s_logger.debug("There are no rules to forward to the network elements");
        return true;
    }
    Purpose purpose = rules.get(0).getPurpose();
    if (!_ipAddrMgr.applyRules(rules, purpose, this, continueOnError)) {
        s_logger.warn("Rules are not completely applied");
        return false;
    } else {
        if (updateRulesInDB) {
            for (FirewallRule rule : rules) {
                if (rule.getState() == FirewallRule.State.Revoke) {
                    FirewallRuleVO relatedRule = _firewallDao.findByRelatedId(rule.getId());
                    if (relatedRule != null) {
                        s_logger.warn("Can't remove the firewall rule id=" + rule.getId() + " as it has related firewall rule id=" + relatedRule.getId() + "; leaving it in Revoke state");
                        success = false;
                    } else {
                        removeRule(rule);
                        if (rule.getSourceIpAddressId() != null) {
                            //if the rule is the last one for the ip address assigned to VPC, unassign it from the network
                            IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId());
                            _vpcMgr.unassignIPFromVpcNetwork(ip.getId(), rule.getNetworkId());
                        }
                    }
                } else if (rule.getState() == FirewallRule.State.Add) {
                    FirewallRuleVO ruleVO = _firewallDao.findById(rule.getId());
                    ruleVO.setState(FirewallRule.State.Active);
                    _firewallDao.update(ruleVO.getId(), ruleVO);
                }
            }
        }
    }
    return success;
}
Also used : Purpose(com.cloud.network.rules.FirewallRule.Purpose) IpAddress(com.cloud.network.IpAddress) FirewallRule(com.cloud.network.rules.FirewallRule) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO)

Example 3 with FirewallRuleVO

use of com.cloud.network.rules.FirewallRuleVO in project cloudstack by apache.

the class FirewallManagerImpl method revokeFirewallRule.

protected boolean revokeFirewallRule(long ruleId, boolean apply, Account caller, long userId) {
    FirewallRuleVO rule = _firewallDao.findById(ruleId);
    if (rule == null || rule.getPurpose() != Purpose.Firewall) {
        throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall);
    }
    if (rule.getType() == FirewallRuleType.System && !_accountMgr.isRootAdmin(caller.getId())) {
        throw new InvalidParameterValueException("Only root admin can delete the system wide firewall rule");
    }
    _accountMgr.checkAccess(caller, null, true, rule);
    revokeRule(rule, caller, userId, false);
    boolean success = false;
    Long networkId = rule.getNetworkId();
    if (apply) {
        // ingress firewall rule
        if (rule.getSourceIpAddressId() != null) {
            //feteches ingress firewall, ingress firewall rules associated with the ip
            List<FirewallRuleVO> rules = _firewallDao.listByIpAndPurpose(rule.getSourceIpAddressId(), Purpose.Firewall);
            return applyFirewallRules(rules, false, caller);
        //egress firewall rule
        } else if (networkId != null) {
            List<FirewallRuleVO> rules = _firewallDao.listByNetworkPurposeTrafficType(rule.getNetworkId(), Purpose.Firewall, FirewallRule.TrafficType.Egress);
            return applyFirewallRules(rules, false, caller);
        }
    } else {
        success = true;
    }
    return success;
}
Also used : InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) List(java.util.List) ArrayList(java.util.ArrayList) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO)

Example 4 with FirewallRuleVO

use of com.cloud.network.rules.FirewallRuleVO in project cloudstack by apache.

the class FirewallManagerImpl method revokeFirewallRulesForIp.

@Override
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_CLOSE, eventDescription = "revoking firewall rule", async = true)
public boolean revokeFirewallRulesForIp(long ipId, long userId, Account caller) throws ResourceUnavailableException {
    List<FirewallRule> rules = new ArrayList<FirewallRule>();
    List<FirewallRuleVO> fwRules = _firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall);
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("Releasing " + fwRules.size() + " firewall rules for ip id=" + ipId);
    }
    for (FirewallRuleVO rule : fwRules) {
        // Mark all Firewall rules as Revoke, but don't revoke them yet - we have to revoke all rules for ip, no
        // need to send them one by one
        revokeFirewallRule(rule.getId(), false, caller, Account.ACCOUNT_ID_SYSTEM);
    }
    // now send everything to the backend
    List<FirewallRuleVO> rulesToApply = _firewallDao.listByIpAndPurpose(ipId, Purpose.Firewall);
    //apply rules
    if (!applyFirewallRules(rulesToApply, rulesContinueOnErrFlag, caller)) {
        if (!rulesContinueOnErrFlag) {
            return false;
        }
    }
    // Now we check again in case more rules have been inserted.
    rules.addAll(_firewallDao.listByIpAndPurposeAndNotRevoked(ipId, Purpose.Firewall));
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("Successfully released firewall rules for ip id=" + ipId + " and # of rules now = " + rules.size());
    }
    return rules.size() == 0;
}
Also used : ArrayList(java.util.ArrayList) FirewallRule(com.cloud.network.rules.FirewallRule) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) ActionEvent(com.cloud.event.ActionEvent)

Example 5 with FirewallRuleVO

use of com.cloud.network.rules.FirewallRuleVO in project cloudstack by apache.

the class FirewallManagerImpl method detectRulesConflict.

@Override
public void detectRulesConflict(FirewallRule newRule) throws NetworkRuleConflictException {
    List<FirewallRuleVO> rules;
    if (newRule.getSourceIpAddressId() != null) {
        rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null);
        assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " + "network conflicts so we should at least have one rule at this point.";
    } else {
        // fetches only firewall egress rules.
        rules = _firewallDao.listByNetworkPurposeTrafficTypeAndNotRevoked(newRule.getNetworkId(), Purpose.Firewall, newRule.getTrafficType());
        assert (rules.size() >= 1);
    }
    for (FirewallRuleVO rule : rules) {
        if (rule.getId() == newRule.getId()) {
            // Skips my own rule.
            continue;
        }
        boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()))));
        // if both rules are firewall and their cidrs are different, we can skip port ranges verification
        boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall);
        boolean duplicatedCidrs = false;
        if (bothRulesFirewall) {
            // Verify that the rules have different cidrs
            _firewallDao.loadSourceCidrs(rule);
            _firewallDao.loadSourceCidrs((FirewallRuleVO) newRule);
            List<String> ruleCidrList = rule.getSourceCidrList();
            List<String> newRuleCidrList = newRule.getSourceCidrList();
            if (ruleCidrList == null || newRuleCidrList == null) {
                continue;
            }
            Collection<String> similar = new HashSet<String>(ruleCidrList);
            similar.retainAll(newRuleCidrList);
            if (similar.size() > 0) {
                duplicatedCidrs = true;
            }
        }
        if (!oneOfRulesIsFirewall) {
            if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
                throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id=" + newRule.getSourceIpAddressId());
            } else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
                throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id=" + newRule.getSourceIpAddressId());
            }
        }
        if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
            throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule " + rule.getXid());
        }
        if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
            if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) {
                throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId());
            }
        }
        boolean notNullPorts = (newRule.getSourcePortStart() != null && newRule.getSourcePortEnd() != null && rule.getSourcePortStart() != null && rule.getSourcePortEnd() != null);
        boolean nullPorts = (newRule.getSourcePortStart() == null && newRule.getSourcePortEnd() == null && rule.getSourcePortStart() == null && rule.getSourcePortEnd() == null);
        if (nullPorts && duplicatedCidrs && (rule.getProtocol().equalsIgnoreCase(newRule.getProtocol())) && !newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO)) {
            throw new NetworkRuleConflictException("There is already a firewall rule specified with protocol = " + newRule.getProtocol() + " and no ports");
        }
        if (!notNullPorts) {
            continue;
        } else if (!oneOfRulesIsFirewall && !(bothRulesFirewall && !duplicatedCidrs) && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
            // we allow port forwarding rules with the same parameters but different protocols
            boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) || (rule.getPurpose() == Purpose.Vpn && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
            boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
            boolean allowVpnPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
            boolean allowVpnLb = (rule.getPurpose() == Purpose.LoadBalancing && newRule.getPurpose() == Purpose.Vpn && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
            if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall || allowVpnPf || allowVpnLb)) {
                throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId() + " which has " + rule.getSourcePortStart() + "-" + rule.getSourcePortEnd());
            }
        }
    }
    if (s_logger.isDebugEnabled()) {
        s_logger.debug("No network rule conflicts detected for " + newRule + " against " + (rules.size() - 1) + " existing rules");
    }
}
Also used : InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) NetworkRuleConflictException(com.cloud.exception.NetworkRuleConflictException) FirewallRuleVO(com.cloud.network.rules.FirewallRuleVO) HashSet(java.util.HashSet)

Aggregations

FirewallRuleVO (com.cloud.network.rules.FirewallRuleVO)32 ArrayList (java.util.ArrayList)18 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)9 ResourceUnavailableException (com.cloud.exception.ResourceUnavailableException)8 IPAddressVO (com.cloud.network.dao.IPAddressVO)8 FirewallRule (com.cloud.network.rules.FirewallRule)8 DB (com.cloud.utils.db.DB)7 List (java.util.List)7 ActionEvent (com.cloud.event.ActionEvent)6 Network (com.cloud.network.Network)6 NetworkVO (com.cloud.network.dao.NetworkVO)6 Test (org.junit.Test)6 Account (com.cloud.user.Account)5 TransactionStatus (com.cloud.utils.db.TransactionStatus)5 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)5 HashSet (java.util.HashSet)5 DataCenter (com.cloud.dc.DataCenter)4 NetworkRuleConflictException (com.cloud.exception.NetworkRuleConflictException)4 PortForwardingRuleVO (com.cloud.network.rules.PortForwardingRuleVO)4 PhysicalNetwork (com.cloud.network.PhysicalNetwork)3