SOCKS protocol. Universal proxy server

When working with proxies, it is very important to choose the right type of proxy for your tasks in order to avoid possible problems and achieve your goals. The most commonly used are HTTP proxies and Socks5 proxies. The differences between them lie in the degree of anonymity, the protocol used, the method of data transmission used when working as a proxy, as well as in some additional functions. Let's look at each type of proxy separately.

Features of HTTP proxy

Let's start with the HTTP proxy. During their work, they use the HTTP protocol, which is intended for visiting sites, downloading and transferring files, and when working with some programs that use this protocol to connect through a proxy. Requests made when working with HTTP proxy servers are not sent directly, but use the proxy server as an intermediary, sending requests on its behalf.

Also in the HTTP proxy protocol, caching is available, which speeds up page loading through the use of saved files, as well as monitoring and filtering network traffic, setting speed limits, blocking unwanted resources, collecting statistics by saving logs, etc.

Proxies of this protocol differ in the degree of anonymity. Stand out following types HTTP proxy for anonymity:

Transparent proxies that do not mask the real IP address, and also do not hide the fact that a proxy server is used to access the resource. Such proxies are rarely used, mainly to redirect the user to another proxy server,

Anonymous Proxy. They transmit information that proxies are used, however, your IP address is masked and replaced with another IP address, providing a reliable level of security.

Elite proxies. They hide the use of proxies and also reliably mask the IP address, which makes them the most secure among HTTP proxies. The server you are trying to access will assume that your connection is direct, without using a proxy server.

We should also highlight HTTPS proxies that use the SSL protocol. They are a subtype of the HTTP protocol that uses a secure connection. Network traffic transmitted by these proxies is securely encrypted, which guarantees the highest level of anonymity. As a rule, such proxies are used to ensure the security of banking networks, in commercial organizations to create secure corporate networks and in other connections that require security. Other features are the same as those of the HTTP protocol.

Features of Socks5 proxy

Another protocol that is popular among users is Socks5. Proxy servers working with this protocol are initially anonymous, since they pass network traffic in pure form without exposing HTTP headers. Therefore, the server you are trying to access will not know that you are using a proxy server, and will not receive your IP address.

Socks5 proxy, supports the following network protocols: HTTP, HTTPS, FTP and their features: caching, SSL connection,authentication. In addition, Socks5 protocol proxies use UDP and TPC connections, which expands their scope of application and makes them the most functional of modern proxy servers. Initially, the Socks5 protocol was intended to work with software. For this reason, most programs support this protocol for connecting via a proxy. Socks5 proxy servers also have a nice feature that allows you to build chains of proxy servers, which is useful for solving some problems when working on the Internet.

If you compare HTTP and Socks5 proxies, it is preferable to use the latter. Since they are more anonymous, they support more features, and also work with any sites and programs that support connection through a proxy. You can visit our website by placing an order in your personal account.

The article is devoted to the SOCKS5 protocol - its internal structure, practical application, as well as SOCKS servers and clients available for the Unix platform

[Valentin Sinitsyn (val AT linuxcenter DOT ru)]

“Sorry, Pooh,” said SAVA. - Tigger chewed all the wires from the mail server, and the mail did not arrive for a long time...
“Wires,” thought Pooh angrily. - Knit socks from these wires.

Andrey Shcherbakov “9600 baud and that’s it, that’s it, that’s it...”

In this article we will talk about the SOCKS protocol[ footnote: "socks" - English. "socks", "stockings"]. With its help you can solve the most different tasks: organize secure access to services located behind a firewall, hide your true IP address when working with unfriendly network resources, or implement a universal proxy server that supports any application level protocols (HTTP, FTP, POP3/SMTP, ICQ etc.). Unfortunately, despite the simplicity and richness of SOCKS, many system administrators are not very familiar with it and have no idea how it can be useful. I would like to hope that after reading this material, the undeservedly forgotten protocol will take its rightful place in their arsenal. Let’s make a reservation right away: all subsequent presentation will refer to the fifth version of SOCKS, SOCKS5. The previous, fourth version (SOCKS4) is still in circulation on the Internet, however, its capabilities are more limited.

