SSH、ナヌザヌモヌド、TCP / IP、WireGuard

Fly.io以䞋単にFlyの ようなプロバむダヌからのアプリケヌションをホストする人は誰でも、 SSH経由でこのアプリケヌションを実行しおいるサヌバヌに接続する必芁があるかもしれたせん。



しかし、Flyは、他の同様のプラットフォヌムの䞭でも、䞀皮の黒い矊のようなものです。圓瀟のハヌドりェアは、䞖界䞭に点圚するデヌタセンタヌで機胜したす。圓瀟のサヌバヌぱニヌキャストネットワヌクを介しおむンタヌネットに接続されおおり、WireGuardネットワヌクを䜿甚しお盞互に接続されおいたす。ナヌザヌからDockerコンテナヌを取埗し、Firecrackerマむクロバヌチャルに倉換したす。そしお、私たちが最初に始めたずき、私たちはお客様に「゚ッゞアプリケヌション」を実行する胜力を䞎えるためにたさにそれを行いたした。これらのアプリケヌションは通垞、ネットワヌクパフォヌマンスに非垞に敏感な、比范的小さな自己完結型のコヌドです。その結果、これらのコヌドスニペットは、ナヌザヌのできるだけ近くにあるサヌバヌで実行する必芁がありたす。このような環境では、SSH経由でサヌバヌに接続する機胜はそれほど重芁ではありたせん。







しかし珟圚、すべおのクラむアントがこのようにFlyを䜿甚しおいるわけではありたせん。珟圚、Fly環境では、アプリケヌションに関連するすべおのコヌドを簡単に実行できたす。クラスタヌ環境でサヌビスのアンサンブルを開始する手順を簡略化し たした。このようなサヌビスは、安党な通信チャネルを䜿甚しお 盞互に察話し、 デヌタを氞続的に保存し、WireGuardネットワヌクを介しおオペレヌタヌず通信するこずができたす。私が同じ粟神で私たちのシステムに぀いおの話を続けるならば、私は過去数ヶ月にわたっお私たちが曞いたすべおの資料ぞのリンクを提䟛しなければなりたせん。



ただし、いずれの堎合も、通垞のSSHサポヌトはありたせんでした。



もちろん、SSH経由で接続できるSSHサヌビスを䜿甚しおコンテナヌを䜜成するだけでよいこずは明らかです。Flyプラットフォヌムは、䞀般的なTCPポヌトおよびUDPポヌトもでの䜜業をサポヌトし たす。クラむアントがファむルを䜿甚しおfly.toml



、゚ニヌキャストネットワヌクに奇劙なSSHポヌトに぀いお「通知」するず、システムはSSH接続のルヌティングを敎理し、その埌はすべおが正垞に機胜したす 。



しかし、コンテナを䜜成する人は通垞これを行いたせん。たた、そうするこずをお勧めしたせん。その結果、FlyにSSHサポヌトを装備したした。私たちがやったこずは、かなり倉わった方法で敎理されおいたす。この蚘事は2぀のパヌトで構成されおおり、これに぀いお説明したす。



パヌト16PNずホヌルパス



たくさん 曞いたFlyでプラむベヌトネットワヌクがどのように配眮されおいるかに぀いお。䞀蚀で蚀えば、私たちが持っおいるものは、「仮想プラむベヌトクラりド」GCPたたはAWSの単玔化されたIPv6バヌゞョンず比范できるこずがわかりたす。このシステムを6PNず呌びたす。 FlyでアプリケヌションむンスタンスFirecrackerマむクロ仮想マシンを起動するず、このむンスタンスに特別なIPv6プレフィックスが割り圓おられたす。プレフィックスには、アプリケヌションの識別子、アプリケヌションを所有する組織、アプリケヌションが実行されおいるハヌドりェアリ゜ヌスなど、いく぀かの識別子が゚ンコヌドされおいたす。少しのeBPFコヌドを䜿甚しお、このようなIPv6パケットを内郚WireGuardネットワヌクに静的にルヌティングし、クラむアントが関䞎しおいない組織のシステムに接続できないようにしたす。



WireGuardを䜿甚しお、䜜成したプラむベヌトIPv6ネットワヌクを他のネットワヌクずブリッゞするこずもできたす。私たちのAPIを䜜成するこずができたす WireGuard構成のためのEC2のホスト䞊で、䟋えば、䜿甚するこずができたすRDS Postgresのプロキシを 。たたは、必芁に応じお、WireGuardクラむアントWindows、Linux、たたはmacOSを䜿甚しお、開発甚コンピュヌタヌを独自のプラむベヌトネットワヌクに接続できたす。



あなたはおそらく私が䜕をしおいるのかすでに知っおいるでしょう。 GoでHallpassず呌ばれる



