# 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> [TOC] ## 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](https://github.com/pyamsoft/tetherfi) 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. :::info **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](https://github.com/darkk/redsocks). ## Steam ToS concerns According to [the 3.A section of the STEAM® Subscriber Agreement](https://store.steampowered.com/subscriber_agreement/english/#3): > 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](https://f-droid.org/) 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](https://f-droid.org/zh_Hant/packages/org.galexander.sshd/) via the [F-droid](https://f-droid.org/) application store application. 1. Launch the application. 1. Start the service. 1. Log into the remote shell using an SSH client and the password specified in the SimpleSSHD application's service log view. 1. Create the `authorized_keys` file with the content of your SSH public key in the remote user's home directory. :::info **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. ::: 1. 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: ```ssh # 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 ``` :::info **Note:** You can disable the SOCKS service by running the following command in a terminal: ```bash! 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: ```bash /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. :::info **Note:** You can disable the SOCKS service by running the following command in a terminal: ```bash! /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: ```bash https_proxy=socks5h://127.0.0.1:1080 curl --head https://one.one.one.one ``` It should output something simlar to this one: ```http-response 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: ```bash systemctl start redsocks ``` If you build redsocks from source, run the following command in the terminal instead: ```bash /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: ```bash /path/to/ProxifierLinux/setup-iptables ``` :::info You may reset the firewall rules by running the following command in a terminal _as root_: ```bash /path/to/ProxifierLinux/setup-iptables --reset ``` ::: You can test whether the proxifier works by running the following command: ```bash 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: ```html 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](https://github.com/snail007/goproxy/releases) to emulate a DNS service at the localhost to redirect all DNS requests to the SSH SOCKS service. :::warning **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. 1. Launch a terminal application 1. Run the following command _as root_ to start the DNS emulation service: ```bash 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[@]}" ``` 1. 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: * [How to use Steam on a proxy network — Step by step guide | by Lime Proxies | Medium](https://medium.com/@limeproxiesserver/how-to-use-steam-on-a-proxy-network-step-by-step-guide-6cfdd74c5b6) Similar tutorial for Windows, including Steam ToS concern discussion. * The ssh(1) manual page. * [darkk/redsocks: transparent TCP-to-proxy redirector](https://github.com/darkk/redsocks) The proxifier software that this project is using. * [networking - How to force all Linux apps to use SOCKS proxy - Super User](https://superuser.com/a/1402071) * [How to install and configure Redsocks on Centos Linux | Alexander Molochko](https://crosp.net/blog/administration/install-configure-redsocks-proxy-centos-linux/) * [!] -d, --destination address[/mask][,...] - PARAMETERS - OPTIONS - The iptables(8) manual page Explains the `-d` command-line option of the `iptables` command. * [networking - Where are addresses from the network 0.0.0.0/8 used in practice? - Super User](https://superuser.com/questions/388056/where-are-addresses-from-the-network-0-0-0-0-8-used-in-practice) Explains what the addresses of the 0.0.0.0/8 subnet are used for. * -C, --check _chain_ _rule-specification_ - COMMANDS - OPTIONS - The iptables(8) manual page Explains how to check whether the specified rule exist in the firewall.