By the way, the name of the protocol has nothing to do with the hosiery items mentioned in the epigraph and is a simple abbreviation for “SOCK-et-S” - “sockets”, or, in a more familiar translation to a computer specialist’s ear, “sockets”. The term was proposed by the creators as a working option, and it stuck. As you know, sockets are the basis of any API that implements networking- Unix, Winsock, etc. To send data over the network, an application simply needs to write it to a socket, similar to what is done when storing information in a local file. In both cases, the program does not have to worry about what is happening “behind the scenes” - the addition of user data with service information, breaking it into segments with their subsequent encapsulation into datagrams and physical sending is carried out by other parts of the operating system - the TCP / IP stack and device drivers that the application knows nothing about. This “division of labor” allows you to change the message delivery procedure as desired, provided that the application programming interface remains constant. It is this feature that underlies the SOCKS ideology. The main task of this protocol is to introduce into the “normal” data exchange process a certain intermediary called a SOCKS server or SOCKS proxy. When a client (an application that supports SOCKS: Mozilla web browser, ICQ Miranda IM client, etc., see below) wants to send any information over the network, it establishes a connection not with the real recipient, but with the SOCKS server, which, in in turn, forwards the data to its destination, but on its own behalf. From the point of view of the "real" server (for example, the web site that the user wants to view in Mozilla Firefox) SOCKS proxy is the most common client. Thus, the identity (IP address) of the true client is hidden from the server serving it. This very convenient circumstance is fraught with potential danger (you can hide You, but they can from you), therefore, real-life SOCKS servers have developed access control schemes (prohibiting incoming and outgoing connections to a given list of addresses) and support user authorization using a password (see below).

Note that since SOCKS operates at a lower level than the application (namely, transport) level of the OSI model, its support will not require any changes in the logic of the client, much less the server. Indeed, all that is needed is to modify the implementation of the functions responsible for creating network connection and sending data: connect(), bind(), send(), etc. In practice, this is usually achieved by intercepting system calls and then replacing them with SOCKS-enabled user-defined counterparts. No changes to the source code client applications, much less access to the source texts, as a rule, is not required. This powerful procedure is known as “soxification” and will be discussed in detail below.

Now that we have a basic understanding of SOCKS, we can move on to a more detailed look. of this protocol.

SOCKS5 specification

The SOCKS5 protocol is described in detail in RFC1928. Unlike monstrous standards like HTTP 1.1, the SOCKS specification fits into 9 pages and can be easily parsed by anyone. The information offered here is a brief summary of it and is intended to help you in this simple matter.

As noted earlier, SOCKS5 is a transport layer protocol. Its “neighbors” - TCP and UDP are directly used to transmit data coming from the application layer (from custom applications), which means the SOCKS proxy must be able to work correctly with each of them. Note also that the ICMP protocol used by the ping and traceroute utilities is located below the transport layer, and therefore, unfortunately, cannot be cosified.[ Footnote: there are non-standard extensions to the SOCKS protocol that allow you to work with ICMP, however, they will not be discussed in this article].

Before sending any data, the client must go through an authorization procedure on the SOCKS server. To do this, it opens a TCP connection to port 1080 (default value) of the SOCKS server and sends a message over it containing the code numbers of the authentication methods it supports. The SOCKS server selects one of the methods at its discretion and reports its number to the client. A list of some of the possible values ​​is given in Table 1. As you can easily see, authentication can be absent (in practice, this most likely means that the SOCKS server distinguishes clients by their IP addresses) or based on a username and password. In the latter case it is possible a large number of various options, from the trivial “Username/Password Authentication” (RFC 1929) providing for the transmission of a password to open form to the much more secure CHAP (encrypted password, plain data) and GSSAPI (RFC 1961), which can be used to completely cryptographicly protect traffic. After successful authorization, the client is able to send requests (commands), establish outgoing connections, and even receive incoming ones.

Establishing an outgoing TCP connection

To establish an outgoing TCP connection, the client sends a “CONNECT” request to the SOCKS server, which specifies the address and delivery port. To identify the recipient node, both IP addresses (IPv4/IPv6 are supported) and full-fledged domain names. In the latter case, the SOCKS server takes care of resolving them, so the network in which the client operates can, in principle, do without a DNS server. In the response message, the SOCKS server reports an error code (as usual, 0 indicates that the operation was successful), as well as the IP address (BND.ADDR) and TCP port (BND.PORT) that will be used to actually communicate with the requested knot. Since SOCKS servers typically have more than one network interface, given IP address may differ from the one with which the control connection was established. The client then opens a new TCP session with BND.ADDR:BND.PORT and sends data. The outgoing TCP connection is terminated when the control session is closed. Note that a CONNECT request may be rejected by a SOCKS proxy if the source (client) or destination (server) addresses are prohibited [ Footnote: or not explicitly allowed, depending on the specific implementation and policy chosen] to service system administrator.

