iptables -a -i 区别
在iptables中,-A和-I的区别主要体现在规则的插入位置和匹配优先级上:12
iptables -A:这个选项用于在规则链的末尾附加一条新的规则。当防火墙进行包匹配时,它会按照规则链中规则的顺序,从上到下依次检查每一条规则,直到找到与数据包匹配的规则并执行相应的操作。因此,使用-A添加的规则会位于现有规则之后,这意味着它只会影响那些没有在其他规则中匹配到的数据包。
iptables -I:这个选项用于将一条新的规则插入到规则链的特定位置。如果-I后面没有指定具体的规则链位置,那么它默认会将新规则插入到规则链的开头。这意味着使用-I添加的规则具有最高的匹配优先级,它会在其他所有规则之前被检查。
总结来说,-A和-I的主要区别在于它们将规则添加到规则链的不同位置,从而影响匹配的顺序和优先级。使用-A添加的规则会位于规则链的末尾,而使用-I添加的规则则会位于规则链的开头,具有最高的匹配优先级。
int FirewallController::setUidRule(ChildChain chain, int uid, FirewallRule rule) {
const char* op;
const char* target;
FirewallType firewallType = getFirewallType(chain);
if (firewallType == WHITELIST) {
target = "RETURN";
// When adding, insert RETURN rules at the front, before the catch-all DROP at the end.
op = (rule == ALLOW)? "-I" : "-D";
} else { // BLACKLIST mode
target = "DROP";
// When adding, append DROP rules at the end, after the RETURN rule that matches TCP RSTs.
op = (rule == DENY)? "-A" : "-D";
}
std::vector<std::string> chainNames;
switch(chain) {
case DOZABLE:
chainNames = { LOCAL_DOZABLE };
break;
case STANDBY:
chainNames = { LOCAL_STANDBY };
break;
case POWERSAVE:
chainNames = { LOCAL_POWERSAVE };
break;
case NONE:
chainNames = { LOCAL_INPUT, LOCAL_OUTPUT };
break;
default:
ALOGW("Unknown child chain: %d", chain);
return -EINVAL;
}
if (mUseBpfOwnerMatch) {
return gCtls->trafficCtrl.changeUidOwnerRule(chain, uid, rule, firewallType);
}
std::string command = "*filter\n";
for (const std::string& chainName : chainNames) {
StringAppendF(&command, "%s %s -m owner --uid-owner %d -j %s\n",
op, chainName.c_str(), uid, target);
}
StringAppendF(&command, "COMMIT\n");
return (execIptablesRestore(V4V6, command) == 0) ? 0 : -EREMOTEIO;
进而分析如下android防火墙黑白名单添加uid规则时,
白名单
iptables-restore < *filter \n
-I fw_INPUT \n
-m owner --uid-owner uid -j RETURN \n
COMMIT \n
黑名单添加uid 规则时:
iptables-restore < *filter \n
-A fw_INPUT \n
-m owner --uid-owner uid -j DROP\n
COMMIT \n
因为白名单默认DROP,所以添加白名单时,被允许的应用匹配后,直接return不执行后面的DROP规则,所以RETURN规则要在DROP规则前,所以用-I。
而黑名单默认accept,所以添加白名单,被允许的应用数据匹配后,执行DROP,为了不影响其他应用,DROP要放在后面,所以用-A。特别是若已经存在return的规则,这样之前的return规则匹配后可以返回父链,不用判断DROP规则,提高效率。