5
5
6
6
Async SOCKS proxy connector client and server implementation, tunnel any TCP/IP-based
7
7
protocol through a SOCKS5 or SOCKS4(a) proxy server, built on top of
8
- [ ReactPHP] ( https://reactphp.org ) .
8
+ [ ReactPHP] ( https://reactphp.org/ ) .
9
9
10
10
The SOCKS proxy protocol family (SOCKS5, SOCKS4 and SOCKS4a) is commonly used to
11
11
tunnel HTTP(S) traffic through an intermediary ("proxy"), to conceal the origin
@@ -81,32 +81,45 @@ Let's take these projects to the next level together! 🚀
81
81
82
82
## Quickstart example
83
83
84
- Once [ installed] ( #install ) , you can use the following code to create a connection
85
- to google.com via a local SOCKS proxy server:
84
+ Once [ installed] ( #install ) , you can use the following code to send a secure
85
+ HTTPS request to google.com through a local SOCKS proxy server:
86
86
87
87
``` php
88
+ <?php
89
+
90
+ require __DIR__ . '/vendor/autoload.php';
91
+
88
92
$proxy = new Clue\React\Socks\Client('127.0.0.1:1080');
89
93
90
- $proxy->connect('tcp://www.google.com:80')->then(function (React\Socket\ConnectionInterface $connection) {
91
- $connection->write("GET / HTTP/1.0\r\n\r\n");
94
+ $connector = new React\Socket\Connector(array(
95
+ 'tcp' => $proxy,
96
+ 'dns' => false
97
+ ));
92
98
93
- $connection->on('data', function ($chunk) {
94
- echo $chunk;
95
- });
99
+ $browser = new React\Http\Browser($connector);
100
+
101
+ $browser->get('https://google.com/')->then(function (Psr\Http\Message\ResponseInterface $response) {
102
+ var_dump($response->getHeaders(), (string) $response->getBody());
103
+ }, function (Exception $e) {
104
+ echo 'Error: ' . $e->getMessage() . PHP_EOL;
96
105
});
97
106
```
98
107
99
108
If you're not already running any other [ SOCKS proxy server] ( #servers ) ,
100
109
you can use the following code to create a SOCKS
101
- proxy server listening for connections on ` localhost :1080` :
110
+ proxy server listening for connections on ` 127.0.0.1 :1080` :
102
111
103
112
``` php
113
+ <?php
114
+
115
+ require __DIR__ . '/vendor/autoload.php';
116
+
104
117
// start a new SOCKS proxy server
105
- $server = new Clue\React\Socks\Server();
118
+ $socks = new Clue\React\Socks\Server();
106
119
107
- // listen on localhost :1080
120
+ // listen on 127.0.0.1 :1080
108
121
$socket = new React\Socket\SocketServer('127.0.0.1:1080');
109
- $server ->listen($socket);
122
+ $socks ->listen($socket);
110
123
```
111
124
112
125
See also the [ examples] ( examples ) .
@@ -379,16 +392,16 @@ URI scheme acts as an alias for the default `socks://` URI scheme.
379
392
380
393
``` php
381
394
// all three forms are equivalent
382
- $proxy = new Clue\React\Socks\Client('127.0.0.1');
383
- $proxy = new Clue\React\Socks\Client('socks://127.0.0.1');
384
- $proxy = new Clue\React\Socks\Client('socks5://127.0.0.1');
395
+ $proxy = new Clue\React\Socks\Client('127.0.0.1:1080 ');
396
+ $proxy = new Clue\React\Socks\Client('socks://127.0.0.1:1080 ');
397
+ $proxy = new Clue\React\Socks\Client('socks5://127.0.0.1:1080 ');
385
398
```
386
399
387
400
If want to explicitly set the protocol version to SOCKS4(a), you can use the URI
388
401
scheme ` socks4:// ` as part of the SOCKS URI:
389
402
390
403
``` php
391
- $proxy = new Clue\React\Socks\Client('socks4://127.0.0.1');
404
+ $proxy = new Clue\React\Socks\Client('socks4://127.0.0.1:1080 ');
392
405
```
393
406
394
407
#### DNS resolution
@@ -467,7 +480,7 @@ so this methods should not be used on a network where you have to worry about ea
467
480
You can simply pass the authentication information as part of the SOCKS URI:
468
481
469
482
``` php
470
- $proxy = new Clue\React\Socks\Client('username :password@127.0.0.1');
483
+ $proxy = new Clue\React\Socks\Client('alice :password@127.0.0.1:1080 ');
471
484
```
472
485
473
486
Note that both the username and password must be percent-encoded if they contain
@@ -476,7 +489,7 @@ special characters:
476
489
``` php
477
490
$user = 'he:llo';
478
491
$pass = 'p@ss';
479
- $url = rawurlencode($user) . ':' . rawurlencode($pass) . '@127.0.0.1';
492
+ $url = rawurlencode($user) . ':' . rawurlencode($pass) . '@127.0.0.1:1080 ';
480
493
481
494
$proxy = new Clue\React\Socks\Client($url);
482
495
```
@@ -493,7 +506,7 @@ version 5 and complains if you have explicitly set anything else:
493
506
494
507
``` php
495
508
// throws InvalidArgumentException
496
- new Clue\React\Socks\Client('socks4://user:pass @127.0.0.1');
509
+ new Clue\React\Socks\Client('socks4://alice:password @127.0.0.1:1080 ');
497
510
```
498
511
499
512
#### Proxy chaining
@@ -627,7 +640,7 @@ Similarly, you can also combine this with [authentication](#authentication)
627
640
like this:
628
641
629
642
``` php
630
- $proxy = new Clue\React\Socks\Client('sockss://user:pass @127.0.0.1:1080');
643
+ $proxy = new Clue\React\Socks\Client('sockss://alice:password @127.0.0.1:1080');
631
644
```
632
645
633
646
> Note that for most use cases, [ secure TLS connections] ( #secure-tls-connections )
@@ -668,7 +681,7 @@ Similarly, you can also combine this with [authentication](#authentication)
668
681
like this:
669
682
670
683
``` php
671
- $proxy = new Clue\React\Socks\Client('socks+unix://user:pass @/tmp/proxy.sock');
684
+ $proxy = new Clue\React\Socks\Client('socks+unix://alice:password @/tmp/proxy.sock');
672
685
```
673
686
674
687
> Note that Unix domain sockets (UDS) are considered advanced usage and PHP only
@@ -690,11 +703,11 @@ It supports the SOCKS5 and SOCKS4(a) protocol versions by default.
690
703
You can start listening on an underlying TCP/IP socket server like this:
691
704
692
705
``` php
693
- $server = new Clue\React\Socks\Server();
706
+ $socks = new Clue\React\Socks\Server();
694
707
695
- // listen on localhost :1080
708
+ // listen on 127.0.0.1 :1080
696
709
$socket = new React\Socket\SocketServer('127.0.0.1:1080');
697
- $server ->listen($socket);
710
+ $socks ->listen($socket);
698
711
```
699
712
700
713
This class takes an optional ` LoopInterface|null $loop ` parameter that can be used to
@@ -725,7 +738,7 @@ $connector = new React\Socket\Connector(array(
725
738
)
726
739
));
727
740
728
- $server = new Clue\React\Socks\Server(null, $connector);
741
+ $socks = new Clue\React\Socks\Server(null, $connector);
729
742
```
730
743
731
744
If you want to forward the outgoing connection through another SOCKS proxy, you
@@ -736,7 +749,7 @@ Internally, the `Server` uses ReactPHP's normal
736
749
[ ` connect() ` ] ( https://github.com/reactphp/socket#connect ) method, but
737
750
it also passes the original client IP as the ` ?source={remote} ` parameter.
738
751
The ` source ` parameter contains the full remote URI, including the protocol
739
- and any authentication details, for example ` socks://user:pass @1.2.3.4:5678 `
752
+ and any authentication details, for example ` socks://alice:password @1.2.3.4:5678 `
740
753
or ` socks4://1.2.3.4:5678 ` for legacy SOCKS4(a).
741
754
You can use this parameter for logging purposes or to restrict connection
742
755
requests for certain clients by providing a custom implementation of the
@@ -758,9 +771,9 @@ If you only want to accept static authentication details, you can simply pass an
758
771
additional assoc array with your authentication details to the ` Server ` like this:
759
772
760
773
``` php
761
- $server = new Clue\React\Socks\Server(null, null, array(
762
- 'tom ' => 'password',
763
- 'admin ' => 'root '
774
+ $socks = new Clue\React\Socks\Server(null, null, array(
775
+ 'alice ' => 'password',
776
+ 'bob ' => 's3cret!1 '
764
777
));
765
778
```
766
779
@@ -770,14 +783,14 @@ If you want more control over authentication, you can pass an authenticator
770
783
function that should return a ` bool ` value like this synchronous example:
771
784
772
785
``` php
773
- $server = new Clue\React\Socks\Server(null, null, function ($user , $pass , $remote) {
774
- // $remote is a full URI à la socks://user:pass @192.168.1.1:1234
775
- // or sockss://user:pass @192.168.1.1:1234 for SOCKS over TLS
786
+ $socks = new Clue\React\Socks\Server(null, null, function ($username , $password , $remote) {
787
+ // $remote is a full URI à la socks://alice:password @192.168.1.1:1234
788
+ // or sockss://alice:password @192.168.1.1:1234 for SOCKS over TLS
776
789
// or may be null when remote is unknown (SOCKS over Unix Domain Sockets)
777
790
// useful for logging or extracting parts, such as the remote IP
778
791
$ip = parse_url($remote, PHP_URL_HOST);
779
792
780
- return ($user === 'root' && $pass === 'secret' && $ip === '127.0.0.1');
793
+ return ($username === 'root' && $password === 'secret' && $ip === '127.0.0.1');
781
794
});
782
795
```
783
796
@@ -791,7 +804,7 @@ from the authenticator function that will fulfill with a `bool` value like this
791
804
async example:
792
805
793
806
``` php
794
- $server = new Clue\React\Socks\Server(null, null, function ($user , $pass ) use ($db) {
807
+ $socks = new Clue\React\Socks\Server(null, null, function ($username , $password ) use ($db) {
795
808
// pseudo-code: query database for given authentication details
796
809
return $db->query(
797
810
'SELECT 1 FROM users WHERE name = ? AND password = ?',
@@ -829,14 +842,14 @@ You can create a SOCKS `Client` instance like this:
829
842
830
843
``` php
831
844
// set next SOCKS server example.com:1080 as target
832
- $proxy = new Clue\React\Socks\Client('user:pass @example.com:1080');
845
+ $proxy = new Clue\React\Socks\Client('alice:password @example.com:1080');
833
846
834
847
// start a new server which forwards all connections to the other SOCKS server
835
- $server = new Clue\React\Socks\Server(null, $proxy);
848
+ $socks = new Clue\React\Socks\Server(null, $proxy);
836
849
837
- // listen on localhost :1080
850
+ // listen on 127.0.0.1 :1080
838
851
$socket = new React\Socket\SocketServer('127.0.0.1:1080');
839
- $server ->listen($socket);
852
+ $socks ->listen($socket);
840
853
```
841
854
842
855
See also [ example #21 ] ( examples ) .
@@ -877,15 +890,15 @@ details.
877
890
You can simply start your listening socket on the ` tls:// ` URI scheme like this:
878
891
879
892
``` php
880
- $server = new Clue\React\Socks\Server();
893
+ $socks = new Clue\React\Socks\Server();
881
894
882
895
// listen on tls://127.0.0.1:1080 with the given server certificate
883
896
$socket = new React\Socket\SocketServer('tls://127.0.0.1:1080', array(
884
897
'tls' => array(
885
898
'local_cert' => __DIR__ . '/localhost.pem',
886
899
)
887
900
));
888
- $server ->listen($socket);
901
+ $socks ->listen($socket);
889
902
```
890
903
891
904
See also [ example 31] ( examples ) .
@@ -912,11 +925,11 @@ having to rely on explicit [authentication](#server-authentication).
912
925
You can simply start your listening socket on the ` unix:// ` URI scheme like this:
913
926
914
927
``` php
915
- $server = new Clue\React\Socks\Server();
928
+ $socks = new Clue\React\Socks\Server();
916
929
917
930
// listen on /tmp/proxy.sock
918
931
$socket = new React\Socket\SocketServer('unix:///tmp/proxy.sock');
919
- $server ->listen($socket);
932
+ $socks ->listen($socket);
920
933
```
921
934
922
935
> Note that Unix domain sockets (UDS) are considered advanced usage and that
@@ -1002,7 +1015,7 @@ $proxy->connect('tcp://www.google.com:80')->then(function (React\Socket\Connecti
1002
1015
1003
1016
### Using the Tor (anonymity network) to tunnel SOCKS connections
1004
1017
1005
- The [ Tor anonymity network] ( https://www.torproject.org ) client software is designed
1018
+ The [ Tor anonymity network] ( https://www.torproject.org/ ) client software is designed
1006
1019
to encrypt your traffic and route it over a network of several nodes to conceal its origin.
1007
1020
It presents a SOCKS5 and SOCKS4(a) interface on TCP port 9050 by default
1008
1021
which allows you to tunnel any traffic through the anonymity network:
@@ -1027,7 +1040,7 @@ which have to be resolved by Tor.
1027
1040
1028
1041
## Install
1029
1042
1030
- The recommended way to install this library is [ through Composer] ( https://getcomposer.org ) .
1043
+ The recommended way to install this library is [ through Composer] ( https://getcomposer.org/ ) .
1031
1044
[ New to Composer?] ( https://getcomposer.org/doc/00-intro.md )
1032
1045
1033
1046
This project follows [ SemVer] ( https://semver.org/ ) .
@@ -1042,12 +1055,12 @@ See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades.
1042
1055
This project aims to run on any platform and thus does not require any PHP
1043
1056
extensions and supports running on legacy PHP 5.3 through current PHP 8+ and
1044
1057
HHVM.
1045
- It's * highly recommended to use PHP 7+ * for this project.
1058
+ It's * highly recommended to use the latest supported PHP version * for this project.
1046
1059
1047
1060
## Tests
1048
1061
1049
1062
To run the test suite, you first need to clone this repo and then install all
1050
- dependencies [ through Composer] ( https://getcomposer.org ) :
1063
+ dependencies [ through Composer] ( https://getcomposer.org/ ) :
1051
1064
1052
1065
``` bash
1053
1066
$ composer install
@@ -1056,14 +1069,14 @@ $ composer install
1056
1069
To run the test suite, go to the project root and run:
1057
1070
1058
1071
``` bash
1059
- $ php vendor/bin/phpunit
1072
+ $ vendor/bin/phpunit
1060
1073
```
1061
1074
1062
1075
The test suite contains a number of tests that rely on a working internet
1063
1076
connection, alternatively you can also run it like this:
1064
1077
1065
1078
``` bash
1066
- $ php vendor/bin/phpunit --exclude-group internet
1079
+ $ vendor/bin/phpunit --exclude-group internet
1067
1080
```
1068
1081
1069
1082
## License
0 commit comments