AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / unix / Perguntas / 407214
Accepted
ilyaigpetrov
ilyaigpetrov
Asked: 2017-11-27 22:11:52 +0800 CST2017-11-27 22:11:52 +0800 CST 2017-11-27 22:11:52 +0800 CST

Como fazer todo o tráfego passar por uma interface no Linux

  • 772

Eu tenho uma interface autoescrita tun0 ( baseada em TUN/TAP ) que emite o que recebe.
Preciso que todo tráfego do sistema flua por essa interface.
O papel da interface é:

  1. Para descobrir os pacotes que provavelmente serão censurados e canalizá-los.
  2. Passe todos os outros tráfegos intocados.

Como você deve imaginar, estou tentando construir uma ferramenta anticensura.
A decisão sobre o tunelamento deve ser tomada dentro do processo tun0
porque somente lá podemos usar DNS confiáveis.

Preciso da sua ajuda para me mostrar como fazer todo o tráfego fluir por meio de uma interface autoescrita tun0. Se tun0 precisar de alterações, peço que forneça essas alterações.

Abaixo está como tentei fazer todo o tráfego passar pelo tun0 e falhei (falha nos pings).

Compilando

  1. gcc tun0.c
  2. sudo ./a.out

Configurando

  1. sudo ip addr add 10.0.0.1/24 dev tun0
  2. criar tabela João

    $ cat /etc/iproute2/rt_tables 
    #
    # reserved values
    #
    255     local
    254     main
    253     default
    0       unspec
    #
    # local
    #
    #1      inr.ruhep
    
    200 John
    

A ordem é importante:

  1. sudo ip rule add from all lookup John
  2. sudo ip route add default dev tun0 table John
  3. sudo ip rule add iif tun0 lookup main priority 500

    $ ip rule
    0:      from all lookup local 
    500:    from all iif tun0 lookup main 
    32765:  from all lookup John 
    32766:  from all lookup main 
    35000:  from all lookup default 
    

Solução de problemas

  1. sudo tcpdump -i wlp2s0 -qtln icmpe então ping -I tun0 8.8.8.8não mostrar nenhum pacote capturado, significa que nenhum pacote foi transmitido de tun0 para wlp2s0 via iif tun0 lookup mainregra.

  2. Quando substituí tun0por lotodos os lugares, funcionou para mim.

Também tentei

  1. Desativando a filtragem de caminho reverso, rp_filter=0em/etc/sysctl.conf

Resposta Solução de problemas

iptables -I FORWARD -j LOG --log-prefix "filter/FORWARD " 
iptables -t nat -I OUTPUT -j LOG --log-prefix "nat/OUTPUT " 
iptables -t nat -I PREROUTING -j LOG --log-prefix "nat/PREROUTING " 
iptables -t nat -I POSTROUTING -j LOG --log-prefix "nat/POSTROUTNG "
tail -f /var/log/syslog

As fontes modificadas da resposta também estão aqui .

linux iptables
  • 1 1 respostas
  • 8807 Views

1 respostas

  • Voted
  1. Best Answer
    tifssoft
    2017-11-30T17:31:26+08:002017-11-30T17:31:26+08:00

    Então, na sua configuração, todos os pacotes que você tenta enviar para a rede inicialmente se originam 10.0.0.1(porque estão passando pela tun0interface e seu endereço local é 10.0.0.1). Você captura os pacotes, está tudo bem até agora.
    Agora, tun0envia os pacotes ainda mais. O endereço de origem é 10.0.0.1e você deseja que os pacotes saiam por uma interface diferente ( wlp2s0no seu caso). Isso é roteamento , então vamos habilitar o roteamento primeiro:

    sysctl -w net.ipv4.ip_forward=1
    

    Depois disso, se você observar, poderá notar que os pacotes saem com o endereço de origem tcpdumpe não com o endereço de origem da interface wlan (o que você esperaria, eu acho). Portanto, precisamos alterar o endereço de origem e é chamado source NAT . No Linux é fácil com a ajuda do netfilter/iptables :wlp2s010.0.0.1

    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.1 -j MASQUERADE
    

    Por favor, verifique também se sua FORWARDrede tem ACCEPTpolítica ou você precisa permitir o encaminhamento com algo como:

    iptables -A FORWARD -i tun0 -o wlp2s0 -s 10.0.0.1 -j ACCEPT
    iptables -A FORWARD -i wlp2s0 -o tun0 -d 10.0.0.1 -j ACCEPT
    

    Tudo deve funcionar agora: o kernel do linux faz o roteamento, está movendo os pacotes da tun0interface para o arquivo wlp2s0. O netfilter deve alterar o IP de origem para o endereço atribuído 10.0.0.1à sua wlp2s0interface para pacotes de saída. Ele memoriza todas as conexões e quando os pacotes de resposta voltam (se eles forem) ele muda o endereço de destino da wlp2s0interface atribuída ao endereço 10.0.0.1(o recurso "conntrack").
    Bem, deveria, mas não. Parece que o netfilter se confunde com essa complicada configuração de roteamento e com o fato de que o mesmo pacote primeiro passa pela OUTPUTcadeia e depois é roteado e chega à PREROUTINGcadeia. Pelo menos na caixa Debian 8 não funciona.
    A melhor maneira de solucionar problemas do netfilter é o TRACErecurso:

    modprobe ipt_LOG
    iptables -t raw -A OUTPUT -p icmp -j TRACE
    iptables -t raw -A PREROUTING -p icmp -j TRACE
    

    Eu só habilito o rastreamento de pacotes ICMP, você pode usar outro filtro para depurar.
    Ele mostrará por quais tabelas e cadeias o pacote passa. E posso ver que o pacote não vai além da FORWARDcadeia (e não está sendo pego pela nat/POSTROUTINGcadeia que realmente faz SNAT).
    Abaixo estão várias abordagens para fazer este trabalho.

    ABORDAGEM Nº 1

    A melhor maneira de desfazer a confusão do netfilter é alterar o endereço IP de origem dos pacotes no tun0.caplicativo. É também a forma mais natural. Precisamos alterar 10.0.0.1 para 10.0.0.2 na ida e 10.0.0.2 para 10.0.0.1 na volta.
    Modifiquei tun0.ccom o código de alteração do endereço de origem. Aqui está o novo arquivo e aqui está o patchfile para o seu arquivo tun0.c. Mudanças no cabeçalho IP também envolvem correção de soma de verificação , então peguei algum código do projeto OpenVPN . Aqui está a lista completa de comandos que executo após uma reinicialização e inicialização limpas tun0_changeip.c:

    ifconfig tun0 inet 10.0.0.1/30 up
    sysctl -w net.ipv4.ip_forward=1
    ip route add default dev tun0 table John
    ip rule add from all lookup John
    ip rule add from 10.0.0.2 lookup main priority 500
    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.0.2 -j MASQUERADE
    

    Observe que você não precisa desativar a filtragem de caminho reverso nesse caso, porque tudo é legal - tun0apenas recebe e envia pacotes que pertencem à sua sub-rede. Além disso, você pode fazer um roteamento baseado em origem em vez de baseado em interface.

    ABORDAGEM Nº 2

    É possível fazer antes da interface SNATde alcance do pacote . tun0Não é muito correto embora. Definitivamente, você precisará desativar a filtragem de caminho reverso neste caso:

    sysctl -w net.ipv4.conf.tun0.rp_filter=0
    # It won't work without also changing the "all" value
    sysctl -w net.ipv4.conf.all.rp_filter=0
    

    Agora, faça SNAT: iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source ip.address.of.your.wlan.interface

    Aqui, alteramos o endereço de origem pouco antes de os pacotes chegarem ao tun0dispositivo. tun0.co código reenvia esses pacotes "como estão" (com o endereço de origem alterado) e eles são roteados com sucesso pela interface wlan. Mas você pode ter um IP dinâmico na interface wlan e deseja usar MASQUERADE(para não especificar explicitamente o endereço da interface). Aqui está como você pode usar MASQUERADE:

    iptables -t nat -A POSTROUTING -o tun0 -s 10.0.0.1 -j SNAT --to-source 10.0.55.1
    iptables -t nat -A POSTROUTING -o wlp2s0 -s 10.0.55.1 -j MASQUERADE
    

    Observe o 10.0.55.1endereço IP " " - é diferente. Você pode usar qualquer IP aqui, não importa. Os pacotes alcançam nat/POSTROUTINGa cadeia na wlp2s0interface se alterarmos o IP de origem antes. E agora não depende de um IP estático para interface wlan.

    ABORDAGEM Nº 3

    Você também pode usar fwmark. Dessa forma, você não precisa SNAT, mas capturará apenas os pacotes de saída:
    Primeiro, precisamos desabilitar a filtragem de caminho reverso tun0porque ela encaminhará pacotes que pertencem a outra rede:

    sysctl -w net.ipv4.conf.tun0.rp_filter=0
    # It won't work without also changing the "all" value
    sysctl -w net.ipv4.conf.all.rp_filter=0
    
    Now let's alter the routing rules a bit:
    # Delete old rules
    ip rule del iif tun0 lookup main
    ip rule del from all lookup John
    
    # Packets will start going from wlan interface so they will have source address of it
    iptables -t mangle -A OUTPUT -o wlp2s0 -j MARK --set-mark 1
    ip rule add fwmark 0x1 lookup John
    

    Esse é outro "hack" para roteamento e netfilter que funciona na minha caixa Debian 8, mas ainda assim recomendo a primeira abordagem, pois é mais natural e não usa nenhum hack.


    Você também pode considerar construir seu aplicativo como um proxy transparente . Acho que seria muito mais fácil em vez de analisar pacotes do dispositivo tun.

    • 10

