Android 14.0 系统限制上网系列之iptables用IOemNetd实现屏蔽ip黑名单的实现

1.前言

在14.0的系统rom定制化开发中,在system中netd网络模块这块的产品需要中,在系统中会要求设置屏蔽ip地址之内的功能,
liunx中iptables命令也是比较重要的,接下来就来在IOemNetd这块实现屏蔽ip黑名单的的相关功能,就是在
app中只能屏蔽某个网址,就是除了这个网址,其他的都能上网,最后在framework自定义服务中实现接口调用

2.  系统限制上网系列之iptables用IOemNetd实现屏蔽ip黑名单功能的实现的核心类

        system\netd\server\binder\com\android\internal\net\IOemNetd.aidl
        system\netd\server\OemNetdListener.cpp
        system\netd\server\OemNetdListener.h

3. 系统限制上网系列之iptables用IOemNetd实现屏蔽ip黑名单功能的实现的核心功能分析和实现

在android原生系统中,iptables是在网络过滤包模块非常重要的,Iptabels是与Linux内核集成的包过滤防火墙系统,linux和android都会包含Iptables的功能。
如果 Linux 系统连接到因特网或 LAN、服务器或连接 LAN 和因特网的代理服务器, 则Iptables有利于在 Linux 系统上更好地控制 IP 信息包过滤和防火墙配置。
netfilter/iptables的另一个重要优点是,它使用户可以完全控制防火墙配置和信息包过滤。您可以定制自己的规则来满足您的特定需求

iptables 常用命令如下:
命令                                        说明

-L  --list          <链名>  查看iptables规则列表
-A  --append        <链名>  在规则列表的最后增加1条规则
-I  --insert        <链名>  在指定的位置插入1条规则
-D  --delete        <链名>  从规则列表中删除1条规则
-F  --flush         <链名>  删除表中所有规则
-X  --delete-chain  <链名>  删除自定义链

“五链”是指内核中控制网络的NetFilter定义的五个规则链,分别为

PREROUTING, 路由前
INPUT, 数据包流入口
FORWARD, 转发管卡
OUTPUT, 数据包出口
POSTROUTING, 路由后

防火墙处理数据包的四种方式
ACCEPT 允许数据包通过
DROP 直接丢弃数据包,不给任何回应信息
REJECT 拒绝数据包通过,必要时会给数据发送端一个响应的信息

屏蔽ip黑名单的命令如下:
iptables -A OUTPUT -d 192.168.1.1 -j DROP

在上述的system/netd的模块中给,在上述的IOemNetd中的相关iptables的命令中,通过增加iptables的使用规则来实现屏蔽ip黑名单的相关功能
接下来就在IOemNetd中增加屏蔽ip黑名单的接口来实现功能

3.1 IOemNetd.aidl中增加屏蔽ip黑名单的接口

    /** {@hide} */
      interface IOemNetd {
         /**
          * Returns true if the service is responding.
          */
          boolean isAlive();
      
         /**
          * Register oem unsolicited event listener
          *
          * @param listener oem unsolicited event listener to register
          */
          void registerOemUnsolicitedEventListener(IOemNetdUnsolicitedEventListener listener);
     +     void setBlackIpList(const ::std::string& addr);// add core
      }

在system/netd下的 IOemNetd.aidl的增加屏蔽ip黑名单的接口中,通过上述的方法可以看出,在这里增加屏蔽ip黑名单的接口,
setBlackIpList(const ::std::string& addr);来实现功能,在这里framework可以通过binder通讯的方式,实现屏蔽ip黑名单的调用
,在这里framework可以通过binder通讯的方式,实现屏蔽ip黑名单的接口的调用规则来实现功能