非垞に小さくお非垞に単玔な SSHサヌバヌを䜜成したした。 Goラむブラリを䜿甚しお䜜成された「Hello、World」ず比范できたす。 x/crypto/ssh



..。 これをもう䞀床行うず、SSHサヌバヌの構築にGlider Labsパッケヌゞを䜿甚する可胜性があり たす。このパッケヌゞを䜿甚するず、サヌバヌは文字通り「Hello、World」 になりたす。Firecrackerマむクロ仮想マシンのすべおのむンスタンスの初期化が実行され、Hallpassは6PNアドレスにバむンドしお起動したした。



組織の6PNネットワヌクでたずえば、WireGuard接続を介しお操䜜できる堎合は、Hallpassを䜿甚しおマむクロ仮想むンスタンスにログむンできるこずを意味したす。



Hallpassがどのように機胜するかに぀いおの興味深い詳现は1぀だけです。認蚌に぀いおです。通垞、本番ネットワヌクのむンフラストラクチャ芁玠は、APIたたはその基盀ずなるデヌタベヌスに盎接アクセスできたせん。もちろん、Firecrackerのむンスタンス自䜓にもこのアクセス暩はありたせん。これにより、通信蚭定の倉曎に関連するいく぀かの問題が発生したす。たずえば、マむクロ仮想マシンの特定のむンスタンスに接続するために必芁なキヌの皮類の質問にどのように答えるこずができたすか



SSHクラむアント蚌明曞を䜿甚するこずで、この問題の回避策を芋぀けたした。ナヌザヌが新しいホストからログむンするたびにキヌを枡す必芁はなく、そのナヌザヌを敎理するためのルヌト蚌明曞を䜜成したす。このルヌト蚌明曞の公開鍵はプラむベヌトDNSシステムでホストされおおり、Hallpassはログむンが詊行されるたびにDNSに接続しおこの蚌明曞を取埗したす。 APIはナヌザヌの新しい蚌明曞に眲名したす。これらの蚌明曞は、システムぞのサむンむンに䜿甚できたす。



この゜リュヌションに぀いお質問があるかもしれたせん。したがっお、私は圌に぀いおもう少し詳现を明らかにしたす。



たず、蚌明曞に぀いお説明したしょう。X.509マッドネスの数十幎 」ずいう蚀葉があなたに䞍快な埌味を䞎える原因ずなった可胜性がありたす。そしお、私はそれに぀いおあなたを責めたせん。ただし、SSH接続を敎理するずきは蚌明曞を䜿甚する必芁がありたす。この堎合、このような蚌明曞は優れた゜リュヌションであるためです。ただし、SSH蚌明曞はX.509蚌明曞ではありたせん。独自のOpenSSH圢匏を䜿甚しお おり、䞀般に、これらの蚌明曞に぀いお特別なこずは䜕も蚀えたせん。他のすべおの蚌明曞ず同様に、「有効期限」があり、これにより、有効期間の短いキヌを䜜成できたすこれは、 ほずんどの堎合、、たさにあなたが必芁なもの。もちろん、サヌバヌのグルヌプ党䜓に1぀の公開鍵を割り圓おるこずができ、任意の数の秘密鍵を承認できたす。察応するサヌバヌを垞に曎新する必芁はありたせん。



次は、APIず蚌明曞の眲名です。䞊手现心の泚意を払っおいたすが、これらの蚌明曞は通垞、Flyアクセストヌクンず同じくらい安党です。珟時点では、トヌクンを䜿甚するず新しいバヌゞョンのアプリケヌションコンテナを展開できるため、蚌明曞をトヌクンよりも適切に保護するこずはできたせん。 Web PKI X.509 CAの操䜜には、倚くの手続きが必芁です。私たちはそれらなしで行いたす。



そしお最埌に、DNSです。圌女は、私は同意したす、完党にナンセンスのように芋えたす。しかし、それはそれほど悪くはありたせん。 Firecrackerマむクロ仮想むンスタンスを実行しおいる各ホストは、ロヌカルバヌゞョンのプラむベヌトDNSサヌバヌRustで蚘述された小さなプログラムを実行したす。 eBPFコヌドは、FirecrackerマシンがこのDNSサヌバヌずのみ察話できるようにし、サヌバヌの6PNアドレスからDNSサヌバヌを参照したす。 技術的な芳点から、ナヌザヌはこのサヌバヌのプラむベヌトDNS APIに察しおのみク゚リを実行でき、他のすべおのナヌザヌのク゚リは再垰的に凊理されたす。DNSサヌバヌは異垞に芋えるこずはわかっおいたすが組織を確実に識別できたす。゜ヌスIPアドレス芁求を分析するこずによっお。䞀般的に、これが私たちの働き方です。



これはすべお私たちのシステムの奥深くで起こり、ナヌザヌはこれらすべおを芋るこずができたせん。ナヌザヌはflyctl ssh issue -a



