In the last post, we set up the x11vnc server on our home computer. We managed to access the desktop remotely, but the connection is still limited in local LAN. In order to access my home computer from the Internet outside, I need a public IP for my PC which is not feasible for me. So I need to find a method to expose my PC to the Internet, and I did set up a V2Ray proxy service that can be also used for the reverse proxy (it is introduced in this post). Then, I realized that I could use the same proxy service to achieve both network proxy and remote desktop access. In this tutorial, we’ll set up the reverse proxy so we can access remote PC that doesn’t have a public IP through ssh and x11vnc.
Before we started, we need to have a big picture of what we are going to do. As shown in the figure below, we will have three main entities: Home PC, VPS, and Client (hereinafter A, B, and C). A hosts some services at local LAN, but it connects to the B through V2Ray to receive our requests from the Internet. B is hosting the V2Ray server side. It receives the requests from the client via V2Ray connection and routing them by predefined rules. Thus, it can handle both network proxy traffic and remote access traffic. C is the client who wants to safely browse the Internet or uses home services.
In short, we will keep the same client and VPS that provides network proxy service part. But adds routing and portal to B, and adds a bridge to A. Please note that A must have a bridge and B must have a portal in order to expose A to the public.
In the scenario above, C also needs a V2Ray client app to connect B which means the home services are only reachable via V2Ray. However, if you want your home services accessible from any kind of normal Internet traffic that doesn’t require a V2Ray client, you can add another “dokodemo” inbounds interface that can accept any traffic comes in on B. Then, connect the “dokodemo” inbounds to the portal.
Now, we are ready for real practical work. The tutorial is consist of three parts (refers to the A, B, and C):
Bridge Configuration (A)
Here I suppose that our service provider PC is run on Ubuntu (Linux) and has V2Ray already installed (this post introduced how to install V2Ray). So, we can jump to the configuration part directly. Open the configure file /etc/v2ray/config.json
on the home PC:
{
"reverse": {
"bridges": [
{
"tag": "bridge",
"domain": "my.homeservice.com"
}
]
},
// start of outbounds
"outbounds": [
{
"tag": "bridgeout1",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:80"
}
},
{
"tag": "bridgeout2",
"protocol": "freedom",
"settings": {
"redirect": "127.0.0.1:22"
}
},
{
"tag": "interconn", // connect to portal
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "vps.domain.com",
"port": 443,
"users": [
{
"id": "your-PC-uuid",
"alterId": 64
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"allowInsecure": false
},
"wsSettings": {
"path": "/path"
}
}
}
],
// end of outbounds
"routing": {
"rules": [
{
"type": "field",
"inboundTag": [
"bridge"
],
"domain": [
"full:my.homeservice.com"
],
"outboundTag": "interconn"
},
{
"type": "field",
"inboundTag": ["bridge"],
"port": "7001",
"outboundTag": "bridgeout1"
},
{
"type": "field",
"inboundTag": ["bridge"],
"port": "7002",
"outboundTag": "bridgeout2"
}
]
}
}
In the configuration above, we defined three outbounds interface on home PC: “bridgeout1”, “bridgeout2”, and “interconn” and one bridge with arbitrary domain “my.homeservice.com”. Then we connect those interfaces by the routing rules. For example, if we received traffic from the “bridge” and the port is “7001”, we redirect the traffic to “bridgeout1” which is “localhost” with port “80”. “interconn” is used to initiate a connection to B’s portal automatically. Don’t forget to change the “interconn” configuration to your own V2Ray setup.
Portal Configuration (B)
For the B part, I also use a Debian (Linux) system with V2Ray installed. The same configuration file /etc/v2ray/config.json
on the B should be like this:
{
// reverse proxy portal
"reverse": {
"portals": [
{
"tag": "portal",
"domain": "my.homeservice.com" // the same as bridge
}
]
},
// v2ray + ws + tls config
"inbounds": [
// receive client's connection
{
"tag": "clientin",
"port": 10000,
"listen":"127.0.0.1", // Only listen to local host 127.0.0.1
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "your-client-uuid",
"alterId": 64
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/v2ray"
}
}
},
// receive bridge's connection
{
"tag": "interconn",
"port": 10001,
"listen": "127.0.0.1",
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "your-PC-uuid",
"alterId": 64
}
]
},
"streamSettings": {
"network": "ws",
"wsSettings": {
"path": "/path"
}
}
}
], // end of the inbounds
// outbounds for network proxy
"outbounds": [{
"tag": "crossfire",
"protocol": "freedom",
"settings": {}
}],
// routing rules
"routing": {
"rules": [
{
"type": "field",
"inboundTag": ["interconn"],
"outboundTag": "portal"
},
{
"type": "field",
"inboundTag": ["clientin"],
"ip": "111.111.111.111",
"port": "7000-8000",
"outboundTag": "portal" // for a specific ip and port range to access remote services
},
{
"type": "field",
"inboundTag": ["clientin"],
"outboundTag": "crossfire" // remaining traffic goes here
}
]
}
}
In this configuration, we created two inbound interfaces for A and C respectively, one outbound interface for network proxy, and one portal transferring services requests. The “portal” should use the same customized domain to talk with the “bridge”. Two inbounds should use the credentials that work with your Apache web server, A and C. The “crossfire” outbound is used for browsing the Internet.
Our demand is to use network proxy and the remote services with one client’s inbound interface. Hence, we have to route the traffic to distinguish Internet browsing and services accessing. I added two rules to achieve this. In the first one, we route all “client”‘s traffic with IP “111.111.111.111” and port range from “7000” to “8000” to the “portal”. Next, we route the remaining traffic to the local “crossfire” for proxy.
From the “client” side, you can type “111.111.111.111:7001” in a browser to access the deployed service on your remote PC for example. Port “7001” will be forwarded to port “80” on your remote PC, thus the connection is established. And the traffic other than “111.111.111.111” will be processed on the server side.
Client Configuration (C)
Basically, C can use any application that supports the V2Ray protocol. For instance, I provide a template configuration:
{
"inbounds": [
{
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks"
}
],
"outbounds": [
{
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "vps.domain.com",
"port": 443,
"users": [
{
"id": "your-client-uuid",
"alterId": 64
}
]
}
]
},
"streamSettings": {
"network": "ws",
"security": "tls",
"tlsSettings": {
"allowInsecure": false
},
"wsSettings": {
"path": "/v2ray"
}
}
}
]
}
The client only receives the network requests from a “socks” inbound interface and transmits them to the server via “vmess”.
Conclusion
In the introduced scenario, our remote PC will not be exposed directly to the Internet, we have to use a client that supports V2Ray to connect. If we want to access remote services like vnc or ssh, just need to use the IP address “111.111.111.111”. Every time when there’s a new service deployed on your remote PC, you need to change the corresponding configure file on that PC to forward the ports. And also remember to use static IP for your remote PC 🙂