android实现网络防火墙控制app访问wifi/移动数据网络

iptables是Linux的一个命令行工具,通过设置一些规则可以直接把指定uid或网址的数据包从ip层过滤掉,从而实现网络防火墙的功能,这部分已经比较成熟,android或厂商只是对iptables命令进行了封装,让android app可以通过iptables命令进行防火墙设置,iptables有很多复杂的功能,我们主要看看怎么设置白名单只让指定的uid app可以联网和设置黑名单让指定的uid app不能联网,我们通过代码流程来分析,代码是mtk android8.1。

root后通过adb shell iptables -L可以查看当前的规则列表,Chain INPUT,OUTPUT就是控制数据包的输入输出,没做任何设置前应该张下面这个样子,Chain OUTPUT的数据包通过Chain fw_OUTPUT控制, Chain fw_OUTPUT的规则是空的,所以当前对网络不做限制。

$ adb shell iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
bw_INPUT   all  --  anywhere             anywhere            
fw_INPUT   all  --  anywhere             anywhere            

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         
oem_fwd    all  --  anywhere             anywhere            
fw_FORWARD  all  --  anywhere             anywhere            
bw_FORWARD  all  --  anywhere             anywhere            
natctrl_FORWARD  all  --  anywhere             anywhere            

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         
oem_out    all  --  anywhere             anywhere            
firewall   all  --  anywhere             anywhere            
fw_OUTPUT  all  --  anywhere             anywhere            
st_OUTPUT  all  --  anywhere             anywhere            
bw_OUTPUT  all  --  anywhere             anywhere           

Chain fw_FORWARD (1 references)
target     prot opt source               destination        

Chain fw_INPUT (1 references)
target     prot opt source               destination            

Chain fw_OUTPUT (1 references)
target     prot opt source               destination        

//android app层

INetworkManagementService networkService = INetworkManagementService.Stub.asInterface(ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));

    public void WhiteListMode(INetworkManagementService networkService) {
        FireWallUtils.setFirewallEnabled(networkService, true);//白名单模式
        FireWallUtils.setFirewallUidRule(networkService, 0, 1016, 0); //重置vpn uid rule
        FireWallUtils.setFirewallUidRule(networkService, 0, 1016, 1); //设置vpn uid为白名单
        FireWallUtils.setFirewallUidRule(networkService, 0, 0, 0); //重置root uid rule
        FireWallUtils.setFirewallUidRule(networkService, 0, 0, 1); //设置root uid为白名单
        
//          List<String> whitelistApp = new ArrayList<>();
//          whitelistApp.add("com.nuts.extremspeedup");
//          PackageManager pm = mContext.getPackageManager();
//            for (String pkgName : whitelistApp) {
//                int uid = FireWallUtils.getUidFromPackageName(pm, pkgName);
//                if (uid > 0) {
//                    FireWallUtils.setFirewallUidRule(networkService, 0, uid, 0); //重置 uid rule
//                    FireWallUtils.setFirewallUidRule(networkService, 0, uid, 1); //设置白名单
//                }
//            }
    }
    
    public void BlackListMode(INetworkManagementService networkService) {
        FireWallUtils.setFirewallEnabled(networkService, false); //黑名单模式
        
          List<String> whitelistApp = new ArrayList<>();
          whitelistApp.add("com.iflytek.inputmethod");//com.iflytek.inputmethod
          PackageManager pm = getPackageManager();
            for (String pkgName : whitelistApp) {
                int uid = FireWallUtils.getUidFromPackageName(pm, pkgName); //获取app的uid
                if (uid > 0) {
                    FireWallUtils.setFirewallUidRule(networkService, 0, uid, 0); //重置 uid rule
                    FireWallUtils.setFirewallUidRule(networkService, 0, uid, 2); //设置uid为黑名单
                }
            }
    }

    public void DisableMobileMode(INetworkManagementService networkService) {
        FireWallUtils.setFirewallEnabled(networkService, false); //黑名单模式
        
          List<String> whitelistApp = new ArrayList<>();
          whitelistApp.add("com.iflytek.inputmethod");//com.iflytek.inputmethod
          PackageManager pm = getPackageManager();
            for (String pkgName : whitelistApp) {
                int uid = FireWallUtils.getUidFromPackageName(pm, pkgName);
                if (uid > 0) {
                    FireWallUtils.setFirewallUidChainRule(networkService, uid, 0, false); //(networkType == 1) ? WIFI : MOBILE; , 禁止此uid连mobile
                }
            }
    }

 

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.INetworkManagementService;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

public class FireWallUtils  {
    private static final String TAG = "FireWallUtils";

    public static void setFirewallEnabled(INetworkManagementService networkService, boolean enable) {
        try {
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值