3.2 OemNetdListener.h中增加屏蔽ip黑名单的接口

   namespace com {
      namespace android {
      namespace internal {
      namespace net {
      
      class OemNetdListener : public BnOemNetd {
        public:
          using OemUnsolListenerMap = std::map<const ::android::sp<IOemNetdUnsolicitedEventListener>,
                                               const ::android::sp<::android::IBinder::DeathRecipient>>;
      
          OemNetdListener() = default;
          ~OemNetdListener() = default;
          static ::android::sp<::android::IBinder> getListener();
      
          ::android::binder::Status isAlive(bool* alive) override;
          ::android::binder::Status registerOemUnsolicitedEventListener(
                  const ::android::sp<IOemNetdUnsolicitedEventListener>& listener) override;
     +   ::android::binder::Status setBlackIpList(const ::std::string& addr) override;
        private:
          std::mutex mMutex;
          std::mutex mOemUnsolicitedMutex;
      
          ::android::sp<::android::IBinder> mIBinder GUARDED_BY(mMutex);
          OemUnsolListenerMap mOemUnsolListenerMap GUARDED_BY(mOemUnsolicitedMutex);
      
          ::android::sp<::android::IBinder> getIBinder() EXCLUDES(mMutex);
      
          void registerOemUnsolicitedEventListenerInternal(
                  const ::android::sp<IOemNetdUnsolicitedEventListener>& listener)
                  EXCLUDES(mOemUnsolicitedMutex);
          void unregisterOemUnsolicitedEventListenerInternal(
                  const ::android::sp<IOemNetdUnsolicitedEventListener>& listener)
                  EXCLUDES(mOemUnsolicitedMutex);
      };
      
      }  // namespace net
      }  // namespace internal
      }  // namespace android
      }  // namespace com
      
      #endif  // NETD_SERVER_OEM_NETD_LISTENER_H

在system/netd下的 IOemNetd的增加屏蔽ip黑名单的接口的模块中,在IOemNetd.aidl的接口中增加对外调用IOemNetd的接口,而具体在OemNetdListener.cpp中具体实现IOemNetd.aidl的接口的功能的实现,接下来就需要在OemNetdListener.h中增加::android::binder::Status setBlackIpList(const ::std::string& addr) override;来定义
屏蔽ip黑名单接口,然后实现屏蔽ip黑名单功能

