Firewall Android con VpnService

Sto cercando di implementare un semplice firewall per Android con il progetto VpnService per BS. Ho scelto VpnService perché lavorerà su dispositivi non radicati. Registra le connessioni e ti consente di filtrare la connessione. (Basato su IP)

C'è un'applicazione in questo modo è ansible.

  • Installazione silenziosa su dispositivi Android
  • Come aprire le autorizzazioni per le applicazioni nei dispositivi MIUI in modo programmato?
  • È una buona idea utilizzare libreria Google Guava per lo sviluppo di Android?
  • Android NDK. Come giocare il video.
  • Quando devo chiudere un cursore e un db?
  • come mostrare la barra di avanzamento prima di riprodurre il video
  • Google gioca l'app store

    Ho fatto qualche ricerca e ho scoperto che VpnService crea un'interface Tun. Niente di più. (Nessuna implementazione VPN è solo un tunnel) Consente di dare un indirizzo a questa interface e aggiungere routes. Restituisce un descrittore di file. È ansible leggere i pacchetti in output e scrivere i pacchetti in arrivo.

    Ho creato una class derivata VpnService e ho iniziato il servizio. Posso configurare tun0 con la class VpnService.Builder. Quando guardo mobiwol's connessione mobiwol's con adb shell netcfg crea un'interface tun0 con l'indirizzo 10.2.3.4/32. Itcrive tutti i pacchetti a questa networking privata e invia a Internet. Sto provando lo stesso. Creata un'interface con l'indirizzo 10.0.0.2/32. Aggiunto un path con function addRoute. 0.0.0.0/0 così posso catturare tutti i pacchetti da tutta la networking per quanto ne capisco. (Im piuttosto nuovo a questo argomento e ancora imparando, ho trovato pezzi su internet, quindi non sono certo.) Correggi se sono sbagliato.)

    Ho creato 2 thread in servizio. Si legge dal descrittore di file e lo scrive in 127.0.0.1 con una presa protetta. (Im non sono sicuro se dovrei leggere / scrivere a 127.0.0.1. Forse questo è il problema.)

    Ho analizzato i pacchetti che ho letto dal descrittore di file. Per esempio:

     01000101 byte:69 //ipv4 20byte header 00000000 byte:0 //TOS 00000000 byte:0 //Total Length 00111100 byte:60 //Total Length 11111100 byte:-4 //ID 11011011 byte:-37 //ID 01000000 byte:64 //fragment 00000000 byte:0 //" 01000000 byte:64 //TTL 00000110 byte:6 //Protocol 6 -> TCP 01011110 byte:94 //Header checksum 11001111 byte:-49 //Header checksum 00001010 byte:10 //10.0.0.2 00000000 byte:0 00000000 byte:0 00000010 byte:2 10101101 byte:-83 //173.194.39.78 //google 00111110 byte:-62 00100111 byte:39 ******** byte:78 10110100 byte:-76 // IP option 01100101 byte:101 00000001 byte:1 10111011 byte:-69 //20byte IP haeder 01101101 byte:109 . . //40byte data (i couldnt parse TCP header, I think its not needed when I route this in IP layer) . . . . 00000110 byte:6 

    Non ho trovato alcuna intestazione IP nel resto dei dati. Penso che ci dovrebbe essere un incapsulamento tra la networking 10.0.0.2 alla networking locale (192.168.2.1) e l'internet. Non ne sono sicuro.

    Il mio vero problema è che mi sono bloccato sul thread dei pacchetti in arrivo. Non riesco a leggere niente. Nessuna risposta. Come potete vedere nello screenshot nessun dato in entrata:

    image dello schermo

    Sto cercando di leggere dalla stessa connessione che sto usando per la scrittura a 127.0.0.1 con socket protetta.

    Android <-> Tun Interface (tun0) <-> Connessione a Internet

    Tutti i pacchetti <-> 10.0.0.2 <-> 127.0.0.1? <-> 192.168.2.1 <-> Internet?

    Non potrei trovare niente di utile per VpnService. (L'esempio di ToyVPN è solo inutile) Ho letto i documenti relativi a Linux Tun / Tap, ma il relativo tunneling tra host e remoto. Voglio host e remoto nello stesso dispositivo. Non come tunneling.

    Come posso fare questo?

    Modifica: Codice richiesto. È in fase molto precoce. Come ho già detto prima è una class derivata da VpnService. 2 thread (lettura e scrittura) creati nel thread di servizio.

     package com.git.firewall; public class GITVpnService extends VpnService implements Handler.Callback, Runnable { private static final String TAG = "GITVpnService"; private String mServerAddress = "127.0.0.1"; private int mServerPort = 55555; private PendingIntent mConfigureIntent; private Handler mHandler; private Thread mThread; private ParcelFileDescriptor mInterface; @Override public int onStartCommand(Intent intent, int flags, int startId) { // The handler is only used to show messages. if (mHandler == null) { mHandler = new Handler(this); } // Stop the previous session by interrupting the thread. if (mThread != null) { mThread.interrupt(); } // Start a new session by creating a new thread. mThread = new Thread(this, "VpnThread"); mThread.start(); return START_STICKY; } @Override public void onDestroy() { if (mThread != null) { mThread.interrupt(); } } @Override public boolean handleMessage(Message message) { if (message != null) { Toast.makeText(this, (String)message.obj, Toast.LENGTH_SHORT).show(); } return true; } @Override public synchronized void run() { try { Log.i(TAG, "Starting"); InetSocketAddress server = new InetSocketAddress( mServerAddress, mServerPort); run(server); } catch (Exception e) { Log.e(TAG, "Got " + e.toString()); try { mInterface.close(); } catch (Exception e2) { // ignore } Message msgObj = mHandler.obtainMessage(); msgObj.obj = "Disconnected"; mHandler.sendMessage(msgObj); } finally { } } DatagramChannel mTunnel = null; private boolean run(InetSocketAddress server) throws Exception { boolean connected = false; android.os.Debug.waitForDebugger(); // Create a DatagramChannel as the VPN tunnel. mTunnel = DatagramChannel.open(); // Protect the tunnel before connecting to avoid loopback. if (!protect(mTunnel.socket())) { throw new IllegalStateException("Cannot protect the tunnel"); } // Connect to the server. mTunnel.connect(server); // For simplicity, we use the same thread for both reading and // writing. Here we put the tunnel into non-blocking mode. mTunnel.configureBlocking(false); // Authenticate and configure the virtual network interface. handshake(); // Now we are connected. Set the flag and show the message. connected = true; Message msgObj = mHandler.obtainMessage(); msgObj.obj = "Connected"; mHandler.sendMessage(msgObj); new Thread () { public void run () { // Packets to be sent are queued in this input stream. FileInputStream in = new FileInputStream(mInterface.getFileDescriptor()); // Allocate the buffer for a single packet. ByteBuffer packet = ByteBuffer.allocate(32767); int length; try { while (true) { while ((length = in.read(packet.arrays())) > 0) { // Write the outgoing packet to the tunnel. packet.limit(length); debugPacket(packet); // Packet size, Protocol, source, destination mTunnel.write(packet); packet.clear(); } } } catch (IOException e) { e.printStackTrace(); } } }.start(); new Thread () { public void run () { DatagramChannel tunnel = mTunnel; // Allocate the buffer for a single packet. ByteBuffer packet = ByteBuffer.allocate(8096); // Packets received need to be written to this output stream. FileOutputStream out = new FileOutputStream(mInterface.getFileDescriptor()); while (true) { try { // Read the incoming packet from the tunnel. int length; while ((length = tunnel.read(packet)) > 0) { // Write the incoming packet to the output stream. out.write(packet.arrays(), 0, length); packet.clear(); } } catch (IOException ioe) { ioe.printStackTrace(); } } } }.start(); return connected; } private void handshake() throws Exception { if (mInterface == null) { Builder builder = new Builder(); builder.setMtu(1500); builder.addAddress("10.0.0.2",32); builder.addRoute("0.0.0.0", 0); //builder.addRoute("192.168.2.0",24); //builder.addDnsServer("8.8.8.8"); // Close the old interface since the parameters have been changed. try { mInterface.close(); } catch (Exception e) { // ignore } // Create a new interface using the builder and save the parameters. mInterface = builder.setSession("GIT VPN") .setConfigureIntent(mConfigureIntent) .establish(); } } private void debugPacket(ByteBuffer packet) { /* for(int i = 0; i < length; ++i) { byte buffer = packet.get(); Log.d(TAG, "byte:"+buffer); }*/ int buffer = packet.get(); int version; int headerlength; version = buffer >> 4; headerlength = buffer & 0x0F; headerlength *= 4; Log.d(TAG, "IP Version:"+version); Log.d(TAG, "Header Length:"+headerlength); String status = ""; status += "Header Length:"+headerlength; buffer = packet.get(); //DSCP + EN buffer = packet.getChar(); //Total Length Log.d(TAG, "Total Length:"+buffer); buffer = packet.getChar(); //Identification buffer = packet.getChar(); //Flags + Fragment Offset buffer = packet.get(); //Time to Live buffer = packet.get(); //Protocol Log.d(TAG, "Protocol:"+buffer); status += " Protocol:"+buffer; buffer = packet.getChar(); //Header checksum String sourceIP = ""; buffer = packet.get(); //Source IP 1st Octet sourceIP += buffer; sourceIP += "."; buffer = packet.get(); //Source IP 2nd Octet sourceIP += buffer; sourceIP += "."; buffer = packet.get(); //Source IP 3rd Octet sourceIP += buffer; sourceIP += "."; buffer = packet.get(); //Source IP 4th Octet sourceIP += buffer; Log.d(TAG, "Source IP:"+sourceIP); status += " Source IP:"+sourceIP; String destIP = ""; buffer = packet.get(); //Destination IP 1st Octet destIP += buffer; destIP += "."; buffer = packet.get(); //Destination IP 2nd Octet destIP += buffer; destIP += "."; buffer = packet.get(); //Destination IP 3rd Octet destIP += buffer; destIP += "."; buffer = packet.get(); //Destination IP 4th Octet destIP += buffer; Log.d(TAG, "Destination IP:"+destIP); status += " Destination IP:"+destIP; /* msgObj = mHandler.obtainMessage(); msgObj.obj = status; mHandler.sendMessage(msgObj); */ //Log.d(TAG, "version:"+packet.getInt()); //Log.d(TAG, "version:"+packet.getInt()); //Log.d(TAG, "version:"+packet.getInt()); } } 

  • android - Notifica Push Notification Firebase non funziona
  • filter intento android per estensione file personalizzata
  • Ricall solo i primi dati da una tabella
  • Corrispondenza di due file audio
  • Dove è il help.py per il monkeyrunner di Android
  • Disegnare Android EditText per mostrare il messaggio di errore come descritto da google
  • 2 Solutions collect form web for “Firewall Android con VpnService”

    Una domanda simile è stata sollevata qualche mese fa , e mentre le risposte non sono molto insightful, i commenti nella risposta accettata forniscono una visione in che cosa può andare male.

    Dovresti tenere presente quale livello nel model OSI la tua logica risiede:

    • I flussi in entrata e in output del VpnService sono nello strato di networking; stai ricevendo (e dovrebbe a sua volta trasmettere) i pacchetti IP grezzi, come descrivi nella tua domanda.

      Nel stream di byte di esempio, è ansible vedere che il stream di byte in arrivo è un datagramma IPv4 poiché i primi quattro bit sono 0100 (4). Consultare questa specifica della struttura dei pacchetti per i dettagli su IPv4.

    • Quando si inoltrano le richieste, si è nel livello applicativo; dovresti trasmettere il contenuto del carico utile UDP o TCP (cioè solo i propri dati, non gli intestazioni stessi) utilizzando rispettivamente un DatagramSocket o un socket.

      Tenga presente che questo salta il livello di trasporto poiché le implementazioni si occupano della costruzione dell'intestazione UDP (in caso di DatagramSocket) e dell'intestazione e delle opzioni TCP (in caso di Socket).

    L'applicazione dovrà essenzialmente essere in grado di interpretare e build intestazioni e opzioni IPv4 e IPv6 e come il payload IP, le intestazioni UDP e le intestazioni e le opzioni TCP.

    Forse è meglio cercare progetti open source come OpenVpn . Funziona in Livello API 14+ (Ice Cream Sandwhich) senza Accesso Root.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.