A network bridge between a Codespace and a local machine.
Перейти к файлу
Oleg Solomka 05ddaf264c
[readme]: improve wording
2022-04-14 08:01:34 -07:00
.github/ISSUE_TEMPLATE Create issue templates 2022-04-04 17:22:13 -07:00
diagrams [readme]: WIP 2022-04-05 01:04:59 +00:00
README.md [readme]: improve wording 2022-04-14 08:01:34 -07:00

README.md

Codespaces Network Bridge

🧪 The extension is currently in Preview stage, so some hiccups are expected. Please help us to improve by submitting feedback!

image

This GitHub CLI extension allows to bridge network between a Codespace and your local machine, so the Codespace can reach out to any remote resource that is reachable from your machine. In another words, it uses your local machine as a network gateway to get to those resources.

For instance, if you are using a VPN to connect to your enterprise network to access a database or any other remote resources on the private network, this extension allows you to get to those resources from within a Codespace, so that you can develop fully inside a Codespace!

About GitHub CLI.

Installation

This extension depends on the latest features of GitHub CLI(>= v2.8.0), please make sure to upgrade it.

How to check if my version works? Run `gh codespace select` command, if it opens the codespace selection dialog, you are good to go! image

Mac OSx:

gh extension install github/gh-net

Linux:

sudo gh extension install github/gh-net

The sudo is required during extension installation on Linux due to https://github.com/cli/cli/issues/5456. Hopefully it won't be the case in the future.

⚠️ If your Codespaces use non-default image, make sure that GitHub CLI is installed inside the Codespaces. The installation step can happen either in Dockerfile or in one of the .devcontainer.json lifecycle hooks e.g. postCreateCommand. See https://github.com/cli/cli#installation for GitHub CLI installation instructions.


Upgrading the extension (you need sudo on Linux):

gh extension upgrade github/gh-net

Usage

To start network forwarding from a Codespace to a local machine, run:

sudo gh net start

Note: sudo privileges are required to bind to network sockets on your machine.

This will provide codespace selection dialog:

image

Select a codespace and press enter. The extension will connect to selected codespace and start forwarding network traffic:

image

There are two pannels in the connected view of the extension:

  • Panel on the left (NAT) shows the network address translation table for currently opened connections. For stateful protocols(e.g. TCP) the records are cleaned up automatically after connection is closed so the records will come and go as connection is established and closed. For stateless protocols (e.g. UDP or ICMP) or unsuccessful TCP connections the records are cleaned up after some time, so those will show up in the list for some time.
  • Panel on the right (DNS) shows the resolved DNS records, as hostname, record and time-to-live (TTL) values.

Press q or ctrl + c to stop the extension.

CLI Options

  • --gui: Enanble/disable GUI mode. [true | false] [default: true]
  • --trace-level: Specify tracing verbosity. [none | trace | debug | info | warn | error] [default: info]

Run gh net start -h for details.

How it works

General diagram is shown below:

general schema

We bind to the default gateway network interface inside the codespace and forward all non-routed traffic to the SSH tunnel that connects a Codespace with your local machine. We forward only L3 (IP) traffic and there are few criterias must hold for traffic to be forwarded:

  • it must appear on the default gateway
  • it must not be addressed tosomething that is on default gateway subnet

This ensures that we fallback to forwaring packets only if they were not handled by any other network interface inside a Codespace.

Once a packet reaches the local machine, we see if we can forward it to a meaningful destination, for that we resolve network interface that can handle the packet destination. Such network interface must not be a default gateway interface given that the packet destination is not to the gateway subnet, otherwise the packet is addressed to the internet which can be handled from within the codespace directly.

If such network interface is found, we create a local network socket and a NAT record for the connection. The NAT record is used to map the remote packet source address to the local network socket address, so it appears to the remote resource as if traffic is coming from the local machine. When a reply packet is received, we perform reverse address translation and send the packet back to the codespace (so it appears as if the reply came directly from the codespace default gateway interface).

For DNS packets, we register an address that is on the default gateway subnet which allows to catch all unresolved DNS queries. Once DNS packet is received, it is passed over to the local machine where the request to the local DNS resolver is made and a reply is sent back to the codespace.

The extension is written in Rust and provides high preformance, low memory footprint and memory safety, hence must cause low latency.

Supported platforms

Target platforms Local Inside Codespace
Mac OSx (Intel) 🙅
Mac OSx (Apple) 🏃 🙅
Linux (Ubuntu)
Linux (Debian)
Linux (Fedora) ? ?
Linux (Red Hat) ? ?
Linux (Mint) ? ?
Linux (OpenSUSE) ? ?
Linux (Centos) ? ?
Linux (Kali) ? ?
Linux (Raspberry Pi OS) ? ?
Alpine Linux (bullseye) ?
Windows 10 🏃 🙅

- currently supported 🏃 - support in progress 🙅 - not applicable

DNS Record Type Support

DNS Record Type Status
A
AAAA
CNAME
NS
TXT
SOA
PTR
NULL
MX
ANY

Transport layer protocol support

Currently only TCP, UDP and ICMP protocols were tested extensively:

Transport protocol Status
TCP
UDP
ICMP
SCTP ?
DCCP ?
RSVP ?
QUIC ?

Network layer protocol support

Currently only IPv4 is supported and was tested extensively:

Network protocol Status
IPv4
IPv6 ?
IGMP ?
NDP ?
ECN ?
IPSec ?

Troubleshooting

Please search for existing issues before creating a new one.

Known issues

My local machine network configuration has changed but extension does not pick up the changes.

  • Please restart the extension by pressing q and connecting to the Codespace again. The extension currently does not watch for changes in network configuration and hence does not detect new network interfaces or changes in interfaces config. This will be fixed in the future.

I'm getting an error an a stack trace immediatelly after starting the extension.

  • Most likely you forgot to use sudo to run the extension. If sudo was used, please create a Bug report.

Extension suddenly stops working after some time and I see some stack traces in the console.

Most likely SSH connection was dropped or there was an intermittent network issue on your machine. The extension does not currently reconnects to the Codespace automatically. This will be fixed in the future. If this happens too often, please create a Bug report.

I'm trying to send Ethernet Datagrams(L2 network layer) directly and expect those to be forwarded but they are not.

The extension currently forwards IP(L3 network layer) traffic and above. If the datagrams contain IP packets that are addressed to a remote resource addressible from your local machine it should work. If it does not, please create a Bug report. If you want to send Ethernet Datagrams directly, please create a Feature request, we would love to know about your use case!

I'm using some transport protocol that does not work.

Currently TCP/UDP and ICMP are supported. Other protocols should work but were not tested extensivelly. Please create Bug report so we can address the issue.