Secure remote connectivity with VS Code for the Web

Tunnel Tech

Remote Tunneling Step-by-Step

To get started, first identify in which Linux user and user subdirectory to locate the VS Code Server CLI binaries. Next, log in and cd into the target destination subdirectory (possibly creating a new subdirectory as you go). Download the VS Code CLI from the VS Code download page. You can also use a tool like wget to download the binaries directly. For example, to download the Insiders edition of VS Code, enter:

wget -O vscode_cli_alpine_x64_cli.tar.gz 'https://code.visualstudio.com/sha/download?build=insider&os=cli-alpine-x64'

Note that if you want the stable edition of VS Code, then change the build query string to stable.

Next, unpack the compressed TAR with the command:

tar xzvf vscode_cli_alpine_x64_cli.tar.gz

If you want to make the binary available at the system level, one option is to copy the code executable to /usr/local/bin. Once you have copied the binary to a preferred location, verify the binary state and confirm the version of VS Code:

code --version

This command prints the code version and the final build commit.

As a side note, you can also source the standard version of VS Code from your local package manager. For example, you can install VS Code with snap:

sudo snap install code --classic

The next step is to set up the tunnel. First, inspect the tunneling command-line configuration options (Table 1):

code tunnel --help

Table 1

Tunnel Commands and Arguments

Command or Argument Function
Most Useful Commands
code tunnel --help Dump tunnel command-line help contents to standard output.
code tunnel --accept-server-license-terms --name remote384 Create a tunnel that is accessible to vscode.dev (integrates with GitHub.com). Accept the license terms and respond to the browser UI prompting to enter the code from initial CLI interaction. It is highly recommended to name your tunnel; otherwise, a host name will often be taken. You can also specify the argument --random-name to randomly name a tunnel for the port forwarding service.
code tunnel status Show the status of the tunnel, including the connection status.
code tunnel restart Restart all tunnels running locally.
Useful to Clean Up, Uninstall
code tunnel kill Stop all tunnels running locally.
code tunnel unregister Remove this machine's association with the port forwarding service.
code tunnel prune Delete all VS Code servers that are NOT currently running.
code tunnel rename Rename the specific tunnel.
Useful Arguments (e.g., to inspect verbose comments and debug info)
--cli-data-dir Directory where CLI metadata should be stored [env: VSCODE_CLI_DATA_DIR=]. The default is normally the .vscode-cli home subdirectory. Use this CLI argument to change to override and set an alternative path. Default home show/appears: /home/kevin/.vscode-cli/server-stable/.
--log <level> Log level to use (possible values: trace, debug, info, warn, error, critical, off).
--verbose Print verbose output during code tunnel execution.
Linux Background Service Management
code tunnel service install Install the tunnel service on this local machine.
code tunnel service log Dump service log contents to the console.
code tunnel service uninstall Uninstall the tunnel service on this local machine.
… with systemctl
systemctl --user restart code-tunnel.service systemctl to stop, start, restart, and get status.
systemctl --user status code-tunnel.service Manage at the user level.
systemctl --user stop code-tunnel.service Note differences between user and system.
systemctl --user --state=running | grep code Search for running Visual Studio Code server instances.
sudo loginctl enable-linger $USER Ensure the service stays running after you disconnect.

Now register and establish the tunnel while accepting first-time licensing services. Be sure to name the tunnel, and also remember the name! It will become important when you transition into a browser context. In my example, I named my tunnel remote384 :

code tunnel --name remote384 --accept-server-license-terms

I suggest a naming convention, something like remoteXYZ . Avoid using a naming pattern with tunnel because the VS Code remote extension already inserts the string tunnel as a fixed part of the URI base path. Monitor the log output from the startup phase of the VS Code Server process and scan for the device code:

*
* Visual Studio Code Server
* ..
* To grant access to the server, please log into https://github.com/login/deviceand use code 0123-9A8B

Once the device code is printed to the console, copy it to your text buffer and switch back to the active GitHub.com session in your web browser.

If you haven't already, log in to your GitHub account from the web browser where you plan to manage your remote session; then, input the authorization code to the GitHub device login page [3] (Figure 2).

