Skip to content

Commit

Permalink
DRIVERS-2789 Convert Socks5 Support Spec to Markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
blink1073 committed Sep 4, 2024
1 parent d127d92 commit f05743f
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 222 deletions.
1 change: 1 addition & 0 deletions source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
- [Retryable Writes](retryable-writes/retryable-writes.md)
- [Run Command](run-command/run-command.md)
- [SDAM Logging and Monitoring Specification](server-discovery-and-monitoring/server-discovery-and-monitoring-logging-and-monitoring.md)
- [SOCKS5 Support](socks5-support/socks5.md)
- [Server Discovery And Monitoring](server-discovery-and-monitoring/server-discovery-and-monitoring.md)
- [Server Discovery And Monitoring -- Summary](server-discovery-and-monitoring/server-discovery-and-monitoring-summary.md)
- [Server Discovery And Monitoring -- Test Plan](server-discovery-and-monitoring/server-discovery-and-monitoring-tests.md)
Expand Down
232 changes: 88 additions & 144 deletions source/socks5-support/socks5.md
Original file line number Diff line number Diff line change
@@ -1,188 +1,132 @@
==============
SOCKS5 Support
==============
# SOCKS5 Support

:Status: Accepted
:Minimum Server Version: N/A
- Status: Accepted
- Minimum Server Version: N/A

.. contents::
______________________________________________________________________

--------
## Abstract

Abstract
========
SOCKS5 is a standardized protocol for connecting to network services through a separate proxy server. It can be used for
connecting to hosts that would otherwise be unreachable from the local network by connecting to a proxy server, which
receives the intended target host's address from the client and then connects to that address.

SOCKS5 is a standardized protocol for connecting to network services through
a separate proxy server. It can be used for connecting to hosts that would
otherwise be unreachable from the local network by connecting to a proxy
server, which receives the intended target host’s address from the client
and then connects to that address.
This specification defines driver behaviour when connecting to MongoDB services through a SOCKS5 proxy.

This specification defines driver behaviour when connecting to MongoDB services
through a SOCKS5 proxy.
## META