relate perguntas

  • Existe uma maneira de fazer ls mostrar arquivos ocultos apenas para determinados diretórios?

  • Inicie/pare o serviço systemd usando o atalho de teclado [fechado]

  • Necessidade de algumas chamadas de sistema

  • astyle não altera a formatação do arquivo de origem

  • Passe o sistema de arquivos raiz por rótulo para o kernel do Linux

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Matriz JSON para bash variáveis ​​usando jq

    • 4 respostas
  • Marko Smith

    A data pode formatar a hora atual para o fuso horário GMT? [duplicado]

    • 2 respostas
  • Marko Smith

    bash + lê variáveis ​​e valores do arquivo pelo script bash

    • 4 respostas
  • Marko Smith

    Como posso copiar um diretório e renomeá-lo no mesmo comando?

    • 4 respostas
  • Marko Smith

    conexão ssh. Conexão X11 rejeitada devido a autenticação incorreta

    • 3 respostas
  • Marko Smith

    Como baixar o pacote não instalá-lo com o comando apt-get?

    • 7 respostas
  • Marko Smith

    comando systemctl não funciona no RHEL 6

    • 3 respostas
  • Marko Smith

    rsync porta 22 e 873 uso

    • 2 respostas
  • Marko Smith

    snap /dev/loop em 100% de utilização -- sem espaço livre

    • 1 respostas
  • Marko Smith

    chave de impressão jq e valor para todos no subobjeto

    • 2 respostas
  • Martin Hope
    EHerman Matriz JSON para bash variáveis ​​usando jq 2017-12-31 14:50:58 +0800 CST
  • Martin Hope
    Christos Baziotis Substitua a string em um arquivo de texto enorme (70 GB), uma linha 2017-12-30 06:58:33 +0800 CST
  • Martin Hope
    Drux A data pode formatar a hora atual para o fuso horário GMT? [duplicado] 2017-12-26 11:35:07 +0800 CST
  • Martin Hope
    AllisonC Como posso copiar um diretório e renomeá-lo no mesmo comando? 2017-12-22 05:28:06 +0800 CST
  • Martin Hope
    Steve Como as permissões de arquivo funcionam para o usuário "root"? 2017-12-22 02:46:01 +0800 CST
  • Martin Hope
    Bagas Sanjaya Por que o Linux usa LF como caractere de nova linha? 2017-12-20 05:48:21 +0800 CST
  • Martin Hope
    Cbhihe Altere o editor padrão para vim para _ sudo systemctl edit [unit-file] _ 2017-12-03 10:11:38 +0800 CST
  • Martin Hope
    showkey Como baixar o pacote não instalá-lo com o comando apt-get? 2017-12-03 02:15:02 +0800 CST
  • Martin Hope
    youxiao Por que os diretórios /home, /usr, /var, etc. têm o mesmo número de inode (2)? 2017-12-02 05:33:41 +0800 CST
  • Martin Hope
    user223600 gpg — o comando list-keys gera uid [ desconhecido ] depois de importar a chave privada para uma instalação limpa 2017-11-26 18:26:02 +0800 CST

Hot tag

linux bash debian shell-script text-processing ubuntu centos shell awk ssh

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve