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 / 786133
Accepted
Avram
Avram
Asked: 2024-11-05 02:15:56 +0800 CST2024-11-05 02:15:56 +0800 CST 2024-11-05 02:15:56 +0800 CST

Faça com que bootpd e bootpc se comuniquem com sucesso

  • 772

O bootpc e o bootpd atuais do Debian (do bootp ) não parecem realmente funcionar juntos no ambiente do kernel Linux de hoje. Parece haver um problema 🐔/🥚; bootpdenvia as respostas como pacotes UDP unicast para o endereço IP ainda não configurado. O kernel do cliente então os descarta sem entregar ao bootpcsoquete do cliente, porque esse endereço IP não é (ainda) um endereço local válido no host.

Como isso funcionou?

  • Existe algum parâmetro do kernel ou outra modificação que pode fazer com que o kernel envie esses pacotes ao bootpcprocesso?
  • Existe uma configuração bootpdque fará com que ele use todos os endereços IP de destino 1 ou 0 em vez do endereço IP unicast do cliente ainda não configurado?

Temos um cliente em potencial com uma grande infraestrutura bootp não-DHCP. Suporte bootp old-school é um dos requisitos deles.

Detalhes do problema

  • bootpdenvia seus pacotes de resposta como pacotes unicast para o endereço MAC do cliente bootpc, usando um valor de endereço IP de destino do endereço que também está na carga útil, informando ao cliente para se configurar.
  • O kernel então descarta esses pacotes, em vez de entregá-los ao bootpcprocesso que os solicitou.
  • bootpcabriu corretamente um soquete de escuta para 0.0.0.0:68 0.0.0.0:*(veja a saída netstat abaixo)
  • Verifiquei essa análise de várias maneiras:
    • Eu corri tcpdumpe posso ver as respostas chegando ao NIC
    • Eu executei dropwatche vi os pacotes sendo descartados com o motivo IPINADDRERROR, que basicamente significa "endereço IP inválido"
    • Posso enganar bootpdpara usar 0.0.0.0 como o endereço IP de destino omitindo uma atribuição de IP real; quando faço isso, bootpcobtenho as respostas e as processa. No entanto, isso não ajuda porque o cliente não obtém um endereço IP
    • Eu tentei adicionar o endereço IP à interface enquanto bootpcela faz requisições. Depois que eu adiciono, a próxima resposta chega ao processo.
  • Eu também tentei a bootpc --serverbcastopção. Isso falha por um motivo similar:
    • bootpdenvia as respostas para o endereço de transmissão da sub-rede (por exemplo, 10.0.43.255)
    • Como o endereço IP e a máscara de sub-rede ainda não estão configurados em uma interface, o kernel não tem motivos para considerar isso um endereço válido para si mesmo.
  • Aqui está nossa bootptabconfiguração atual:
.vs-default:\
  :sm=255.255.254.0:\
  :gw=10.0.42.1:\
  :ds=10.0.42.1:\
  :hn:
client-ad02-vs:\
  ht=1:\
  ha=0xea4a1fad0002:\
  ip=10.0.42.31:\
  tc=.vs-default:

Saída do Netstat mostrando bootpc's listening socket:

$ sudo netstat -unlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
udp        0      0 0.0.0.0:68              0.0.0.0:*                           2295/bootpc         

Solução alternativa para o Hacky

Eu inventei uma solução alternativa que parece hackeada. Em particular, acho que ela aproveita um comportamento não intencional, talvez não possamos contar com ela para funcionar no futuro:

  • o módulo iptables conntrack tem uma correspondência ctstatecom um valor de DNAT.
  • Isso pode ser usado para aceitar pacotes que tenham um endereço IP de destino não reconhecido
  • Não creio que a intenção seja corresponder a IPs de horário de verão arbitrários:
    • Ele só pode ser usado com pacotes que foram NAT'd pelo kernel do mesmo host
    • Acredito que seu propósito seja corresponder a pacotes que tiveram seus endereços reescritos (o que não estamos fazendo), mas é uma implementação "barata" que ignora a tabela de mapeamento NAT em vez de verificar se há uma entrada que corresponde a esse pacote específico.
    • Estou preocupado que isso seja removido ou reescrito para ser menos promíscuo no futuro
    • Para que isso funcione, preciso mapear a porta desses pacotes para a porta DST existente, apenas para obter dados de estado da conexão NAT no pacote. Caso contrário, --ctstate DNATnão se aplica ao pacote.

