Androidは、Iptablesを利用してネットワーク白黒リスト(ファイアウォール)を実現する。
一、概要
この簡単なペンを読んでいる人がIptablesを簡単に理解するために、ここで強引に百度の概念を作りました。Iptablesの各種の配置規則とカーネルの管理運行メカニズムを深く理解したいならば、自行してください。これらは本簡筆の目的ではありません。
余談はさておいて、本文を始めます。
-->以下の概要はbaiduから来ています。読者は適宜スキップできます。
iptablesの前身はipfirewall(カーネル1.x時代)といい、freeBSDから移植されたもので、カーネルの中で働くことができ、パケットを検査する簡易アクセス制御ツールです。しかし、ipfirewallの機能は極めて限られています。(すべての規則をカーネルに入れる必要があります。このように規則が実行できます。カーネルに入れるのは一般的に難しいです。)カーネルが2.xシリーズに発展すると、ソフトウェアはipchainsと名前を変えて、複数のルールを定義して、彼らをつなぎ合わせて役割を果たしますが、今はiptablesといいます。ルールをリストに構成して、絶対的に詳細なアクセス制御機能を実現します。
彼らはすべてユーザーの空間の中で働くので、規則のツールを定義して、自身はファイアウォールとは言えません。彼らが定義したルールは、カーネル空間の中のnetfilterに読み込ませ、ファイアウォールを作動させることができます。カーネルを入れるところは特定の位置なら、tcp/ipのプロトコルスタックが通るところでなければなりません。このtcp/ipプロトコルスタックを通過しなければならないところで、読み取りルールが実現できるところをnetfilterといいます。
-->以下は本稿の注目点である。
二、Iptablesネットワークモノクロリスト(ファイアウォール)実現の詳細
いくつかの権限の問題を考慮して、このような方法を実行するためにsystemserverを作成します。そして、3つのアプリケーションにmanagerを提供し、これにより、呼び出し時にいくつかの権限の制限を排除することができる。また、本論文では簡単な参考概要を作成するだけですので、白黒リストを追加する方法とiptablesルールだけを提供しています。削除ルールなどは提供されていません。
2.1、システムズセーバーを作成する
2.1.1、system/sepolicy/service.teに追加
これを追加しなくてもいいですが、後からの呼び出しが便利なように追加しました。このステップをスキップすると、後ろにContect.FXJNET_が現れます。SERVICEのところは全部文字列で代用すればいいです。
3.1、Serviceが起動時に動作するように、system/core/rootdir/init.rcに次のように追加します。
この簡単なペンを読んでいる人がIptablesを簡単に理解するために、ここで強引に百度の概念を作りました。Iptablesの各種の配置規則とカーネルの管理運行メカニズムを深く理解したいならば、自行してください。これらは本簡筆の目的ではありません。
余談はさておいて、本文を始めます。
-->以下の概要はbaiduから来ています。読者は適宜スキップできます。
iptablesの前身はipfirewall(カーネル1.x時代)といい、freeBSDから移植されたもので、カーネルの中で働くことができ、パケットを検査する簡易アクセス制御ツールです。しかし、ipfirewallの機能は極めて限られています。(すべての規則をカーネルに入れる必要があります。このように規則が実行できます。カーネルに入れるのは一般的に難しいです。)カーネルが2.xシリーズに発展すると、ソフトウェアはipchainsと名前を変えて、複数のルールを定義して、彼らをつなぎ合わせて役割を果たしますが、今はiptablesといいます。ルールをリストに構成して、絶対的に詳細なアクセス制御機能を実現します。
彼らはすべてユーザーの空間の中で働くので、規則のツールを定義して、自身はファイアウォールとは言えません。彼らが定義したルールは、カーネル空間の中のnetfilterに読み込ませ、ファイアウォールを作動させることができます。カーネルを入れるところは特定の位置なら、tcp/ipのプロトコルスタックが通るところでなければなりません。このtcp/ipプロトコルスタックを通過しなければならないところで、読み取りルールが実現できるところをnetfilterといいます。
-->以下は本稿の注目点である。
二、Iptablesネットワークモノクロリスト(ファイアウォール)実現の詳細
いくつかの権限の問題を考慮して、このような方法を実行するためにsystemserverを作成します。そして、3つのアプリケーションにmanagerを提供し、これにより、呼び出し時にいくつかの権限の制限を排除することができる。また、本論文では簡単な参考概要を作成するだけですので、白黒リストを追加する方法とiptablesルールだけを提供しています。削除ルールなどは提供されていません。
2.1、システムズセーバーを作成する
2.1.1、system/sepolicy/service.teに追加
type fxjnet_service, system_api_service, system_server_service, service_manager_type;
2.2.2、在/system/sepolicy/service_contextsに下記のように追加します。
fxjnet u:object_r:fxjnet_service:s0
2.2.3、フレームワーク/base/core/java/android/content/Conttext.javaに追加これを追加しなくてもいいですが、後からの呼び出しが便利なように追加しました。このステップをスキップすると、後ろにContect.FXJNET_が現れます。SERVICEのところは全部文字列で代用すればいいです。
public static final String FXJNET_SERVICE="fxjnet";
2.2.4、フレームワーク/base/core/java/android/ap/System ServiceRegistry.javaの静的コードブロックに以下のコードを追加してserviceを登録します。
registerService(Context.FXJNET_SERVICE, FXJNETManager.class,
new CachedServiceFetcher<FXJNETManager>() {
@Override
public FXJNETManager createService(ContextImpl ctx) {
IBinder b = ServiceManager.getService(Context.FXJNET_SERVICE);
IFXJNETService service = IFXJNETService.Stub.asInterface(b);
return new FXJNETManager(ctx, service);
}});
2.2.5、フレームワーク/base/services/java/com/android/server/SystemServer.javaに下記のコードを追加し、serviceをsystemServerに加入する。
ServiceManager.addService(Context.FXJNET_SERVICE, new FXJNETService());
2.2.6、AIDLファイル
package android.os;
interface IFXJNETService{
void addNetworkRestriction(List<String> ipName,int type);
}
2.2.7、外部に提供するFXJNETManger
package android.app;
import android.os.IFXJNETService;
import android.os.RemoteException;
import android.content.Context;
public class FXJNETManager{
IFXJNETService mService;
public FXJNETManager(Context ctx,IFXJNETService service){
mService=service;
}
public void addNetworkRestriction(List<String> ipName,int type) {
try{
mService.addNetworkRestriction(ipName,type);
}catch (RemoteException e){
}
}//end addNetworkRestriction
}
2.2.8、システムサービスすなわちAIDLのServerを実現する
package com.android.server;
import android.os.IFXJNETService;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class FXJNETService extends IFXJNETService.Stub {
final File file = new File("/data/fxj/", "firewall.sh");
/**
* { IP }
*/
public void addNetworkRestriction(List<String> ipName,int type) {
String str= getIPlist(type,ipName);
setiptablesRestriction();
}
// Iptables ,1- ;2-
private String getIPlist(int type,List<String> iplist){
StringBuilder sb = new StringBuilder();
sb.append("echo runscript start
");
sb.append("iptables -F OUTPUT
");
if (type == 1){
if (iplist != null && iplist.size() > 0){
for (int i = 0 ; i < iplist.size() ;i++){
String ipname = iplist.get(i);
sb.append("echo blacklist mode
");
sb.append("iptables -I OUTPUT -d ");
sb.append(ipname);
sb.append(" -j DROP
");
}
}
}else if (type == 2){
if (iplist != null && iplist.size() > 0){
for (int i = 0 ; i < iplist.size() ; i++){
String ipname =iplist.get(i);
sb.append("echo whitelist mode
");
sb.append("iptabless -P OUTPUT DROP
");
sb.append("iptables -I OUTPUT -d ");
sb.append(ipname);
sb.append(" -j ACCEPT
");
}
}
}
sb.append("run script end
");
return sb.toString();
}
private void setiptablesRestriction(String ipName){
final FXJScriptRunner runner = new FXJScriptRunner(file,ipName,new StringBuilder());
new Thread(new Runnable() {
@Override
public void run() {
runner.run();
}
}).start();
}
}
2.2.9、IPTABLESスクリプトコマンドを実行するツール類
package com.android.server;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import android.os.FileUtils;
import android.os.SystemProperties;
import android.util.Log;
public class FXJScriptRunner extends Thread{
private final File file;
private final String script;
private final StringBuilder res;
public int exitcode = -1;
private final String TAG = "ScriptRunner" ;
public ScriptRunner(File file, String script, StringBuilder res,
boolean asroot) {
this.file = file;
this.script = script;
this.res = res;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
file.delete();
file.createNewFile();
final String abspath = file.getAbsolutePath();
// make sure we have execution permission on the script file
FileUtils.setPermissions(abspath, 00700, -1, -1);
Runtime.getRuntime().exec("chmod 777 " + abspath).waitFor();// sh
// Write the script to be executed
final OutputStreamWriter out = new OutputStreamWriter(
new FileOutputStream(file));
if (new File("/system/bin/sh").exists()) {
out.write("#!/system/bin/sh
");
}
out.write(script);
if (!script.endsWith("
"))
out.write("
");
out.write("exit 0
");
out.flush();
out.close();
// SystemProperties.set("ctl.start", "fxjmotnitor") service, ,
//fxjmotnitor service ,
SystemProperties.set("ctl.start", "fxjmotnitor");
} catch (Exception ex) {
if (res != null)
res.append("
" + ex);
} finally {
//destroy();
}
}
}
三、fxjmotnitor serviceの作成手順は以下の通りです。3.1、Serviceが起動時に動作するように、system/core/rootdir/init.rcに次のように追加します。
service fxjmotnitor /system/bin/sh /data/fxj/firewall.sh
class main
oneshot
seclabel u:r:fxjmotnitor:s0
3.2、sepolicy/ディレクトリの下でfxjmotnitor.teファイルを作成します。内容は以下の通りです。
type fxjmotnitor, domain;
type fxjmotnitor_exec, exec_type, file_type;
init_daemon_domain(fxjmotnitor)
allow fxjmotnitor shell_exec:file { entrypoint getattr read };
3.3、はい/sepolicy/file_contextsに追加
/data/fxj/firewall.sh u:object_r:fxjmotnitor_exec:s0
3.4、sepolicy/Android.mkの
BOARD_SEPOLICY_UNION += \
#
......\
fxjmotnitor.te \
......\
以上はiptables規則に基づいてipアドレスを制御し、携帯電話のipがアクセスできないプロセスの詳細を制限しています。もちろんiptablesの役割はこれに限らず、興味のあるものは自分で学習を知ることができます。私たちを応援してください。