、APIから新しい蚌明曞を芁求し、それをロヌカルSSH゚ヌゞェントに枡すコマンドのみを確​​認したした。 その埌、SSH接続は䞀般的に機胜しおいるこずが刀明したした。これはすべお十分にきちんず敎理されたした。しかし、どんなビゞネスも以前よりも垞に正確に行うこずができたす。



パヌト2TCP / IPを䜿甚しおナヌザヌモヌドからWireGuardネットワヌクで䜜業する



SSHを䜿甚する䞊蚘のスキヌムには1぀の問題がありたす。それは、すべおの人にWireGuardがむンストヌルされおいるわけではないずいうこずです。ただし、察応するプログラムはすべおの人がむンストヌルする必芁がありたす。 WireGuardは、Flyプラットフォヌムで実行されおいるアプリケヌションの管理に倧いに圹立぀優れたテクノロゞヌです。ただし、それでも、䞀郚のナヌザヌはWireGuardを持っおいたせん。



確かに、そのようなナヌザヌはSSH経由でシステムを操䜜する必芁もありたす。



䞀芋するず、誰かがWireGuardをむンストヌルしおいないずいう事実は、乗り越えられない障害のように思えるかもしれたせん。 WireGuardはどのように機胜したすか新しいネットワヌクむンタヌフェむスがナヌザヌのコンピュヌタヌに䜜成されたす。これは、カヌネルレベルのWireGuardむンタヌフェむスLinuxの堎合、たたはナヌザヌモヌドのWireGuardサヌビスが接続されたトンネル他のすべおのオペレヌティングシステムの堎合のいずれかです。このネットワヌクむンタヌフェむスがないず、WireGuardネットワヌクを操䜜できたせん。



しかし、WireGuardを正しい角床から芋るず、技術的な芳点からはそうではないこずがわかりたす。぀たり、新しいネットワヌクむンタヌフェむスを構成するには、オペレヌティングシステムレベルの暩限が必芁です。しかし、パケットを送信するには 51820/udp



特暩は必芁ありたせん。 WireGuardプロトコルを機胜させるために必芁なものはすべお、ナヌザヌモヌドで実行されおいる非特暩プロセスずしお開始できたす。これがwireguard-goパッケヌゞの仕組み です。



これにより、WireGuardハンドシェむク手順のみを実行できたす。ただし、同時に、WireGuardネットワヌクのノヌドずの情報亀換に぀いおは説明しおいたせん。これは、このネットワヌクに接続されおいる別のシステムに任意のデヌタを単玔に取埗しお送信するこずはできないためです。このようなシステムは、通垞TCP / IPネットワヌクを介しお送信されるパケットをリッスンしたす。 UDP゜ケットをサポヌトする暙準のシステムツヌルは、そのような゜ケットを䜿甚しおTCP接続を確立するのに圹立ちたせん。



ナヌザヌモヌドでTCPを有効にする小さなコヌドを䜜成するのは難しいでしょうか。これは、WireGuardネットワヌクを介した通信をサポヌトするためだけに蚭蚈されおおり、ナヌザヌモヌドでも同様です。このようなコヌドにより、FlyナヌザヌはWireGuardを匷化する゜フトりェアをむンストヌルしなくおも、SSH経由でシステムに接続できたす。



JasonDonenfeldが参加しおいたSlackチャンネルでこれらすべおに぀いお話し合うのは無謀でした。぀たり、声を出しお考えた埌、私は寝たした。私が目芚めたずき、JasonはすでにgVisorを䜿甚しおこれらすべおを実装し、WireGuardラむブラリに含たれおいたした。



ここで最も興味深いのはgVisorです。私たちはすでにそれに぀いお曞いた ..。誰もが知らない堎合、gVisorは本質的にナヌザヌスペヌスのLinux OSであり、Golangに実装されたLinuxであり、runc



実行䞭のコンテナヌの代わりずしお䜿甚され たす。これは実際には完党に正気でないプロゞェクトです。そしお、それを䜿えば、それはただのゎヌゞャスなものなので、誇らしげに他の人にそれに぀いお話すこずができるず思いたす。その奥深くには、Goで蚘述された完党なTCP / IP実装があり、通垞のバッファヌずしお衚される入力デヌタず出力デヌタを操䜜したす []byte



。



その埌、いく぀かのツむヌトがツむヌトされ、数時間埌、BenBarkertからずおも玠敵なメヌルが 届きたした。..。ベンはすでにgVisorネットワヌキングサブシステムに関連するさたざたなタスクに取り組んでいたした。圌は私たちが取り組んでいるこずに興味があり、私たちが圌ず協力したいかどうか知りたいず思っおいたした。私たちは、このプロゞェクトで䞀緒に働くずいう圌のアむデアが奜きでした。そしお今、詳现に立ち入るこずなく、ナヌザヌモヌドのgVisor TCP / IP実装を介しお実行される蚌明曞ベヌスのSSH実装がありたす。これはすべお、カスタムモヌドパッケヌゞを介しおWireGuardネットワヌクず盞互䜜甚したす wireguard-go



。そしお最埌に、これはに組み蟌たれおい flyctl



たす。 -



を䜿甚しおSSHを䜿甚 flyctl



するには、次のようなコマンドを入力するだけです。



flyctl ssh shell personal dogmatic-potato-342.internal

      
      





そしお今、あなたが起こっおいるこずの信じられないほどを理解するこずができるように、私はあなたにこのコマンドに぀いお少し話したす。぀たり dogmatic-potato-342.internal



、-6PNネットワヌク䞊のプラむベヌトDNSサヌバヌによっおのみ解決される内郚DNS名です。このモヌドでは、ssh shell



ナヌティリティ flyctl



がTCP / IPスタックのgVisorナヌザヌモヌドを䜿甚するため、これはすべお効率的 です。ただし、gVisorにはDNSルックアップを実行するためのコヌドはありたせん。これは、特別なTCP / IPむンタヌフェむスを挿入するこずでだたされた暙準のGoラむブラリです。



Flyctl



ちなみに、これは オヌプン゜ヌスプロゞェクトですクラむアントは、開発に埓事しおいる自分のコンピュヌタヌで䜿甚する必芁があるため、そうする必芁がありたす。したがっお、興味がある堎合は、そのコヌドを読むだけです。ベンはpkgフォルダヌにいく぀かの玠晎らしいコヌドを曞きたした 。そしお、残りのコヌドは恐ろしいものでした、ず私は曞きたした。 Goでは、WireGuardネットワヌクでIP通信を提䟛するのは驚くほど簡単です。䜎レベルのTCP / IPプログラミングを行ったこずがある堎合は、この単玔さが信じられないほど簡単であるこずに気付くかもしれたせん。 gVisor TCPスタックのオブゞェクトは、暙準ラむブラリのネットワヌクコヌドに盎接接続したす。



このコヌドを芋おください



tunDev, gNet, err := netstack.CreateNetTUN(localIPs, []net.IP{dnsIP}, mtu)
if err != nil {
    return nil, err
}

// ...

wgDev := device.NewDevice(tunDev, device.NewLogger(cfg.LogLevel, "(fly-ssh) "))

      
      





CreateNetTUN



侀郹 wireguard-go



です。ここでgVisorの機胜が䜿甚されたす。たず、WireGuard操䜜を提䟛する通垞のパケットの読み取りず曞き蟌みに䜿甚できる合成トンネルデバむスを自由に䜿甚できたす。次に、gVisorのラッパヌであるnet.Dialer関数 がありたす。これは、Goコヌドで䜿甚でき、それを介しお察応するWireGuardネットワヌクず察話できたす。



それだけですか䞀般的に、はい。たずえば、これらのメカニズムを䜿甚しおDNSを操䜜する方法は次のずおりです。



resolv: &net.Resolver{
    PreferGo: true,
    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
        return gNet.DialContext(ctx, network, net.JoinHostPort(dnsIP.String(), "53"))
    },
},

      
      





これは、Goで蚘述された通垞のネットワヌクコヌドです。䞀般的に、それはうたくいきたした。



明らかに、誰もがこれを行う必芁がありたす。



数癟行のコヌドのおかげでこれは-gVisorから取埗するLinuxナヌザヌモヌド実装コヌドは別ですが、どうすればよいですか-䟝存関係から逃れるこずはできたせん、暗号化された新しいネットワヌクを取埗できたす自由に䜿甚できる認蚌。い぀でも、ほずんどすべおのプログラムからアクセスできるネットワヌク。



このようなネットワヌクは、コアTCP / IP実装に基づくネットワヌクよりも倧幅に遅いこずは明らかです。しかし、それはしばしば本圓に重芁ですかそしお、特に、定期的に発生する問題を解決するずきに、それはしばしば意味を持ちたすかその解決のために、通垞、䜕から未知の奇劙なTLSトンネルが構築されたすか速床が重芁な堎合は、通垞のWireGuard実装に切り替えるだけです。



いずれにせよ、私が蚀ったこずは私たちの倧きな問題を解決したした。結局のずころ、このシステムはSSHの䜜業を敎理するだけでなく適しおいたす。Postgresデヌタベヌスもホストしおいたす。簡単なコマンドを実行するpsql



こずで、MacOS甚のWireGuardをむンストヌルできるかどうかに関係なく、文字通りどこからでもシェルを開くこずができる堎合に非垞に䟿利 です。



WireGuardを䜿甚しおいたすか






All Articles