Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOAX relay for remote measurement #286

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion transport/socks5/packet_listener.go
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert the transport changes. See below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna please refer to my above comment.

Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ func (c *Client) ListenPacket(ctx context.Context) (net.PacketConn, error) {
// https://datatracker.ietf.org/doc/html/rfc1928#section-6
// Whoile binding address to specific client address has its advantages, it also creates some
// challenges such as NAT traveral if client is behind NAT.
sc, bindAddr, err := c.connectAndRequest(ctx, CmdUDPAssociate, "0.0.0.0:0")
sc, bindAddr, err := c.ConnectAndRequest(ctx, CmdUDPAssociate, "0.0.0.0:0")
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions transport/socks5/stream_dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func (c *Client) request(conn io.ReadWriter, cmd byte, dstAddr string) (*address
}

// connectAndRequest manages the connection lifecycle and delegates the SOCKS5 communication to the request function.
func (c *Client) connectAndRequest(ctx context.Context, cmd byte, dstAddr string) (transport.StreamConn, *address, error) {
func (c *Client) ConnectAndRequest(ctx context.Context, cmd byte, dstAddr string) (transport.StreamConn, *address, error) {
proxyConn, err := c.se.ConnectStream(ctx)
if err != nil {
return nil, nil, fmt.Errorf("could not connect to SOCKS5 proxy: %w", err)
Expand All @@ -230,7 +230,7 @@ func (c *Client) connectAndRequest(ctx context.Context, cmd byte, dstAddr string
// The returned [error] will be of type [ReplyCode] if the server sends a SOCKS error reply code, which
// you can check against the error constants in this package using [errors.Is].
func (c *Client) DialStream(ctx context.Context, dstAddr string) (transport.StreamConn, error) {
proxyConn, _, err := c.connectAndRequest(ctx, CmdConnect, dstAddr)
proxyConn, _, err := c.ConnectAndRequest(ctx, CmdConnect, dstAddr)
if err != nil {
return nil, err
}
Expand Down
131 changes: 131 additions & 0 deletions x/examples/soax-relay/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# SOCKS5 Proxy Relay for SOAX

This program creates a SOCKS5 proxy relay that allows users to share access to SOAX without sharing their own credentials. It's designed for connectivity testing purposes.

## Design

The proxy relay works as follows:

1. It listens for incoming SOCKS5 connections on a specified local address and port.
2. It authenticates incoming connections using a custom authentication mechanism.
3. For authenticated connections, it relays requests to the SOAX proxy server.
4. It supports both TCP and UDP traffic.

#### Key components:

- **CustomAuthenticator**: Handles authentication based on username prefix and extracts the suffix which includes connection parameters such as country, city, ISP, etc.
- **StaticCredentialStore**: Stores and validates user credentials.
- **UDP Associate Handler**: Manages UDP connections by relaying the SOAX bind address back to the client.

## Usage

### Configuration

The program uses a YAML configuration file (`config.yaml`) for settings. Example configuration:

```yaml
server:
address: "127.0.0.1"
port: "1080"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"server" is ambiguous. Perhaps "listen_address"? And we can simplify with a single string

Suggested change
server:
address: "127.0.0.1"
port: "1080"
listen_address: 127.0.0.1:1080


upstream:
prefix: "package-xxxxx-"
password: "YourSOAXPassword"
address: "proxy.soax.com:5000"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's simplify this and be explicit about the soax info, using the names they use:

Suggested change
upstream:
prefix: "package-xxxxx-"
password: "YourSOAXPassword"
address: "proxy.soax.com:5000"
soax:
package_id: "XXXXXX"
package_key: "YourSOAXPassword"

I'd omit the server address too, it's easier.


credentials:
foo: "bar"
jane: "password123"

udp_timeout: 1m
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
udp_timeout: 1m
# Optional
udp_timeout: 1m

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

timeout param is removed

```

### Authentication
Users connect to the relay using the following format:

<b>Username:</b>

username-country-{cc_code}-sessionid-{session_id}-sessionlength-{time_in_sec}

where any part that goes after username-country-{cc_code} is optional. For more information on the format refer to [this document](https://helpcenter.soax.com/en/articles/6723733-sticky-sessions) on soax support page.

<b>Password:</b> (as defined in the credentials section of the config file)

<b>Example Username:</b>

outline-country-ru-sessionid-12-sessionlength-600

The relay will use the SOAX package ID and password to connect to the SOAX server, appending the country, sessionid, and sessionlength from the user's input.

### Setup and Running
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is too complicated. You can just use go run directly and pass the full package name. See the docs for the other tools.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simplified the readme accordingly


Ensure you have Go installed on your system.
Clone the repository:

```bash
git clone <repository-url>
cd <repository-directory>
```

Install dependencies:
```bash
go mod tidy
```

Create a `config.yaml` file in the project directory with your SOAX credentials and desired settings.

Build the program:

```bash
go build -o socks5relay
```

Run the program:

```bash
./socks5relay
```


The relay will start and listen for incoming connections on the specified address and port.

SOAX Sticky Sessions:

This relay supports SOAX sticky sessions. Users can specify:

1. country

Two-letter country code (e.g., "us" for United States)

2. sessionid

A random string to maintain the same IP across requests

3. sessionlength

Duration of the session in seconds (10 to 3600)

4. city

City name. Example: new+york

5. region

Region name. Example: new+york

6. isp

ISP name. Please use this parameter together with the country information.

For more information on the format for values please check out [this document](https://helpcenter.soax.com/en/articles/6723733-sticky-sessions) on soax support page.

The relay will forward these parameters to SOAX, allowing users to benefit from sticky sessions without direct access to SOAX credentials.

### Security Considerations
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, SOCKS5 is plaintext....


This relay is intended for testing purposes only.
Ensure the relay is run in a secure environment, as it handles sensitive SOAX credentials.
Regularly update the credentials in the config file to maintain security.



14 changes: 14 additions & 0 deletions x/examples/soax-relay/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
server:
address: 127.0.0.1
port: 1080

soax:
package: package-000000-
password: XXXXXXXX
address: proxy.soax.com:5000

credentials:
foo: bar
exampleuser: examplepass

udp_timeout: 1m
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UDP timeout is not needed. Remove.

The TCP connection for the UDP Association is how we determine when to close it.

Loading
Loading