3.3 OemNetdListener.cpp中增加屏蔽ip黑名单的接口中

     #define LOG_TAG "OemNetd"
      
      #include "OemNetdListener.h"
      
      namespace com {
      namespace android {
      namespace internal {
      namespace net {
      
      ::android::sp<::android::IBinder> OemNetdListener::getListener() {
          static OemNetdListener listener;
          return listener.getIBinder();
      }
      
      ::android::sp<::android::IBinder> OemNetdListener::getIBinder() {
          std::lock_guard lock(mMutex);
          if (mIBinder == nullptr) {
              mIBinder = ::android::IInterface::asBinder(this);
          }
          return mIBinder;
      }
      
      ::android::binder::Status OemNetdListener::isAlive(bool* alive) {
          *alive = true;
          return ::android::binder::Status::ok();
      }
      
      ::android::binder::Status OemNetdListener::registerOemUnsolicitedEventListener(
              const ::android::sp<IOemNetdUnsolicitedEventListener>& listener) {
          registerOemUnsolicitedEventListenerInternal(listener);
          listener->onRegistered();
          return ::android::binder::Status::ok();
      }
     
    //add core start
    ::android::binder::Status OemNetdListener::setBlackIpList(const ::std::string& addr) {
         ALOGD("OemNetdListener:setBlackIpList addr=%s",addr.c_str());
        int res = -1;
        IptablesTarget target = V4V6;
        std::string command = "*filter\n";
        std::stringstream ss(addr);
        std::string ipAddr;
        while(std::getline(ss, ipAddr, '-')) {
            ::android::base::StringAppendF(&command, "-A %s -d %s -j DROP\n", "OUTPUT", ipAddr.c_str());
        }
        ::android::base::StringAppendF(&command, "-A %s -j ACCEPT\n", "OUTPUT");
        ::android::base::StringAppendF(&command, "COMMIT\n");
        
        res = execIptablesRestore(target, command.c_str());
        ALOGD("OemNetdListener:command=%s,res=%d",command.c_str(),res);
        if(res == 0) {
             return ::android::binder::Status::ok();
        } else {
            return ::android::binder::Status::fromServiceSpecificError(res,
                ::android::String8::format("OemNetdListener:setBlackIpList error: %d", res));
        }
    }
    //add core end

在system/netd下的 IOemNetd的增加屏蔽ip黑名单的接口模块中,在IOemNetd.aidl的接口中增加对外调用IOemNetd的接口,
而具体在OemNetdListener.cpp中具体实现IOemNetd.aidl的接口的功能的实现,所以在OemNetdListener.cpp中
增加::android::binder::Status OemNetdListener::setBlackIpList(const ::std::string& addr)来具体实现屏蔽ip黑名单的功能,
所以&command拼接iptables的命令,然后调用execIptablesRestore(target, command.c_str());来
执行屏蔽ip黑名单的功能,然后可以根据返回的res值来得知执行命令的结果

3.4 在创建的自定义服务中,来调用增加屏蔽ip黑名单的功能

在上述的IOemNetd的增加屏蔽ip黑名单的接口模块中,根据iptables相关的规则,需要在native netd中添加,可以参考其他的controller中的实现。
增加接口,需要在framework的NetworkManagementService或者自定义服务中添加;也需要在native层的INetd.aidl/IOemNetd.aidl中添加,
在native为了方便区分系统自带的接口和自定义接口,统一放在IOemNetd.aidl这里添加便可以。上层通过获取netd服务,调用接口

    IOemNetd.Stub.asInterface(mNetdService.getOemNetd());

得到IOemNetd的实例OemNetdListener,再调用具体接口。实现IOemNetd.aidl的iptables的相关调用具体实现如下:

  //add core start
    import android.os.INetworkManagementService;
    import com.android.internal.net.IOemNetd;
    import android.net.util.NetdService;
    import android.content.pm.ApplicationInfo;
    import java.net.InetAddress;
    import android.content.pm.PackageManager;
     
        private IOemNetd mIoemNetd;
            try {
                mIoemNetd = IOemNetd.Stub.asInterface(NetdService.getInstance().getOemNetd());
                //Log.d(TAG,"mIoemNetd:"+mIoemNetd);
            } catch (Exception e) {
                e.printStackTrace();
            }
        private InetAddress[] getInetAddress(String address) {
            InetAddress[] inetAddresses = null;
            try {
                inetAddresses = InetAddress.getAllByName(address);
            } catch (UnknownHostException e) {
    //            e.printStackTrace();
                return null;
            }
            return inetAddresses;
        }
    //add core end

在自定义服务中,实现增加屏蔽ip黑名单的接口功能中,通过创建IOemNetd mIoemNetd的实例,然后在framework中的自定义服务中,
在通过binder通讯的方式调用在IOemNetd中增加的增加的屏蔽ip黑名单的的功能,接下来来实现这个功能

 //add core start
        private Runnable mThreadRunnable = new Runnable() {
            @Override
            public void run() {
                try {
                  InetAddress[] inetAddresses = getInetAddress("www.hupu.com");
                  String ipAr="";
                  if (inetAddresses != null) {
                    for (int i=0;i< inetAddresses.length;i++ ) {
                        InetAddress inetAddress = inetAddresses[i];
                        String hostAddress = inetAddress.getHostAddress();
                        if(i==inetAddresses.length-1){
                           ipAr+=hostAddress;
                        }else{
                           ipAr+=hostAddress+"-";
                        }
                    }
                  }
                  Log.d(TAG,"ipAr:"+ipAr);
                  if(!TextUtils.isEmpty(ipAr)){
                     mIoemNetd.setBlackIpList(ipAr);
                  }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
     
    //add core end

在自定义服务中,实现增加屏蔽ip黑名单的接口中,通过创建IOemNetd mIoemNetd的实例后,就可以调用mIoemNetd.setBlackIpList(ipAr);
来实现IOemNetd中屏蔽ip黑名单的功能

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安卓兼职framework应用工程师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值