How to use VS Code Remote SSH with WP Engine
Tags: vscode, ssh, wordpress, tutorial
Published: 2023-03-11 14:09:06

## Summary

**UPDATE** : I kind of stopped using this way after other people started touching the same environment. Another reason I stopped doing this is that it is troublesome to compile Sass files and then upload it. It is better to [do the dev work in your local environment with Git and then push it to WP-Engine's remote repository](https://wpengine.com/support/git/) ([Another page explaining about that](https://wpengine.com/builders/git-version-control-in-local/)).

So I wanted to use [VS Code Remote SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) to amend the files in [WP Engine](https://wpengine.com/), and I could not have done it even though the file `/usr/local/etc/ssh/usermode_sshd_config` looks they let me do that.

```
# Tried this by using 2 SSH connections and that did not work
ControlMaster yes
LocalForward 127.0.0.1:12222 127.0.0.1:2222
======
channel 2: open failed: administratively prohibited: port forwarding is disabled for 127.0.0.1:2222
```

And therefore, I decided to attempt to establish SSH Reverse Port Forwarding from WP Engine to an Extra Server, and then use [VS Code Remote SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh) to connect to WP Engine through the Extra Server because I discovered that WP Engine has `ssh` command :

```
[VSC Remote SSH]--->[Your PC]--->[Extra Server]--->[WP Engine]
```

Although that method worked, the preparation is troublesome. It may be better to use another VS Code Extension such as [SFTP](https://marketplace.visualstudio.com/items?itemName=satiromarra.code-sftp) or do the coding work at another environment. ~~Additionally, note that [the connection gets cut off after 10 minutes](https://wpengine.com/support/ssh-gateway/) :~~

> ~~WP Engine uses a sandboxed SSH “sidecar” that sits alongside your server with a timeout of 10 minutes.~~

**UPDATE** : I included `ServerAliveInterval` to `~/.ssh/config` and that solved above issue.

**UPDATE** : I kept using VSC Remote SSH for awhile to do the dev work with WP Engine because I prefer applying the same way to do the dev work, and I have not got an issue so far.

## Requirements

- [You can access WP Engine via SSH on the terminal](https://wpengine.com/support/ssh-gateway/).

- Another host, Extra Server, allowing you to SSH from WP Engine.

- Although, this is fundamentally a copy-and-paste solution, you must be able to assemble this information to fit your own.

## Steps

### Add a new user at Extra Server to SSH from WP Engine

This user is used only for this purpose. If you want to reuse the existing user, you can skip this step.

```
sudo su -
```

```
# "rbash" restricts the user to perform things
adduser --shell /bin/rbash --ingroup nogroup wpe_pf

# Restrict the user more
cd /home/wpe_pf
chown root:root .bash_logout .bash_profile .bashrc .profile
# "readonly PATH=xxx" is like "const PATH = xxx;"
# restricting what the user can see
# ($HOME/bin does not exist)
echo "readonly PATH=$HOME/bin" > .bash_profile
echo "export PATH" >> .bash_profile
```

The following setting may make above redundant, but just in case:

```
/etc/ssh/sshd_config
or
/etc/ssh/sshd_config.d/101-wpe_pf.conf
======
# Avoid the user for WP Engine to do much but SSH
Match User wpe_pf
  PermitTTY no
  X11Forwarding no
  PermitTunnel no
  GatewayPorts no
  # This does not work with "/bin/rbash"
  # ForceCommand /usr/sbin/nologin
```

```
service ssh reload
```

```
exit
```

### Create a new SSH Key

This key is used to connect to the Extra Server from WP Engine. If you want to reuse the existing key, you can skip this step.

```
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519.wp-engine-example -C "example@example.com"
```

Include what `~/.ssh/id_ed25519.wp-engine-example.pub` has to the file `~/.ssh/authorized_keys` on Extra Server.

### Place 2 files at WP Engine

To begin, SSH to WP Engine via the terminal.

Copy the private SSH key `~/.ssh/id_ed25519.wp-engine-example` to `/sites/example/_wpeprivate/id_ed25519.wp-engine-example`, and then run :

```
chmod 400 /sites/example/_wpeprivate/id_ed25519.wp-engine-example
```

and then create a new script (where `ssh-ed25519 AAAAAAAAAAAA...` represents your public SSH key) :

```
/sites/example/_wpeprivate/ssh-reverse-pf.sh
======
#
# The copy of this script may be better to be kept in your PC
# in case you copied a WP Engine Environment from the one not having this script
#
# Location of the SSH file in WP Engine
SSH_AUTH_FILE=~/.ssh/authorized_keys
# SSH Private Key for Extra Server
SSH_IDENT_FILE=/sites/example/_wpeprivate/id_ed25519.wp-engine-example
# SSH Public Key for WP Engine
# Using the same key for Extra Server would be easier to manage
# because this script may get wiped out when copying the environment
# and the source environment does not have this script
SSH_PUB_KEY='ssh-ed25519 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA example@example.com'
SSH_SERVER=my_user@my-server.com
SSH_PORT=12222

chmod 600 $SSH_AUTH_FILE && \
echo "$SSH_PUB_KEY" >> $SSH_AUTH_FILE && \
echo "Establishing Reverse Porting Forwarding" && \
ssh -C -o StrictHostKeyChecking=accept-new -i $SSH_IDENT_FILE -R 127.0.0.1:$SSH_PORT:127.0.0.1:2222 $SSH_SERVER
```

and then change the permission :

```
chmod 700 /sites/example/_wpeprivate/ssh-reverse-pf.sh
```

and log out from WP Engine.

### Amend ~/.ssh/config

```
Host *
  PermitLocalCommand yes

Host wp-engine
  HostName example.ssh.wpengine.net
  User example
  IdentityFile ~/.ssh/id_ed25519.wp-engine-example
  Compression yes
  ServerAliveInterval 60
  RequestTTY yes
  LocalCommand ssh-keygen -R "[localhost]:12222"
  RemoteCommand /sites/example/_wpeprivate/ssh-reverse-pf.sh
Host extra-server
  HostName extra-server.com
  User my_user
  IdentityFile ~/.ssh/id_ed25519.wp-engine-example
  Compression yes
  LocalForward 127.0.0.1:12222 127.0.0.1:12222
Host wp-engine-pf
  HostName localhost
  User wpe-user
  Port 12222
  IdentityFile ~/.ssh/id_ed25519.wp-engine-example
  StrictHostKeyChecking accept-new
```

Note : If you need to handle multiple WP Engines, you may need to create multiple settings. For each additional setting, use a different port number instead of "12222" (which is used as an example in this article).

### Log in WP Engine

```
ssh wp-engine
# OR
# Keep running with the infinite loop
# in case "ServerAliveInterval" does not work
# because it gets cut off every 10 minutes...?
while true; do ssh wp-engine; sleep 2; done
```

Above "ssh" command establishes SSH connection to WP Engine and then runs the script `ssh-reverse-pf.sh` to establish another SSH connection to Extra Server.

That another SSH connection is initiated by WP Engine and it creates the port forwarding as to forward the data from Extra Server to WP Engine (SSH Server in WP Engine). Thus, it is called Reverse Port Forwarding as WP Engine initiates the SSH connection but the port forwarding is in other way round :

```
# "ssh" command
[Your PC]---SSH--->[WP Engine]
# The script "ssh-reverse-pf.sh"
[WP Engine]---SSH--->[Extra Server]
[Extra Server]---Port Forward--->[WP Engine]
```

### Log in Extra Server

```
ssh my-server
```

This SSH is to forward the data from VS Code Remote SSH to Extra Server so that the extension can SSH to WP Engine :

```
[Your PC]------>[Extra Server]------>[WP Engine]
```

### Connect to WP Engine with VS Code Remote SSH

- Have the setting `Remote.SSH: Enable Remote Command` ticked.

- SSH to Your PC (with `wp-engine-pf` in this example).

```
[VSC Remote SSH]--->[Your PC]--->[Extra Server]--->[WP Engine]
```

## ToDo

Create my first VS Code Extension who does the things above once the settings are created...?