Histórico/Due Diligence

  • Nosso ambiente de testes usa o Debian 12 no Linux 6.1.0.
  • Nossos hosts de teste são de imagens de VM prontas para uso do UTM Debian 12
  • bootpdtem muito poucas opções de cli, nenhuma das quais envolve respostas, portas ou endereços. A página do manual não menciona "broadcast" ou "unicast", e referências a "address" ou "destination" são poucas e não relevantes.
  • Nosso produto atual é o Debian 12 em um kernel Linux 5.19.9 personalizado (e se comporta da mesma maneira)
  • A conectividade IP está funcionando totalmente entre o cliente e o servidor do ambiente de teste
  • bootpcse recusa a enviar solicitações, a menos que o seguinte seja verdadeiro:
    • Não há nenhum endereço IP roteável na interface (169.254/16 é permitido, embora eu tenha tentado sem ele)
    • Há uma rota padrão 0/0 apontando para a interface onde o servidor bootp é esperado
      • Caso contrário, diznetwork unreachable
      • Nota: especificar --dev <iface>na bootpclinha de comando não ajuda com isso
  • Ainda estou trabalhando na avaliação de bootptabopções de configuração para ver se há alguma que afete isso. Não encontrei uma boa referência para elas, a bootptabpágina man do man é muito concisa sobre elas.

Solução alternativa

Consegui fazer isso funcionar com uma iptablessolução menos complicada: adicionei uma regra NAT que corresponde à porta UDP 68 (bootpc) e mapeia o endereço IP de destino para 255.255.255.255 (e mantém a mesma porta UDP).

Isso funciona, mas considero isso hacky. Claramente não é assim que o protocolo deve funcionar, então eu preferiria uma solução "real", se possível.

networking
  • 1 1 respostas
  • 47 Views

1 respostas

  • Voted
  1. Best Answer
    grawity
    2024-11-07T15:30:55+08:002024-11-07T15:30:55+08:00

    Parece haver um problema 🐔/🥚; o bootpd envia as respostas como pacotes UDP unicast para o endereço IP ainda não configurado. O kernel do cliente então as descarta sem entregar ao soquete do cliente bootpc, porque esse endereço IP não é (ainda) um endereço local válido no host.

    Como isso funcionou?

    O DHCP se comporta da mesma forma; a maioria dos clientes DHCP, e espero que também os clientes BOOTP, usam soquetes brutos para receber pacotes IP inteiros antes do processamento usual do kernel (bem como para enviar pacotes IP sem ainda ter nenhum endereço IP para enviá-los). O próprio software cliente constrói o cabeçalho IP e UDP completo ao enviar a descoberta ou solicitação e, em seguida, usa o BPF¹ para filtrar pacotes de entrada em vez do bind()-to-local-port usual.

    (Entre outras coisas, isso também ignora a filtragem de entrada do iptables e as correções de soma de verificação UDP.)

    Existe algum parâmetro do kernel ou outra modificação que possa fazer com que o kernel envie esses pacotes para o processo bootpc?

    O cliente deve ser reescrito para usar soquetes brutos ( AF_PACKET, PF_LINK, ou similar).

    Por exemplo, systemd-networkd usa socket(AF_PACKET, SOCK_DGRAM, ...)como nesta fonte . O cliente dhcpcd usa AF_LINKem alguns sistemas, AF_PACKETem outros, e da mesma forma filtra pacotes usando BPF¹ em vez de fazer o kernel fazer isso.

    Para simplificar as coisas, algumas partes podem ser manipuladas via libpcap.

    ¹ (Este é o BPF "clássico" – Berkeley Packet Filter – em vez do eBPF moderno, portanto não é específico do Linux e não requer nenhum recurso incomum.)

    Existe uma configuração para o bootpd que o fará usar todos os endereços IP de destino 1 ou 0 em vez do endereço IP unicast do cliente ainda não configurado?

    O servidor deve honrar um sinalizador "wants broadcast" na solicitação BOOTP ou DHCP. bootpcO cliente do Debian o define quando você passa --serverbcast(porque ele aparentemente não usa sockets raw):

      /* Server needs to broadcast for me to see it */
      if (broadcast || givenhwaddr)
        bootp_xmit->bp_flags |= htons(BPFLAG_BROADCAST);
    

    Mas o bootpservidor só honra esse sinalizador quando compilado com a DHCPopção que o Debian corrige nele:

    #ifdef DHCP
        /*
         * This code is placed here, because otherwise the siaddr
         * will not be found...
         */
        if (ntohs(bp->bp_flags) & 0x8000 && bp->bp_giaddr.s_addr==0)
            dst.s_addr = INADDR_BROADCAST;
    #endif
    

    Se você estiver tentando integrar seu novo servidor Bootp em uma rede de clientes Bootp existentes, então o ISC dhcpdpode funcionar melhor para você, pois parece ter um modo de compatibilidade com Bootp. (Sim, aquele que agora é EOL, mas pelo menos é menos EOL do que o servidor do Debian bootp– que parece ter sido tocado pela última vez em 1995).

    Da mesma forma, se você estiver tentando fazer seu sistema cliente funcionar com a infraestrutura Bootp existente, considere se você pode usar algum cliente DHCP no modo Bootp.

    • 1

relate perguntas

  • Encontrar threads/scripts associados a uma porta?

  • Pergunta sobre arquivos montados em rede

  • Um endereço IP pode terminar em 255 e não ser um endereço IP de transmissão?

  • Incapaz de identificar qual saída de endereço MAC do comando arp ou comando ip está correta

  • Roteador estranho funciona com centos 6 [fechado]

Sidebar

Stats

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

    Possível firmware ausente /lib/firmware/i915/* para o módulo i915

    • 3 respostas
  • Marko Smith

    Falha ao buscar o repositório de backports jessie

    • 4 respostas
  • Marko Smith

    Como exportar uma chave privada GPG e uma chave pública para um arquivo

    • 4 respostas
  • Marko Smith

    Como podemos executar um comando armazenado em uma variável?

    • 5 respostas
  • Marko Smith

    Como configurar o systemd-resolved e o systemd-networkd para usar o servidor DNS local para resolver domínios locais e o servidor DNS remoto para domínios remotos?

    • 3 respostas
  • Marko Smith

    apt-get update error no Kali Linux após a atualização do dist [duplicado]

    • 2 respostas
  • Marko Smith

    Como ver as últimas linhas x do log de serviço systemctl

    • 5 respostas
  • Marko Smith

    Nano - pule para o final do arquivo

    • 8 respostas
  • Marko Smith

    erro grub: você precisa carregar o kernel primeiro

    • 4 respostas
  • Marko Smith

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

    • 7 respostas
  • Martin Hope
    user12345 Falha ao buscar o repositório de backports jessie 2019-03-27 04:39:28 +0800 CST
  • Martin Hope
    Carl Por que a maioria dos exemplos do systemd contém WantedBy=multi-user.target? 2019-03-15 11:49:25 +0800 CST
  • Martin Hope
    rocky Como exportar uma chave privada GPG e uma chave pública para um arquivo 2018-11-16 05:36:15 +0800 CST
  • Martin Hope
    Evan Carroll status systemctl mostra: "Estado: degradado" 2018-06-03 18:48:17 +0800 CST
  • Martin Hope
    Tim Como podemos executar um comando armazenado em uma variável? 2018-05-21 04:46:29 +0800 CST
  • Martin Hope
    Ankur S Por que /dev/null é um arquivo? Por que sua função não é implementada como um programa simples? 2018-04-17 07:28:04 +0800 CST
  • Martin Hope
    user3191334 Como ver as últimas linhas x do log de serviço systemctl 2018-02-07 00:14:16 +0800 CST
  • Martin Hope
    Marko Pacak Nano - pule para o final do arquivo 2018-02-01 01:53:03 +0800 CST
  • Martin Hope
    Kidburla Por que verdadeiro e falso são tão grandes? 2018-01-26 12:14:47 +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

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