computerscot.github.io

SSH over Xray

July 18, 2023

The scenario in this post is that you want to SSH into a remote server, but your direct connection to the remote server is blocked by a firewall. Therefore you decide to pass SSH over an Xray connection. There are two server IP addresses in the examples:

XRAY.SERVER.IP.ADDRESS
SSH.SERVER.IP.ADDRESS

Xray server

Install Xray-core on your Xray server using the latest beta, and configure it to run as root:

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --beta -u root

Example of a completed server configuration file /usr/local/etc/xray/config.json:

{
    "log": {
        "loglevel": "warning"
    },
    "routing": {
        "domainStrategy": "IPIfNonMatch",
        "rules": [
            {
                "type": "field",
                "ip": [
                    "geoip:cn",
                    "geoip:private"
                ],
                "outboundTag": "block"
            }
        ]
    },
    "inbounds": [
        {
            "listen": "0.0.0.0",
            "port": 443,
            "protocol": "vless",
            "settings": {
                "clients": [
                    {
                        "id": "3b5390c5-52a2-472d-8dc2-103ef508be6c",
                        "flow": ""
                    }
                ],
                "decryption": "none"
            },
            "streamSettings": {
                "network": "h2",
                "security": "reality",
                "realitySettings": {
                    "show": false,
                    "dest": "www.lovelive-anime.jp:443",
                    "xver": 0,
                    "serverNames": [ 
                        "www.lovelive-anime.jp"
                    ],
                    "privateKey": "QNraK6EdxPNOzfbL2G1BTl_OeMSxm49H5vps2qzQ3E0",
                    "shortIds": [ 
                        "77c2358dc476ae9e"
                    ]
                }
            }
        }
    ],
    "outbounds": [
        {
            "protocol": "freedom",
            "tag": "direct"
        },
        {
            "protocol": "blackhole",
            "tag": "block"
        }
    ]
}

Restart xray systemd service with your final configuration file:

systemctl restart xray
systemctl status xray

Xray client

Download the Xray CLI client from https://github.com/XTLS/Xray-core/releases.

Create a file config.json in the same folder as the xray executable. Following is a template you can use for your client configuration config.json. Note that the Xray client will accept SOCKS proxy input on port 10808.

{
    "log": {
        "loglevel": "warning"
    },
    "routing": {
        "domainStrategy": "IPIfNonMatch",
        "rules": [
            {
                "type": "field",
                "domain": [
                    "geosite:category-ads-all"
                ],
                "outboundTag": "block"
            },
            {
                "type": "field",
                "domain": [
                    "geosite:geolocation-!cn"
                ],
                "outboundTag": "proxy"
            },
            {
                "type": "field",
                "domain": [
                    "geosite:cn",
                    "geosite:private"
                ],
                "outboundTag": "direct"
            },
            {
                "type": "field",
                "ip": [
                    "geoip:cn",
                    "geoip:private"
                ],
                "outboundTag": "direct"
            }
        ]
    },
    "inbounds": [
        {
            "listen": "127.0.0.1",
            "port": 10808,
            "protocol": "socks"
        },
        {
            "listen": "127.0.0.1",
            "port": 10809,
            "protocol": "http"
        }
    ],
    "outbounds": [
        {
            "protocol": "vless",
            "settings": {
                "vnext": [
                    {
                        "address": "XRAY.SERVER.IP.ADDRESS",
                        "port": 443,
                        "users": [
                            {
                                "id": "3b5390c5-52a2-472d-8dc2-103ef508be6c",
                                "encryption": "none",
                                "flow": ""
                            }
                        ]
                    }
                ]
            },
            "streamSettings": {
                "network": "h2",
                "security": "reality",
                "realitySettings": {
                    "show": false,
                    "fingerprint": "chrome",
                    "serverName": "www.lovelive-anime.jp",
                    "publicKey": "eZfl07Tg9UII29GaS23QXqB15aqrJ4Khm0vKJIcaMCo",
                    "shortId": "77c2358dc476ae9e", 
                    "spiderX": ""
                }
            },
            "tag": "proxy"
        },
        {
            "protocol": "freedom",
            "tag": "direct"
        }
    ]
}

At a minimum, replace XRAY.SERVER.IP.ADDRESS with the actual Xray server IP address.

Save the file with your changes in it.

Set the CLI client running with the above config.json:

./xray -c config.json

Leave the terminal window open with the xray program running in it.

SSH server

The only special preparation you need on the SSH server is to open the firewall for SSH input on port tcp/22 from source IP address XRAY.SERVER.IP.ADDRESS.

SSH client

Your workstation will be the SSH client, communicating with the SSH server, but doing so over the Xray connection between your workstation and your Xray server.

Open a second terminal window, so that the Xray client can continue to run in the first terminal window.

Edit .ssh/config. Insert the following lines:

Host myssh
    Hostname SSH.SERVER.IP.ADDRESS
    User ubuntu
    ProxyCommand nc -X 5 -x 127.0.0.1:10808 %h %p
    ServerAliveInterval 10

Replace the hostname and user as necessary.

Save the file with your changes in it.

Then to connect use:

ssh myssh