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 / coding / Perguntas / 79286131
Accepted
dimimir
dimimir
Asked: 2024-12-17 05:39:06 +0800 CST2024-12-17 05:39:06 +0800 CST 2024-12-17 05:39:06 +0800 CST

Como o ngrok gerencia com eficiência vários subdomínios sem criar registros DNS individuais?

  • 772

Quero construir um serviço similar ao ngrok e estou tentando entender a arquitetura por trás do gerenciamento de subdomínios do ngrok para seu serviço de tunelamento. Pelo que posso ver, o ngrok fornece subdomínios exclusivos (como abcde.ngrok.io) para cada túnel, mas estou intrigado sobre como eles gerenciam isso em escala.

Especificamente:

  1. Cada túnel tem um endereço IP separado? Se sim, como é que o ngrok tem um número tão grande de IPs? Como eles adicionam dinamicamente novos registros DNS para seus IPs?
  2. Se diferentes subdomínios são gerenciados pelo mesmo endereço IP, como o ngrok entende que eu me conectei ao a.ngrok.io, não ao b.ngrok.io se ambos têm o mesmo endereço IP? Eu sei, existem tecnologias como SNI, mas como isso funciona então se eu fizer um túnel TCP sem criptografia TLS?

E a pergunta principal: há uma maneira de implementar um sistema similar para um projeto de menor escala? Quais seriam os componentes-chave?

Qualquer insight sobre a arquitetura potencial ou melhores práticas para implementar tal sistema seria muito apreciado! Obrigado!

dns
  • 1 1 respostas
  • 26 Views

1 respostas

  • Voted
  1. Best Answer
    grawity_u1686
    2024-12-17T18:35:51+08:002024-12-17T18:35:51+08:00

    Cada túnel tem um endereço IP separado? Se sim, como é que o ngrok tem um número tão grande de IPs?

    Não, os endereços dos túneis são compartilhados entre os usuários.

    Como eles adicionam dinamicamente novos registros DNS para seus IPs?

    Primeiro, subdomínios curinga. O DNS suporta registros nomeados como *.example.com, que cobririam automaticamente qualquer subdomínio (de um nível) .example.comque não fosse especificamente definido de outra forma.

    Segundo: registros DNS, por analogia com URLs HTTP, não precisam ser adicionados em algum lugar, pois não há um banco de dados central de subdomínios; em vez disso, essas informações são fornecidas somente pelos próprios servidores de nomes do Ngrok. Então, assim como um webapp HTTP pode responder dinamicamente para várias URLs por meio de código, é possível escrever um servidor DNS que responda dinamicamente para vários subdomínios.

    Se diferentes subdomínios são gerenciados pelo mesmo endereço IP, como o ngrok entende que eu me conectei ao a.ngrok.io, não ao b.ngrok.io se ambos têm o mesmo endereço IP? Eu sei, existem tecnologias como SNI, mas como isso funciona então se eu fizer um túnel TCP sem criptografia TLS?

    Para túneis TCP simples, eles realmente não sabem disso. Até onde eu entendo o sistema deles, eles só usam números de porta TCP para distinguir entre túneis, já que você nunca obtém um subdomínio inteiro – você obtém apenas uma única porta TCP naquele endereço IP.

    E a pergunta principal: há uma maneira de implementar um sistema similar para um projeto de menor escala? Quais seriam os componentes-chave?

    Depende da escala. Em uma escala realmente pequena (como talvez 0–3 usuários), até mesmo servidores SSH padrão podem fornecer o mesmo tipo de tunelamento usando ssh -R(e o Ngrok ainda oferece o mesmo tipo de interface estilo SSH para seu backend personalizado).

    O código básico para tal serviço começaria como um proxy TCP comum (rinetd, haproxy, nginx) – você abre um soquete de escuta e, para cada conexão recebida, faz uma conexão de saída e cria um loop poll() que copia dados de um soquete para o outro.

    Para fazê-lo funcionar como o serviço do Ngrok, no entanto (onde a ideia é que o Ngrok não pode se conectar ao backend; o backend tem que se conectar ao Ngrok), você precisaria alterá-lo para que o proxy esteja escutando conexões de 'cliente' e conexões de 'agente' em dois ouvintes diferentes, e pareando-os de forma semelhante. (Semelhante a como socat tcp-l:1234 tcp-l:2345funcionaria.)

    Isso seria limitado a um cliente por vez, então o próximo passo seria alterar a conexão 'agente-proxy' para que ela pudesse multiplexar dados de vários clientes (semelhante a, por exemplo, como SSH ou QUIC têm vários "fluxos" distintos de dados dentro da conexão TCP) – e fazer o 'agente' desmultiplexá-los.

    Por exemplo, o proxy agora aceita uma conexão 'agente' e, para cada conexão 'cliente' recebida, ele envia um comando ao agente como "cliente nº 5 conectado – abra uma nova conexão com o backend, por favor" e "envie este pedaço de dados pela conexão de backend nº 5", e assim por diante. (Isso é muito parecido com o modo como ssh -Rfunciona também.)

    O resto é apenas tornar o proxy mais flexível, por exemplo, fazendo com que ele aloque automaticamente um novo ouvinte 'cliente' sempre que receber uma conexão 'agente', implementando verificações de manutenção de atividade para NAT, etc.

    • 1

relate perguntas

  • Posso usar o subdomínio em um endereço como um serviço web quando o próprio nome de domínio contém um subdomínio?

Sidebar

Stats

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

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

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