Establishing an outgoing UDP connection

Unlike the TCP streaming protocol, which involves establishing a session, the UDP protocol is datagram-based and therefore somewhat more complex to use. Its support appeared only in SOCKS5.

Before sending UDP datagrams, the client requests the SOCKS server UDP association using the "UDP ASSOCIATE" command. A UDP association is a kind of virtual session between a client and a SOCKS server. In the outgoing request, the client specifies allegedthe address and port that will act as the source of future UDP datagrams. If this information is not yet known when the UDP association is established, the client should use the combination 0.0.0.0:0 (or, say, x.x.x.x:0 if only the port number is unknown). In the response message, the SOCKS server specifies the IP address (BND.ADDR) and UDP port (BND.PORT) to which outgoing datagrams should be sent. In this case, the address and port of their real recipient are indicated directly in the body (we can say that UDP encapsulation takes place). E you parameters, along with the sender's address and port, are used to decide whether a datagram can be sent. As you can easily see, this creates an additional load on the SOCKS server: filtering rules must be applied to each UDP datagram, whereas in the case of a TCP connection, its legitimacy is assessed once, at the time the SOCKS server executes the “CONNECT” command. According to the standard, the SOCKS server must ensure that the IP address of the datagram sender matches the address of the host that created the UDP association. The UDP association is destroyed simultaneously with the closing of the TCP control session in which the UDP ASSOCIATE command was sent.

Many of the existing SOCKS servers experience serious problems if a NAT (Network Address Translation) firewall is placed between them and the client requesting the UDP association. The reason for this lies in the change in the source address and port that occurs the moment the UDP datagram crosses the firewall. As a result, the server and the unsuspecting client application begin to speak different languages: the intended source address and port specified in the “UDP ASSOCIATE” command no longer correspond to the real parameters of the datagrams received by the SOCKS server. As a result, they are discarded as not belonging to the UDP association. The problem could be solved by specifying 0.0.0.0:0 as the intended source (see above), which should be interpreted by the SOCKS server as “any UDP datagram coming from the same address as the command to create the association.” Unfortunately, most of the actual SOCKS servers interpret the standard more narrowly and do not allow you to simultaneously set both the intended address and the sender port to zero. Of the implementations tested by the author, the “trick with forwarding UDP through NAT” described here allows only one to be done - Dante.

Receiving incoming connections

This rather original feature can be useful in cases where the client and the “real” server in the scheme described above are swapped, which can happen, for example, in protocols like FTP. For the purpose of further discussion, we will assume that between the “client” (the party intending to accept incoming connection) and the “server” (the party initiating the incoming connection) has already established a “direct” communication channel using the “CONNECT” command. To open a “reverse” channel, the “client” must send the “BIND” command to the SOCKS server, specifying in its parameters the IP address and port that it will use to receive the incoming connection. In response, the SOCKS server reports the IP address and port allocated to it to maintain the “reverse” channel. The "client" is expected to pass these parameters to the "server" using the facilities provided by application layer protocols (for example, the FTP "PORT" command). After the SOCKS server accepts (or rejects) the incoming connection, it re-notifies the “client”, telling it the IP address and port used by the “server”. Note that incoming connections can only be accepted by an application whose developers took care of SOCKS support at the design stage. Otherwise (if the application works with the SOCKS server through a sockets program), it will not be able to provide correct information about the address of the socket that is waiting for “feedback” (i.e., it will generate the incorrect “PORT” command in the FTP example discussed above).

"Chains" SOCKS

Come on, get to work. Six rented “at a time” routers through which the signal runs. And all are quite resistant to hacking.

Sergey Lukyanenko “Labyrinth of Reflections”

The architecture of the SOCKS5 protocol makes it easy to combine SOCKS servers into cascades, or as they are also called “chains”. It is noteworthy that all the actions necessary for this can be performed on the client side. The only requirement for the “links” of the chain is that they must “trust” each other (i.e., allow the establishment of incoming and outgoing connections). If the SOCKS servers that form the cascade are not anonymous (that is, they use Username/Password, CHAP, or similar authentication schemes), it is also necessary that the user can successfully complete the authorization procedure on each of them.

