Try   HackMD

How to force Steam access the internet via a proxy service in GNU/Linux?

This tutorial explains the workaround to force Steam to use the phone's proxy service to access the internet.

https://hackmd.io/@brlin/steam-over-proxy-howto

The problem

I'm avoiding my ISP throttling my internet access too much according my network usage of network tethering by using the TetherFi application to run an HTTP/HTTPS proxy service on the phone and configure the computer to access the internet over it. However, in this case Steam online functionalities such as cloud save syncing and game download/update will not work hence the need to find a workaround.

Note:

The major part of Steam(except of minor features such as crash dump uploading) doesn't honour the http_proxy and https_proxy environment variables.

The solution

By running an SSH service capable of application-level port forwarding on the phone I can setup a SOCKS proxy service using the SSH client at the localhost and force all outgoing TCP network packets to go through the SOCKS proxy service via the use of the Redsocks service.

Steam ToS concerns

According to the 3.A section of the STEAM® Subscriber Agreement:

You agree that you will not use IP proxying or other methods to disguise the place of your residence, whether to circumvent geographical restrictions on game content, to order or purchase at pricing not applicable to your geography, or for any other purpose. If you do this, Valve may terminate your access to your Account.

This may raise concerns of whether using the proxy may violate the agreement, fortunately, for this use case the proxy service is at the same geographic location as the proxy client, thus does not fall under the the terms of this section.

Prerequisites

This section documets the prerequisites of doing this tutorial:

Phone

  • OS: Android OS that is compatible with the TetherFi and the SimpleSSHD applicationos.
  • Should install the F-Droid application store which will be used for installing SimpleSSHD.

Computer OS

Any regular GNU+Linux distribution should do.

The process

This section documents the process of setting the solution up:

Acquire the auxillary utilities

A Git repository has been prepared for the following operations, please clone the repository or download & extract the code to your local host.

https://gitlab.com/brlin/ProxifierLinux

Start the TetherFi service

Launch the TetherFi application and start the service.

Connect to the TetherFi hotspot

Configure the network of your computer to connect to the TetherFi hotspot.

Setup the SimpleSSHD SSH service on the phone

Follow the following operation instructions to setup the SimpleSSHD SSH service on the phone:

  1. Install the SimpleSSHD application via the F-droid application store application.

  2. Launch the application.

  3. Start the service.

  4. Log into the remote shell using an SSH client and the password specified in the SimpleSSHD application's service log view.

  5. Create the authorized_keys file with the content of your SSH public key in the remote user's home directory.

    Note:

    • SimpleSSHD does not use the standard ~/.ssh/authorized_keys path for the authorized_keys file, you should create it under the remote user's home directory.
    • You can use the vi editor to create and edit the file, or use SCP/SFTP to upload it from local.
    • The authorized_keys file should contain the complete SSH public key, not its fingerprint.
  6. Log out and re-login to verify whether the key authentication works.

Setup SSH application-level packet forwarding

Now we can configure our SSH client to connect to the SimpleSSHD server, and set up a SOCKS server at the localhost to serve TCP/UDP network requests that would route through the SSH connection and sent out as if it is sent by the mobile device itself.

Option 1: Write a OpenSSH client configuration

Merge the following OpenSSH client configuration into the ~/.ssh/config file:

# Config for setting up a TetherFi forward proxy
Host tetherfi
  User user
  HostName 192.168.49.1
  Port 2222
  DynamicForward 127.0.0.1:1080
  SessionType none
  ForkAfterAuthentication yes
  ExitOnForwardFailure yes
  LogLevel ERROR

You can now start the SSH SOCKS service by running the following command in a terminal:

ssh tetherfi

Note:

You can disable the SOCKS service by running the following command in a terminal:

ssh -O exit tetherfi

Option 2: Use the setup script in the auxilary tools

Run the following command in a terminal to start the SSHD service:

/path/to/ProxifierLinux/enable-ssh-socks-service.sh

Refer the shell script file's header to find environment variables that needs to be customized according to your configuration.

If the command runs successful there should be a SOCKS service listening locally at the 1080 port that will route all connections through the mobile device.

Note:

You can disable the SOCKS service by running the following command in a terminal:

/path/to/ProxifierLinux/enable-ssh-socks-service.sh --disable

Verification

You may verify whether the SOCKS service is running by running the following command in a terminal:

https_proxy=socks5h://127.0.0.1:1080 curl --head https://one.one.one.one

It should output something simlar to this one:

HTTP/2 200 
date: Fri, 17 May 2024 04:42:03 GMT
content-type: text/html; charset=utf-8
cf-ray: 8850f049b8854a48-TPE
access-control-allow-origin: *
cache-control: public, max-age=0, must-revalidate
etag: "5dd740d0e716a31c1b8437db0263fa93"
vary: Accept-Encoding
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
server: cloudflare
alt-svc: h3=":443"; ma=86400

Use the redsocks proxifier service to force all TCP connections through the SSH SOCKS proxy

Install redsocks software via your distribution's package manager or from the source code.

Refer to the /path/to/ProxifierLinux/redsocks.conf.sample for a sample configuration file for configuring redsocks.

Start the redsocks service by running the following command as root if you're using a systemd-managed redsocks installation:

systemctl start redsocks

If you build redsocks from source, run the following command in the terminal instead:

/path/to/redsocks -c /path/to/redsocks.conf

Run the following command in a terminal as root to set up the iptables firewall rules to redirect all outgoing and incoming packets to the redsocks service:

/path/to/ProxifierLinux/setup-iptables

You may reset the firewall rules by running the following command in a terminal as root:

/path/to/ProxifierLinux/setup-iptables --reset

You can test whether the proxifier works by running the following command:

curl_opts=(
    # Only print the response header
    --head
)
curl "${curl_opts[@]}" https://1.1.1.1

It should have an output similar to the following one:

HTTP/1.1 200 Connection Established

HTTP/2 302 
date: Mon, 01 Jul 2024 16:01:47 GMT
content-length: 0
location: https://one.one.one.one/
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v4?s=gNPFA3UUUoCzlK%2BuPoVhlGsfTW11Y1%2B%2FHOauSBpJcku6%2B5t0au5YbBvTPS4eof41JjqJYUWsVIE44HQw%2F7MkqaW%2FijIacPEYXj2AIeNACauQLelWfqR%2Bcfg%3D"}],"group":"cf-nel","max_age":604800}
nel: {"report_to":"cf-nel","max_age":604800}
server: cloudflare
cf-ray: 89c79ddf5a2b4a57-TPE

Use the goproxy service to force the DNS request via the SOCKS proxy

At the moment, the name resolution will not work as TetherFi doesn't support DNS service:

$ curl --location https://1.1.1.1
curl: (6) Could not resolve host: one.one.one.one

we will solve this problem by using the goproxy software to emulate a DNS service at the localhost to redirect all DNS requests to the SSH SOCKS service.

Warning: The developer of the goproxy software may be under the influence of the Chinese autocracy government. Use the software with caution.

  1. Download and extract the pre-built archive or build the software from source.

  2. Launch a terminal application

  3. Run the following command as root to start the DNS emulation service:

    ​​​​proxy_dns_opts=(
    ​​​​    # Parent service address
    ​​​​    --parent=127.0.0.1:1080
    
    ​​​​    # Parent protocol type
    ​​​​    --parent-type=tcp
    
    ​​​​    --parent-service-type=socks
    
    ​​​​    # Local port to listen
    ​​​​    --local=127.0.0.1:53
    
    ​​​​    # Write log for troubleshooting
    ​​​​    #--log=proxy.log
    
    ​​​​    # Run service in background
    ​​​​    --daemon
    ​​​​)
    ​​​​/path/to/goproxy/proxy dns "${proxy_dns_opts[@]}"
    
  4. Configure your network to use the 127.0.0.1 custom DNS server instead of the supplied defunct 192.168.49.1 one. This time the curl --location https://1.1.1.1 command should work.

Troubleshooting

The following section documents ways to troubleshoot setup problems.

goproxy service fails to resolve host

Like this log entry:

2024/05/17 08:16:07.044 [LookupFromProxy, id: 36406, domain: iot.cht.com.tw/dns: 1.1.1.1:53] WARN dns query fail, non answers, 

Try restarting the systemd-resolved service, the service may mark the DNS server as down thus blocking all resolve requests.

systemd-resolved fails to resolve host

Try running the following two commands in the text terminal:

resolvectl reset-server-features
resolvectl flush-caches

References

The following third-party materials are referenced during the development of this solution: