1P by neo 3달전 | favorite | 댓글 1개

Fly.io의 WireGuard 개선 사항

  • Fly.io는 컨테이너를 VM으로 변환하여 전 세계적으로 하드웨어에서 Firecracker의 힘을 이용해 실행함.
  • WireGuard를 많이 사용하며, 이제 고객 API의 일부가 됨.
  • flyctl CLI를 실행할 때마다 TCP/IP 스택을 생성하고, 고유한 IPv6 주소를 사용하여 Fly Machines과 직접 통신함.
  • 이 접근 방식의 장단점이 있으며, 몇 가지 개선 사항이 있음.

이전 상황

  • 전 세계에 있는 "게이트웨이" 서버들이 WireGuard 연결을 수락하고 적절한 사설 네트워크에 연결하는 역할을 함.
  • flyctl을 실행할 때마다 백그라운드 에이전트 프로세스를 생성하거나 연결함.
  • 에이전트는 GraphQL API에서 새로운 WireGuard 피어 설정을 생성함.
  • API는 NATS 메시징 시스템을 통해 적절한 게이트웨이에 피어 설정을 전송함.
  • 게이트웨이에서 wggwd 서비스가 설정을 받아 SQLite 데이터베이스에 저장하고 커널에 추가함.
  • API가 GraphQL 요청에 응답하여 설정을 전달하고, flyctl이 WireGuard 피어에 연결함.
  • NATS는 빠르지만 배달을 보장하지 않으며, 게이트웨이에 남아 있는 오래된 피어들을 정리하지 않음.

더 나은 방법

  • WireGuard 피어를 저장하는 것은 복잡한 데이터베이스가 필요하지 않음.
  • 게이트웨이가 API에서 필요할 때마다 설정을 가져오도록 변경함.
  • 클라이언트가 연결을 원할 때만 커널에 피어를 추가하고, 필요 없을 때는 제거할 수 있음.

JIT WireGuard 피어 가능

  • Linux 커널의 WireGuard 설정 인터페이스는 Netlink를 사용함.
  • WireGuard 연결 요청 패킷을 BPF 필터와 패킷 소켓으로 식별하고 가로챌 수 있음.
  • WireGuard는 "클라이언트"와 "서버" 개념이 없으며, 점대점 프로토콜임.
  • flyctl이 게이트웨이에 UDP 패킷을 보내면, 이는 handshake initiation임.
  • BPF 필터를 사용하여 들어오는 연결을 잡을 수 있음.
  • Noise 프로토콜 프레임워크를 기반으로 하여, 요청을 식별하기 위해 암호화를 해제해야 함.
  • 이벤트 피드를 생성하여 게이트웨이에 연결을 시도하는 모든 사용자의 공개 키를 얻을 수 있음.
  • 새로운 피어를 볼 때마다 내부 HTTP API 요청을 통해 해당 피어 정보를 가져오고 설치함.

앱을 분 단위로 런칭

  • Fly.io에서 앱을 빠르게 배포하고 자체 JIT WireGuard 피어를 얻을 수 있음.

그래프 살펴보기

  • 몇 주 동안 이 시스템을 운영하며, 게이트웨이에 남아 있는 오래된 WireGuard 피어 수를 현저히 줄임.
  • 게이트웨이가 더 적은 상태를 유지하고 피어 설정이 더 빨라짐.
  • Grafana 차트를 통해 전환 당일의 성공적인 결과를 공유함.

GN⁺의 의견

  • Fly.io의 WireGuard 개선은 네트워크 성능과 안정성을 크게 향상시키는 좋은 예시임.
  • 이러한 접근 방식은 특히 클라우드 기반 서비스에서 네트워크 트래픽 관리와 보안을 강화하는 데 도움이 될 수 있음.
  • 비슷한 기능을 제공하는 다른 프로젝트로는 Tailscale이나 ZeroTier가 있으며, 이들도 개인 및 기업 사용자에게 VPN 대안을 제공함.
  • WireGuard를 도입할 때는 네트워크 구성, 보안 정책, 호환성 등을 고려해야 함.
  • 이 기술을 선택함으로써 얻는 이점은 빠른 성능과 간단한 구성이지만, 기존 인프라와의 통합이나 관리 측면에서 도전이 될 수 있음.