Let's assume that we have a set of N SOCKS servers named socks1, socks2, ..., socksN, satisfying all the above requirements. Then, to create a cascade, the client can do the following:

    When outgoing TCP connection: the client connects to socks1, goes through the authorization procedure (if necessary) and sends the “CONNECT” command, specifying socks2 as the delivery address. By executing this request, socks1 will create a new connection with socks2 and will regularly transfer all the information passing through it to the client, while socks2 will not even guess with whom it is actually communicating. The procedure is then repeated until a connection is established between socks(N-1) and socksN. The last server in the cascade connects directly to the node that interests the client. Data transfer occurs as usual: the client sends a packet to the socks1 server, which, in turn, transmits it to socks2, ... and so on until the end node is reached.

    When outgoing UDP connection: the client connects to socks1, goes through the authorization procedure and sequentially sends two commands: “CONNECT” (delivery address - socks2) and “UDP ASSOCIATE”. Thus, two new connections are created: a virtual UDP channel between the client and socks1, and a TCP session between socks1 and socks2.

Using this TCP session, the client (on behalf of socks1) sends the command “UDP ASSOCIATE” to the socks2 server (opens a UDP channel between socks1 and socks2) and “CONNECT” to the socks3 server.The procedure continues until virtual UDP channels are established between all SOCKS servers in the cascade. To send any data, the client first performs N-fold encapsulation of the UDP datagram, specifying sequentially socks1, socks2, socks3, socksN and the address of the real recipient as the delivery address, and then sends it to the socks1 server. Note that in practice this cascading option is extremely rare. This is due to the fact that SOCKS servers, like NAT Firewalls, can change the source port of the datagram, which will lead to problems described in detail in the section “Establishing an outgoing UDP connection”. Using chains of SOCKS servers that do not require authentication, the client can significantly increase the anonymity of browsing the Internet (see epigraph). You can find many programs on the Internet that implement the schemes described here. These, for example, are SocksChain ( http://www.ufasoft.com/socks/) for Windows or ProxyChains ( ).

) for Unix. Cascading SOCKS servers is also an integral part of some soxifiers, most notably FreeCap (

Now that we are well familiar with the operating principles of a SOCKS server, it’s time to move from theory to practice. There are a large number of programs in the world that implement the SOCKS5 protocol. They cover all popular operating systems (Unix, Windows, ...) and distribution methods (freeware, shareware, open-source, etc.). Here we will briefly consider the most famous (or interesting from the author’s point of view) implementations.

Let's start with SOCKS5 Reference Implementation (http://www.socks.permeo.com/), made by NEC and owned by currently Permeo company. The current version is numbered 1.0r11 and is dated August 2000. As you can easily guess from the name, this server is a reference implementation of the protocol and, generally speaking, is not intended for industrial use. However, for reasons that are not very clear to me, it was included in the FreeBSD ports, and therefore is a de facto standard on this platform. The product has GSSAPI support and is distributed in source code, but under a proprietary license. Commercial use of this server is prohibited.

Dante, developed by Norwegian company Inferno Nettverk, is especially popular among Linux supporters. The product is developing, although not very rapidly (the latest version, 1.1.15, is dated January 31, 2005) and is quite suitable for practical use. As mentioned earlier, Dante allows UDP associations to work correctly even if they go through a NAT Firewall. The program is distributed in source code under the BSD license. Dante includes a library for transparent coxification of Unix applications (see below)

Valentin Sinitsyn (val AT linuxcenter DOT ru) - Universal proxy server

Some time ago I wanted to try to implement a proxy server for my own needs, and one that could be used in the future, and also that its size would be minimal. The natural option for me was implementation using assembler. The program turned out to be small, convenient, and in the future I used it very often. But now, after years, I would like to show simplest implementation one protocol, SOCKS4. This protocol was created so that clients located on the local network behind the firewall could access the external network. At the same time, in this case, it is possible to control client requests :) The very first thing you need to do when implementing is to read the documentation describing this protocol, since we want our protocol to be understood by standard programs, without “undermining with a file.” So, the documentation:

Now, armed with a description, let's get started. The job of a proxy server is to accept a request from a client in a certain format, generate a socket and connect it to the address requested by the client, and then ensure the exchange of data between two sockets until they are closed by the server or client. Let's start implementation.

