# 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.