META
====
The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in [RFC 2119](https://www.ietf.org/rfc/rfc2119.txt).

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
interpreted as described in `RFC 2119 <https://www.ietf.org/rfc/rfc2119.txt>`__.
## Specification

Specification
=============
### Terms

#### SOCKS5

Terms
-----
The SOCKS protocol, version 5, as defined in [RFC1928](https://datatracker.ietf.org/doc/html/rfc1928), restricted to
either no authentication or username/password authentication as defined in
[RFC1929](https://datatracker.ietf.org/doc/html/rfc1929).

SOCKS5
^^^^^^
### MongoClient Configuration

The SOCKS protocol, version 5, as defined in `RFC1928 <https://datatracker.ietf.org/doc/html/rfc1928>`__,
restricted to either no authentication or username/password authentication
as defined in `RFC1929 <https://datatracker.ietf.org/doc/html/rfc1929>`__.
#### proxyHost

To specify to the driver to connect using a SOCKS5 proxy, a connection string option of `proxyHost=host` MUST be added
to the connection string or passed through an equivalent `MongoClient` option. This option specifies a domain name or
IPv4 or IPv6 address on which a SOCKS5 proxy is listening. This option MUST only be configurable at the level of a
`MongoClient`.

MongoClient Configuration
-------------------------
#### proxyPort

proxyHost
^^^^^^^^^
To specify to the driver to connect using a SOCKS5 proxy listening on a non-default port, a connection string option of
`proxyPort=port` MUST be added to the connection string or passed through an equivalent `MongoClient` option. This
option specifies a TCP port number. The default for this option MUST be `1080`. This option MUST only be configurable at
the level of a `MongoClient`. Drivers MUST error if this option was specified and `proxyHost` was not specified.

To specify to the driver to connect using a SOCKS5 proxy, a connection string
option of :code:`proxyHost=host` MUST be added to the connection string
or passed through an equivalent :code:`MongoClient` option.
This option specifies a domain name or IPv4 or IPv6 address on which
a SOCKS5 proxy is listening.
This option MUST only be configurable at the level of a :code:`MongoClient`.
#### proxyUsername

proxyPort
^^^^^^^^^
To specify to the driver to connect using a SOCKS5 proxy requiring username/password authentication, a connection string
option of - Code:`proxyUsername=username` MUST be added to the connection string or passed through an equivalent
`MongoClient` option. This option specifies a string of non-zero length. Drivers MUST ignore this option if it specifies
a zero-length string. Drivers MUST error if this option was specified and `proxyHost` was not specified or
`proxyPassword` was not specified.

To specify to the driver to connect using a SOCKS5 proxy listening
on a non-default port, a connection string option of :code:`proxyPort=port`
MUST be added to the connection string or passed through an
equivalent :code:`MongoClient` option.
This option specifies a TCP port number. The default for this option
MUST be :code:`1080`.
This option MUST only be configurable at the level of a :code:`MongoClient`.
Drivers MUST error if this option was specified and :code:`proxyHost`
was not specified.
#### proxyPassword

proxyUsername
^^^^^^^^^^^^^
To specify to the driver to connect using a SOCKS5 proxy requiring username/password authentication, a connection string
option of - Code:`proxyPassword=password` MUST be added to the connection string or passed through an equivalent
`MongoClient` option. This option specifies a string of non-zero length. Drivers MUST ignore this option if it specifies
a zero-length string. Drivers MUST error if this option was specified and `proxyHost` was not specified or
`proxyUsername` was not specified.

To specify to the driver to connect using a SOCKS5 proxy requiring
username/password authentication, a connection string option of
:code:`proxyUsername=username` MUST be added to the connection string
or passed through an equivalent :code:`MongoClient` option.
This option specifies a string of non-zero length. Drivers MUST ignore
this option if it specifies a zero-length string. Drivers MUST error
if this option was specified and :code:`proxyHost` was not specified
or :code:`proxyPassword` was not specified.
### Connection Pooling

proxyPassword
^^^^^^^^^^^^^
#### Connection Establishment

To specify to the driver to connect using a SOCKS5 proxy requiring
username/password authentication, a connection string option of
:code:`proxyPassword=password` MUST be added to the connection string
or passed through an equivalent :code:`MongoClient` option.
This option specifies a string of non-zero length. Drivers MUST ignore
this option if it specifies a zero-length string. Drivers MUST error
if this option was specified and :code:`proxyHost` was not specified
or :code:`proxyUsername` was not specified.
When establishing a new outgoing TCP connection, drivers MUST perform the following steps if `proxyHost` was specified:

Connection Pooling
------------------------
1. Connect to the SOCKS5 proxy host, using `proxyHost` and `proxyPort` as specified.

Connection Establishment
^^^^^^^^^^^^^^^^^^^^^^^^
2. Perform a SOCKS5 handshake as specified in RFC1928.

When establishing a new outgoing TCP connection, drivers MUST perform
the following steps if :code:`proxyHost`
was specified:
> If `proxyUsername` and `proxyPassword` were passed, drivers MUST indicate in the handshake that both "no
> authentication" and "username/password authentication" are supported. Otherwise, drivers MUST indicate support for
> "no authentication" only.
>
> Drivers MUST NOT attempt to perform DNS A or AAAA record resolution of the destination hostname and instead pass
> the hostname to the proxy as-is.
#. Connect to the SOCKS5 proxy host, using :code:`proxyHost` and :code:`proxyPort` as specified.
3. Continue with connection establishment as if the connection was one to the destination host.

#. Perform a SOCKS5 handshake as specified in RFC1928.
Drivers MUST use the SOCKS5 proxy for connections to MongoDB services and
[client-side field-level encryption KMS servers](../client-side-encryption/client-side-encryption.md#kms-provider).

If :code:`proxyUsername` and :code:`proxyPassword` were passed,
drivers MUST indicate in the handshake that both "no authentication"
and "username/password authentication" are supported. Otherwise,
drivers MUST indicate support for "no authentication" only.
Drivers MUST NOT use the SOCKS5 proxy for connections to - Code:`mongocryptd` processes spawned for automatic
client-side field-level encryption.

Drivers MUST NOT attempt to perform DNS A or AAAA record resolution
of the destination hostname and instead pass the hostname to the
proxy as-is.
Drivers MUST treat a connection failure when connecting to the SOCKS5 proxy or a SOCKS5 handshake or authentication
failure the same as a network error (e.g. `ECONNREFUSED`).

#. Continue with connection establishment as if the connection was one
to the destination host.
### Events

Drivers MUST use the SOCKS5 proxy for connections to MongoDB services
and `client-side field-level encryption KMS servers <../client-side-encryption/client-side-encryption.md#kms-provider>`__.
SOCKS5 proxies are fully transparent to connection monitoring events. In particular, in `CommandStartedEvent`,
`CommandSucceededEvent`, and - Code:`CommandFailedEvent`, the driver SHOULD NOT reference the SOCKS5 proxy as part of
the `connectionId` field or other fields.

Drivers MUST NOT use the SOCKS5 proxy for connections to
:code:`mongocryptd` processes spawned for automatic client-side field-level encryption.
### Q&A

Drivers MUST treat a connection failure when connecting to the SOCKS5
proxy or a SOCKS5 handshake or authentication failure the same as a
network error (e.g. `ECONNREFUSED`).
#### Why not include DNS requests in the set of proxied network communication?

Events
------
While SOCKS5 as a protocol does support UDP forwarding, using this feature has a number of downsides. Notably, only a
subset of SOCKS5 client libraries and SOCKS5 server implementations support UDP forwarding (e.g. the OpenSSH client's
dynamic forwarding feature does not). This would also considerably increase implementation complexity in drivers that do
not use DNS libraries in which the driver is in control of how the UDP packets are sent and received.

SOCKS5 proxies are fully transparent to connection monitoring events.
In particular, in :code:`CommandStartedEvent`, :code:`CommandSucceededEvent`, and
:code:`CommandFailedEvent`, the driver SHOULD NOT reference the SOCKS5
proxy as part of the :code:`connectionId` field or other fields.
#### Why not support other proxy protocols, such as Socks4/Socks4a, HTTP Connect proxies, etc.?

Q&A
---
SOCKS5 is a powerful, standardized and widely used proxy protocol. It is likely that almost all users which require
tunneling/proxying of some sort will be able to use it, and those who require another protocol or a more advanced setup
like proxy chaining, can work around that by using a local SOCKS5 intermediate proxy.

Why not include DNS requests in the set of proxied network communication?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

While SOCKS5 as a protocol does support UDP forwarding, using this feature has a number
of downsides. Notably, only a subset of SOCKS5 client libraries and SOCKS5 server
implementations support UDP forwarding (e.g. the OpenSSH client’s dynamic
forwarding feature does not). This would also considerably increase implementation
complexity in drivers that do not use DNS libraries in which the driver is
in control of how the UDP packets are sent and received.

Why not support other proxy protocols, such as Socks4/Socks4a, HTTP Connect proxies, etc.?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

SOCKS5 is a powerful, standardized and widely used proxy protocol. It is likely that
almost all users which require tunneling/proxying of some sort will be able to use it,
and those who require another protocol or a more advanced setup like proxy chaining,
can work around that by using a local SOCKS5 intermediate proxy.

Why are the connection string parameters generic, with no explicit mention of SOCKS5?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In the case that future changes will enable drivers using other proxy protocols,
keeping the option names generic allows their re-use.
In that case, another option would specify the protocol and SOCKS5 would be the
implied default. However, since there is no reason to believe that such additions
will be made in the foreseeable future, no option for specifying the proxy protocol
is introduced here.
#### Why are the connection string parameters generic, with no explicit mention of SOCKS5?

Why is support for authentication methods limited to no authentication and username/password authentication?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In the case that future changes will enable drivers using other proxy protocols, keeping the option names generic allows
their re-use. In that case, another option would specify the protocol and SOCKS5 would be the implied default. However,
since there is no reason to believe that such additions will be made in the foreseeable future, no option for specifying
the proxy protocol is introduced here.

This matches the set of authentication methods most commonly implemented by SOCKS5
client libraries and thus reduces implementation complexity for drivers.
This advantage is sufficient to ignore the possible advantages that would
come with enabling other authentication methods.
#### Why is support for authentication methods limited to no authentication and username/password authentication?

Design Rationales
-----------------
This matches the set of authentication methods most commonly implemented by SOCKS5 client libraries and thus reduces
implementation complexity for drivers. This advantage is sufficient to ignore the possible advantages that would come
with enabling other authentication methods.

Alternative Designs
-------------------
### Design Rationales

Changelog
=========
### Alternative Designs

:2022-10-05: Remove spec front matter
## Changelog

- 2024-09-04: Migrated from reStructuredText to Markdown.
- 2022-10-05: Remove spec front matter
4 changes: 4 additions & 0 deletions source/socks5-support/socks5.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

.. note::
This specification has been converted to Markdown and renamed to
`socks5.md <socks5.md>`_.
Loading

0 comments on commit f05743f

Please sign in to comment.