Hacker News 의견
  • 리눅스 커널의 WireGuard는 요청 시 피어를 설치하는 기능이 없어 설계 구축에 문제가 발생한다고 합니다.

    • 리눅스 커널의 WireGuard가 요청에 따라 피어를 설치하는 기능 부재로 설계에 어려움이 있음.
    • 런타임에 피어를 추가할 수 있지만, 인터페이스에 추가하기 전에 피어를 인증하여 불필요한 항목을 방지하려는 것으로 보임.
    • eBPF 필터를 사용하여 인증된 상대방과의 암호키 라우팅 기반 연결을 직접 관리하고, 검증이 완료되면 피어를 인터페이스에 추가하고 타임아웃 후 제거함.
  • HTTP 요청이 메시지 큐를 통한 라우팅보다 더 신뢰성이 있다는 데는 동의하지만, NATS로 인해 손실된 메시지가 서비스에 큰 영향을 미쳤다는 것에 놀랐습니다.

    • 직접 HTTP 요청이 메시지 큐보다 신뢰성이 높다는 의견에 동의하지만, NATS에서 메시지 손실이 서비스에 상당한 영향을 미쳤다는 점에 대해 의아함.
    • 메시지 손실 시 NATS가 재전송을 시도할 것으로 예상되지만, 눈에 띄는 신뢰성 문제가 발생한 이유에 대해 궁금증을 표함.
  • 최근 실험적인 프로젝트를 홍보하고 싶습니다. 사용자 공간 WireGuard 피어로 작동하는 Go 앱을 구축하는 데 관심이 있다면 확인해 보세요.

    • 사용자 공간 WireGuard 피어로 작동하는 Go 앱을 구축하는 데 관심 있는 사람들을 위해 자신의 프로젝트를 소개함.
    • wireguard-go의 우수한 작업을 기반으로 하되, 라이브러리 사용에 더 적합하도록 단순화하고자 함.
    • 서비스 메시 구축에 관심이 있으며, 다양한 언어 지원이 어려울 수 있지만 소켓 API를 구현할 수 있을 것으로 생각함.
    • WireGuard의 암호화에 대한 하드웨어 가속이 아직 보이지 않아 mTLS와 경쟁하기 어려울 수 있음을 언급함.
    • 고속/보안 네트워킹 분야에서 프리랜서로 활동하고 있으며, 관심 있는 사람은 연락 바람(이메일 프로필에 있음).
  • WireGuard를 WebSockets 위에 터널링하는 것이 기본 설정이라는 것이 흥미롭습니다. 성능에는 좋지 않지만 flyctl이 사용되는 DevOps 작업에는 적합할 것입니다.

    • WireGuard를 WebSockets를 통해 터널링하는 것이 기본 설정이라는 사실에 주목함.
    • 성능에는 최적이 아니지만, flyctl이 사용되는 DevOps 작업에는 문제가 없을 것으로 예상함.
    • QUIC/HTTP3의 미래에 대해 궁금해하며, 네트워크 운영자들이 UDP를 443 포트에서 차단하는 대신 제대로 처리할 가능성에 대해 의문을 제기함.
  • 우리는 발신자로서 피어를 설치할 수 있으며, flyctl이 응답자입니다. 리눅스 커널은 flyctl로 WireGuard 연결을 시작합니다. 이 방법은 작동하며, 프로토콜은 서버와 클라이언트가 누구인지 크게 신경 쓰지 않습니다. 새로운 연결이 가능한 한 빨리 설치됩니다.

    • 발신자로서 피어를 설치하고 flyctl이 응답자로서 리눅스 커널이 WireGuard 연결을 시작하는 방식에 대해 설명함.
    • 프로토콜이 서버와 클라이언트의 역할에 크게 구애받지 않으며, 새로운 연결이 매우 빠르게 이루어질 수 있음을 언급함.
  • 내 스타트업은 거의 1년 동안 Fly를 사용했습니다. 코드를 배포된 코드로 1분 이내에 전환하는 핵심 기능은 아름답습니다. 새 노드를 몇 초 만에 스핀업/다운할 수 있습니다.

    • 스타트업이 Fly를 거의 1년간 사용한 경험을 공유함.
    • 코드를 빠르게 배포할 수 있는 기능에 대해 긍정적으로 평가하지만, 회사가 다소 미성숙하다고 느낌.
    • API 서버가 Fly에서 48시간 동안 접근 불가능했던 경험과, "db" 제품의 일관성 없는 연결 끊김 문제를 언급함.
    • Fly의 API 접근이 자주 다운되어 새로운 서비스 수정을 배포하는 데 문제가 있었음을 지적함.
    • 배포 경험은 그리워하지만, GCP의 Cloud Run을 사용하는 것이 더 만족스러움을 표현함.
  • “flyctl을 실행할 때마다, 우리의 사랑스러운, 방대한 CLI는 공중에서 TCP/IP 스택을 만들어내고, 고유한 IPv6 주소를 가지고 직접 Fly Machines과 통신합니다.”

    • flyctl 실행 시 TCP/IP 스택을 즉석에서 생성하고 고유한 IPv6 주소를 통해 Fly Machines과 직접 통신한다는 설명에 대한 궁금증을 표함.
  • 초기 핸드셰이크 패킷이 네트워크 스택으로 재전송되는 것을 막는 것은 무엇인가요? 그렇게 하면 패킷 손실이 없을 것 같습니다. 또한 eBPF 필터에서 "udp[8] = 1"을 확인하는 목적은 무엇인가요?

    • 초기 핸드셰이크 패킷이 네트워크 스택으로 재전송되는 것을 방지하는 메커니즘과 eBPF 필터에서 특정 UDP 패킷 값을 확인하는 이유에 대한 질문을 제기함.
  • 임의의 도커화된 애플리케이션을 Fly.io에 배포하려면 어떻게 해야 하나요? 제 돈을 가져가세요

    • 도커화된 애플리케이션을 Fly.io에 배포하는 방법에 대한 관심과 의지를 표현함.
  • 다른 모든 사람들을 위해, Netmaker를 뻔뻔스럽게 홍보하겠습니다.

    • Netmaker를 사용한 만족스러운 경험을 공유하며, AWS VPC에 대한 개인적인 접근 필요성을 언급하고, Netmaker가 더 널리 채택되기를 희망함.