Macros and data structures used in the program

Let's create an include file, includes.inc. In this file we will place standard macros + structures for working with SOCKS4 when writing Windows programs. Here I will not give all the macros, I will only give the description and functionality necessary to solve the main problem, everything else you will find in the attached file with source codes.
; SOCKS4 – The structure used by the client when requesting a connection; to the specified server(DSTIP)/port(DSTPORT) CONNECT_SOCK4 Struc VN Db ?

CD Db? DSTPORT Dw? DSTIP Dd?
NULL Db? CONNECT_SOCK4 Ends ; SOCKS4 - proxy server response about the connection. RESPONSE_SOCK4 Struc VN Db ?
CD Db?
DSTPORT Dw?
* And the final, third stage is sending data between the client socket and the socket created and connected by us to the requested address.

Implementation of the first stage, initialization of the program:

; The main procedure is the starting procedure for the WinMain program Proc LOCAL ThreadId, hServSock:DWORD LOCAL hostname :BYTE LOCAL _wsa:WSADATA LOCAL _our:sockaddr_in ; Launching the library for working with sockets, we use the functionality of version 1.1, ; let's request it as a minimum invoke WSAStartup, 0101h, ADDR _wsa .if eax == 0 ; We take our address, prepare a structure to initialize the server socket invoke gethostname, ADDR hostname, 256 invoke gethostbyname, ADDR hostname .if eax == 0 invoke inet_addr, ADDR hostname .else mov eax, mov eax, mov eax, .endif mov _our. sin_addr, eax invoke inet_ntoa, eax mov _our.sin_family, AF_INET mov _our.sin_addr.S_un.S_addr, INADDR_ANY xor eax, eax ; Enter the port on which we want to listen to incoming messages mov ax, SOCKS_PORT invoke htons, eax mov _our.sin_port, ax invoke socket, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET ; Save the created server socket mov hServSock, eax ; We bind the server socket to our address and the required port invoke bind, hServSock, ADDR _our, SIZEOF sockaddr_in .if eax != SOCKET_ERROR @@: ; Initiate the socket to wait invoke listen, hServSock, SOMAXCONN .repeat ; A client has arrived, we receive a socket with the incoming client invoke accept, hServSock, NULL, NULL .until eax != INVALID_SOCKET ; Create a thread in which the current client will be processed xchg eax, ebx invoke CreateThread, NULL, NULL, ADDR socketThread, ebx, NULL, ADDR ThreadId ; We leave to wait for clients jmp @B .endif .endif invoke closesocket, hServSock .endif invoke ExitProcess, 0 WinMain Endp
This is our first procedure, I tried to comment on the code as much as possible so that you can figure it out, but if something is still not clear, please contact either me or MSDN. Basically all code is written using MASM and WinAPI syntax. The result of the above function should be a working socket on one of network addresses your machine (local address, or external address if you have a real IP) + based on the client connection, the function creates a separate thread used to work with the incoming client. Now let's move on...

Second stage, analysis of the client's request

In the second step, all that needs to be done is to accept a CONNECT_SOCK4 structure, create a socket, try to connect it, and send a response to the client. Implementation:

SocketThread Proc sock:DWORD LOCAL lpMem, _csock, ThreadId, dAmount:DWORD LOCAL Remote:sockaddr_in LOCAL wrFds, rdFds:fd_set LOCAL hResp:RESPONSE_SOCK4 ; Getting ready to read data from the socket invoke FdZero, ADDR rdFds invoke FdSet, sock, ADDR rdFds invoke select, NULL, ADDR rdFds, NULL, NULL, NULL ; We get the size of the data waiting to be read invoke ioctlsocket, sock, FIONREAD, ADDR dAmount ; We reserve memory for data mov lpMem, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount) ; Read request data from the socket invoke recv, sock, lpMem, dAmount, 0 ; The request came lea edi, hResp mov esi, lpMem ; Esi contains a user request. We handle (here) only the SOCKS4 version, ; SOCKS5 can, in principle, be processed here, but that will come later... Assume Esi: Ptr CONNECT_SOCK4 Assume Edi: Ptr RESPONSE_SOCK4 .if .VN == 4 ; Implementation of the SOX 4 protocol .if .CD == 1 invoke socket, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET mov _csock, eax ; We take the data of the remote host with which the client wants to connect mov Remote.sin_family, AF_INET mov ax, .DSTPORT mov Remote.sin_port, ax mov eax, .DSTIP mov Remote.sin_addr, eax mov cx, .DSTPORT mov edx, .DSTIP ; Edi contains the answer to the user mov .VN, 0 mov .DSTPORT, cx mov .DSTIP, edx ; We are trying to connect with remote server invoke connect, _csock, ADDR Remote, SIZEOF Remote .if !eax ; We are preparing a response that we have connected mov .CD, 90 ; We send the client a response containing the result of the connection attempt invoke send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 ; We form a structure with information about the server and; connected client sockets; - by server here I mean the socket connected to the client; who sent the request; - by client I mean a socket connected to the server; whose data was requested by the client mov ebx, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, SIZEOF THREAD_DATA) Assume Ebx: Ptr THREAD_DATA mov eax, _csock mov .Server, eax mov eax, sock mov .Client, eax Assume Ebx: Nothing ; We start the socket processing thread (reading from the client and transmitting to the server socket) invoke CreateThread, NULL, NULL, ADDR ClientSock, ebx, NULL, ADDR ThreadId .else ; If the connection fails, close the client socket invoke closesocket, _csock ; We say that there was a connection error mov , 91 ; We send the client a response containing the result of the connection attempt invoke send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 .endif .endif .endif .endif Assume Edi: Nothing Assume Esi: Nothing ; Freeing the memory allocated for the request invoke LocalFree, lpMem ret socketThread Endp
The result of this procedure is a connected socket, as well as a created thread that implements data exchange between two sockets. It's simple. One has only to clarify that several addressing points are used here within the structures that were introduced into MASM to make the programmer’s life easier. First point, the “Assume” macro.
The line Assume Esi: Ptr CONNECT_SOCK4 tells the compiler that this register (Esi) contains the address of the CONNECT_SOCK4 structure, which further simplifies accessing variables within this structure. Assume Esi:Nothing cancels the binding. To better understand, it might be easier if I list a few addressing options:
Assume Esi:Ptr CONNECT_SOCK4 mov al, .VN ; We place in AL the byte value from the variable VN structure mov al, .CD ; Place the variable CD mov ax in AL. .DSTPORT ; Place the DSTPORT variable in AX Assume Esi:Nothing
or
mov al, ; Place the byte value from the VN variable in AL mov al, ; Place the variable CD in AL mov ax, ; Place the DSTPORT variable in AX
or
mov al, byte ptr ; Place variable VN in AL mov al, byte ptr ; Place the CD variable in AL mov ax, word ptr ; Place the DSTPORT variable in AX

I think it’s obvious to you, just as it is to me, that it’s faster, more convenient and clearer to use the first option. Although if it is necessary to refer to one variable of the structure, the second option has a right to exist. I think it is better to use the third option in cases where the data at the address is not structured. But, as you know, every Tambov wolf has its own taste and color. Use the method that is most convenient for you.
One more point worth clarifying. Result macro. This macro was written so that you can call a WinAPI function in one line and write the execution result to a register or memory. So the line:
mov lpMem, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount)
First makes a call like this:
invoke LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount
and after executing this call, the execution result (Eax) is stored in the lpMem variable. In this particular case, memory will be allocated, and the address at which the area allocated for us is located will be written to the variable.

Stage three, data transfer