Figure 2: GitHub.com prompts for authorization.

Once you verify the device code, the system will ask you to confirm GitHub authorizations for VS Code (Figure 3). The default authorizations grant full control over namespaces and access to read org projects, view user profile data, manage private repos fully, and update GitHub Actions workflows.

Figure 3: Authorize GitHub for VS Code access.

If you forget to specify the argument -accept-server-license-terms, you will be prompted to accept (y/n) the conditions. Similarly, if you don't specify the name argument, the system will prompt you to name the tunnel (aka machine name).

Once acknowledged, VS Code for Web indicates the "device" is now connected and that you are all set. For example, a console message will print the VS Code for Web URL (https://vscode.dev/tunnel/remote384).

You will be prompted to allow GitHub account access as part of the sign-in process. Depending on your browser user state, you could also see a dialog box confirming authorization. Opening the remote VS Code for Web session URL in a web browser will initiate the VS Code Server download to the remote environment (Figure 4). As the messaging illustrates (Listing 1), studying the log output can also confirm this behavior.

Figure 4: Feedback showing the VS Code Server download.

Listing 1

VS Code Download Log

[rpc.0] Checking /home/kevin/.vscode/cli/servers/Stable-f1b07bd25dfad64b0167beb15359ae573aecd2cc/log.txt and /home/kevin/.vscode/cli/servers/Stable-f1b07bd25dfad64b0167beb15359ae573aecd2cc/pid.txt for a running server...
[rpc.0] Downloading Visual Studio Code server -> /tmp/.tmp9ANcrP/vscode-server-linux-x64.tar.gz
[rpc.0] Starting server...
[rpc.0] Server started
.. ..

Part of session initialization will also activate several extensions, including ms-vscode.remote-server, in the local server-side environment. To view the list of extensions installed as part of the initial setup, including the setup of the remote tunnel, switch back to the VS Code for the Web user interface, then browse to the running extensions view (Figure 5).

Figure 5: Viewing running extensions (in particular, extensions installed by default).

VS Code Through a Browser

The basic layout of the VS Code for the Web user interface hosted at vscode.dev differs from its desktop sibling. Instead of a fixed top-level menu with File, Edit, Selection, and so forth, the launching point to access the menu navigation hierarchy is the icon with three vertical bars (hamburger menu) anchored to the top of the Activity Bar (Figure 6).

Figure 6: Access the menu hierarchy from the hamburger menu.

To open a project folder, click the hamburger menu, navigate to the File | Open Folder (Figure 7). The Integrated Terminal is also available in the Terminal submenu item. You can open multiple terminal windows from the browser, which display as tabs near the bottom-right corner.

Figure 7: Cascading Open Folder submenus.

VS Code supports comprehensive keyboard mappings to shortcut virtually all functions available in VS Code. With few exceptions, VS Code for the Web supports these keyboard mappings.

Typically classified as a code editor, VS Code provides enhanced debugging capabilities through language and tool-specific extensions. Figure 8 illustrates a Python debugging session in a VS Code for the Web context. Considering mainstream tasks and capabilities, VS Code for the Web is on par with its desktop sibling. (See also the "Managing Long-Running Tasks" boxout.)

Figure 8: The debugger facilities rendered in VS Code for the Web.

Managing Long-Running Tasks

By nature, remote tunnels are susceptible to disconnection events, especially if you are working in a dynamic environment where you might need to close your notebook. Consider the screen terminal multiplexer to manage such long-running tasks. Figure 9 illustrates the Redis project open in a VS Code for the Web session with the long-running make process executing in an integrated terminal. In this case, the build process is running for the Redis project, which is an extensive open source software system with many C source files and several build steps. In this scenario of using the screen utility, disconnection events will not cause the build process to bail out. Instead, the process can continue in the background, and the user or developer can later recall the screen as needed.

Figure 9: Building the Redis open source project in VS Code for the Web.

VS Code Server in the Background

The previous command series demonstrated how to interact manually with VS Code for the Web running in a foreground context. To make this a robust configuration, place VS Code Server in the background, configure it to auto-start from a user context, and verify that VS Code is available in the shell search path:

which code

To configure VS Code to run in the background, install the back-end program as a service:

code tunnel service install --accept-server-license-terms --name remote32

Similar to the earlier example, the arguments --accept-server-license-terms and --name <NAME> are available for first-time setup. Omitting either command-line argument will result in interactive prompting before installation.

The output of this service-oriented installation step will generate additional details regarding systemd unit files (Listing 2). Additionally, please pay attention to the loginctl tip it provided. Specifying the enable-linger command will enable this user-oriented background service to pre-initialize before any user login activity. In other words, the tunnel will be available in the background after a complete system startup, after a reboot, or after the user (or developer) that initiated this tunnel service logs out.

Listing 2

Back-End Installation Output

*
* Visual Studio Code Server
* ..
*
[2023-10-07 22:40:26] info Successfully registered service...
[2023-10-07 22:40:26] info Successfully enabled unit files...
[2023-10-07 22:40:26] info Tunnel service successfully started
[2023-10-07 22:40:26] info Tip: run `sudo loginctl enable-linger $USER` to ensure the service stays running after you disconnect.

To keep track of user sessions commenced on a particular Linux host, use this:

sudo loginctl list-sessions

Also, note that you can monitor and observe the most recent log contents of the VS Code server with the command:

code tunnel service log

Listing 3 is example log output from the VS Code Tunnel service. You can check the status of the tunnel with the status argument, which is available to both the code tunnel and code tunnel service commands. This example uses the tunnel service context:

code tunnel service status

Listing 3

VS Code Tunnel Log Output

code-tunnel.service - VS Code Tunnel
Loaded: loaded (/home/kevin/.config/systemd/user/code-tunnel.service; enabled; vendor preset: enabled)
Active: active (running) since .. ..
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/code-tunnel.service
|-- 33011 /usr/local/bin/code --verbose --cli-data-dir /home/kevin/.vscode/cli tunnel service internal-run
|-- 35321 sh /home/kevin/.vscode/cli/servers/Stable-f1b07bd25dfad64b0167beb15359ae573aecd2cc/server/bin/code-server --connection-tok>
...
Oct 14 15:20:43 ubuntu22-vbox code[33011]: [2023-10-14 15:20:43] debug [tunnels::connections::ws] sent liveness ping
Oct 14 15:20:43 ubuntu22-vbox code[33011]: [2023-10-14 15:20:43] debug [tunnels::connections::ws] received liveness pong

The tunnel status output (Insiders edition of VS Code) is shown in Listing 4. You will see an error status if no tunnel process is running.

Listing 4

Tunnel Status Output

{"tunnel":
{"name":"remote32",
"started_at":"2023-10-14T03:49:25.040529254Z",
"tunnel":"Connected",
"last_connected_at":"2023-10-14T15:11:02.730231871Z",
"last_disconnected_at":null,
"last_fail_reason":null},
"service_installed":true}

You can also check the status with systemctl by specifying the --user argument:

systemctl --user status code-tunnel.service

Note that this status command's output is identical to the previous tunnel log command.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

  • Secure and seamless server access
    The powerful Cloudflare Tunnel provides secure and seamless access to servers and applications, making it a convenient alternative to VPN for any modern IT infrastructure.
  • Remote maintenance and automation with RPort
    Firewalls and network address translation often stand in the way of access to remote systems, but the free RPort software works around these obstacles and supports remote maintenance through a tunnel locally, in the cloud, and from your home office.
  • Secure your data channel with stunnel
    Stunnel provides a TLS wrapper with extensive configuration options to secure your data over insecure wireless networks.
  • Self-hosted remote support
    RustDesk supports self-hosted cross-platform remote support and maintenance. The client and optional basic server are open source and available free of charge.
  • SSH on Windows

    For Linux admins, SSH is one the most important tools of remote administration. SSH also works in Windows, with tools such as PuTTY or WinSSH, MobaXterm, WinSCP, or Swish.

comments powered by Disqus