So, the two most difficult stages have been completed. The client arrived, we connected him to the remote server, and it was time for the simplest “monkey” work. Transfer data between two sockets. Let's do it quickly and easily:
; A stream reading from the client socket and sending it to the server socket.... ClientSock Proc Param:DWORD LOCAL sserver, sclient:DWORD LOCAL rdFds:fd_set LOCAL dAmount, lpBuf: DWORD ; In Param we have information about the server and client sockets; transfer to local variables mov ebx, Param Assume Ebx: Ptr THREAD_DATA mov eax, .Server mov sserver, eax mov eax, .Client mov sclient, eax Assume Ebx: Nothing ; Don't forget to free up memory invoke LocalFree, Param @@: invoke FdZero, ADDR rdFds invoke FdSet, sserver, ADDR rdFds invoke FdSet, sclient, ADDR rdFds invoke select, NULL, ADDR rdFds, NULL, NULL, NULL ; Check if there is data to read.if eax == SOCKET_ERROR || eax == 0 ; No data - exit jmp @F .endif ; Is there data from the server that needs to be passed to the client? invoke FdIsSet, sserver, ADDR rdFds .if eax ; We get the size of the data waiting to be read invoke ioctlsocket, sserver, FIONREAD, ADDR dAmount ; Reserve memory for data mov lpBuf, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount) invoke recv, sserver, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif invoke send, sclient, lpBuf, eax, 0 invoke LocalFree, lpBuf .endif ; Is there data from the client to send to the server socket? invoke FdIsSet, sclient, ADDR rdFds .if eax ; We get the size of the data waiting to be read invoke ioctlsocket, sclient, FIONREAD, ADDR dAmount ; Reserve memory for data mov lpBuf, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount) invoke recv, sclient, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif invoke send, sserver, lpBuf, eax, 0 invoke LocalFree, lpBuf .endif ; Let's go to
new cycle
jmp @B @@: ; Close the sockets invoke closesocket, sserver invoke closesocket, sclient ; Exit the invoke thread ExitThread, 0 ClientSock Endp Initially, this procedure initializes internal variables from the structure passed to the stream to make them more convenient to use. Then, in the loop, a check is made to see if there is data to read from the sockets, then in two pieces of code (actually copy-paste, here I didn’t bother with removing the function and optimizing it because it’s clearer) read from one socket and send it to the second.– FireFox. In the connection settings we indicate that we need to use a SOCKS4 proxy server. We indicate its address and the port on which it is located. After that, we save the settings and enjoy the Internet, passed through our proxy, 3.5 kbytes in size))) Yes, I’ll clarify. For compilation it is necessary to have the package installed

Such a proxy server controls the client’s rights to access external resources and transmits the request to the server. SOCKS can also be used in the opposite way, allowing external clients to connect to servers behind a firewall.

Unlike HTTP proxy servers, SOCKS transmits all the data from the client without adding anything from itself, that is, from the point of view of the end server, the SOCKS proxy is a regular client. SOCKS is more universal - it does not depend on specific application layer protocols (layer 7 of the OSI model) and is based on the TCP/IP standard - the layer 4 protocol. But the HTTP proxy caches data and can more carefully filter the content of the transmitted data.

This protocol was developed by David Koblas, a system administrator at MIPS Computer Systems. After MIPS became part of Silicon Graphics (SGI) that year, Koblas gave a talk on SOCKS at the Usenix Security Symposium, and SOCKS became publicly available. The protocol was extended to version 4 by Ying-Da Lee of NEC Systems Laboratory.

SOCKS 4 protocol

SOCKS 4 is designed to work through a firewall without authentication for client-server applications running over TCP, such as TELNET, FTP, and popular communication protocols such as HTTP, WAIS, and GOPHER. Essentially, a SOCKS server can be thought of as a firewall that supports the SOCKS protocol.

A typical SOCKS 4 request looks like this (each field is one byte):

Client request to SOCKS Server:

  • field 1: SOCKS version number, 1 byte (should be 0x04 for this version)
  • field 2: command code, 1 byte:
    • 0x02 = TCP/IP port assignment (binding)
  • field 3: port number, 2 bytes
  • field 4: IP address, 4 bytes
  • field 5: user ID, variable length string, terminated with a null byte (0x00). The field is intended to identify the user (see Ident)

Response from the Server to the SOCKS Client:

  • field 1: null byte
  • field 2: response code, 1 byte:
    • 0x5a = request granted
    • 0x5b = request rejected or invalid
    • 0x5c = The request failed because identd is not running (or is not accessible from the server)
    • 0x5d = The request failed because the client identd could not validate the user ID in the request
  • field 3: 2 arbitrary bytes, should be ignored
  • field 4: 4 arbitrary bytes, should be ignored

SOCKS 5 protocol

SOCKS 5 extends the SOCKS 4 model by adding UDP support, providing universal schemes strong authentication and extends addressing methods by adding support for domain names and IPv6 addresses. Initial installation The connection now consists of the following:

  • The client connects and sends a greeting that includes a list of supported authentication methods
  • The server chooses one of them (or sends a request failure response if none of the proposed methods is acceptable)
  • Depending on the chosen method, a number of messages may pass between the client and server
  • The client sends a connection request, similar to SOCKS 4
  • Server responds, similar to SOCKS 4

Authentication methods are numbered as follows:

  • 0x00 - no authentication required
  • 0x01 - GSSAPI
  • 0x02 - username/password
  • 0x03-0x7F - reserved by IANA
  • 0x80-0xFE - reserved for private use methods

Initial greeting from the client:

  • field 2: number of supported authentication methods, 1 byte
  • field 3: authentication method numbers, variable length, 1 byte for each supported method

The server reports its choice:

  • field 1: SOCKS version, 1 byte (0x05 for this version)
  • field 2: selected authentication method, 1 byte, or 0xFF if no acceptable method was proposed

Subsequent identification depends on the chosen method.

Customer Request:

  • field 1: SOCKS version number (should be 0x05 for this version)
  • field 2: command code, 1 byte:
    • 0x01 = setting up TCP/IP connection
    • 0x02 = TCP/IP port assignment (binding)
    • 0x03 = UDP port association
  • field 3: reserved byte, must be 0x00
  • field 4: address type, 1 byte:
    • 0x01 = IPv4 address
    • 0x03 = domain name
    • 0x04 = IPv6 address
  • field 5: address assignment
    • 4 bytes for IPv4 address
    • 16 bytes for IPv6 address
  • field 6: port number, 2 bytes

Server response:

  • field 1: SOCKS version number, 1 byte (0x05 for this version)
  • field 2: response code, 1 byte:
    • 0x00 = request granted
    • 0x01 = SOCKS server error
    • 0x02 = connection is prohibited by the ruleset
    • 0x03 = network unavailable
    • 0x04 = host unreachable
    • 0x05 = connection refused
    • 0x06 = TTL expired
    • 0x07 = Command not supported / protocol error
    • 0x08 = address type not supported
  • field 3: byte reserved, must be 0x00
  • field 4: subsequent address type, 1 byte:
    • 0x01 = IPv4 address
    • 0x03 = domain name
    • 0x04 = IPv6 address
  • field 5: address assignment
    • 4 bytes for IPv4 address
    • the first byte is the length of the name, followed by the domain name without a terminating null
    • 16 bytes for IPv6 address
  • field 6: port number, 2 bytes

Implementations

  • Sun Java System Web Proxy Server - caching proxy server for Solaris, Linux, Windows. Supports HTTPS, NSAPI I/O filters, dynamic reconfiguration and reverse proxy.
  • DeleGate is a multifunctional application level gateway and proxy server that runs on various platforms. In addition to SOCKS, it also supports HTTP(S), FTP, NNTP, SMTP, POP, IMAP, LDAP, Telnet, DNS and other protocols.
  • 3proxy - lightweight proxy server with SOCKS-proxy support
  • WinGate is a multi-protocol proxy server with SOCKS support for Windows.
  • OpenSSH allows you to dynamically create tunnels defined through a subset of the SOCKS protocol.

see also

  • Tor is an anonymous onion routing network with a SOCKS interface.

Links

  • RFC 1928 - SOCKS Protocol Version 5
  • RFC 1928 (Russian) - SOCKS 5 Protocol
  • RFC 1929 - Username/Password Authentication for SOCKS V5
  • RFC 1961 (English) - GSS-API Authentication Method for SOCKS Version 5
  • SOCKS: A protocol for TCP proxy across firewalls - SOCKS 4 protocol

Wikimedia Foundation.

2010.

    See what "SOCKS" is in other dictionaries: SOCKS

    See what "SOCKS" is in other dictionaries:- is an Internet protocol that allows client server applications to transparently use the services of a network firewall. SOCKS is an abbreviation for SOCKetS [ ]… … Wikipedia

    - Saltar a navegación, búsqueda SOCKS es un protocolo de Internet que permite a las aplicaciones Cliente servidor usar de manera transparente los servicios de un firewall de red. SOCKS es una abreviación de SOCKETS . Los clientes que hay detrás… … Wikipedia Español Network protocol that allows the client server applications

    transparently use services behind firewalls. SOCKS is short for SOCKetS (sockets). Clients behind a firewall needing access to... ... Wikipedia Socks

    transparently use services behind firewalls. SOCKS is short for SOCKetS (sockets). Clients behind a firewall needing access to... ... Wikipedia- im Briefing Room des Weißen Hauses Betty Currie und Socks … Deutsch Wikipedia