양말 프로토콜 들어오는 연결 수신

이러한 프록시 서버는 클라이언트의 외부 리소스 액세스 권한을 제어하고 요청을 서버로 전송합니다. SOCKS는 반대 방식으로도 사용될 수 있으며, 외부 클라이언트가 방화벽 뒤의 서버에 연결할 수 있도록 허용합니다.

HTTP 프록시 서버와 달리 SOCKS는 자체적으로 아무것도 추가하지 않고 클라이언트의 모든 데이터를 전송합니다. 즉, 최종 서버의 관점에서 SOCKS 프록시는 일반 클라이언트입니다. SOCKS는 보다 보편적입니다. 특정 애플리케이션 계층 프로토콜(OSI 모델의 계층 7)에 의존하지 않고 TCP/IP 표준인 계층 4 프로토콜을 기반으로 합니다. 그러나 HTTP 프록시는 데이터를 캐시하고 전송된 데이터의 내용을 보다 신중하게 필터링할 수 있습니다.

이 프로토콜은 David Koblas가 개발했습니다. 시스템 관리자 MIPS 컴퓨터 시스템. 그해 MIPS가 SGI(Silicon Graphics)의 일부가 된 후 Koblas는 Usenix 보안 심포지엄에서 SOCKS에 대해 강연했고 SOCKS는 공개적으로 사용 가능해졌습니다. 이 프로토콜은 NEC 시스템 연구소의 Ying-Da Lee에 의해 버전 4로 확장되었습니다.

SOCKS 4 프로토콜

SOCKS 4는 TELNET, FTP 등 TCP와 HTTP, WAIS, GOPHER 등 널리 사용되는 통신 프로토콜을 통해 실행되는 클라이언트-서버 애플리케이션에 대해 인증 없이 방화벽을 통과하도록 설계되었습니다. 기본적으로 SOCKS 서버는 SOCKS 프로토콜을 지원하는 방화벽으로 생각할 수 있습니다.

일반적인 SOCKS 4 요청은 다음과 같습니다(각 필드는 1바이트임).

SOCKS 서버에 대한 클라이언트 요청:

  • 필드 1: SOCKS 버전 번호, 1바이트(이 버전의 경우 0x04여야 함)
  • 필드 2: 명령 코드, 1바이트:
    • 0x02 = TCP/IP 포트 할당(바인딩)
  • 필드 3: 포트 번호, 2바이트
  • 필드 4: IP 주소, 4바이트
  • 필드 5: 사용자 ID, 가변 길이 문자열, 널 바이트(0x00)로 종료됩니다. 이 필드는 사용자를 식별하기 위한 것입니다(ID 참조).

SOCKS 클라이언트에 대한 서버 응답:

  • 필드 1: 널 바이트
  • 필드 2: 응답 코드, 1바이트:
    • 0x5a = 요청 승인됨
    • 0x5b = 요청이 거부되었거나 유효하지 않음
    • 0x5c = identd가 실행 중이 아니거나 서버에서 액세스할 수 없기 때문에 요청이 실패했습니다.
    • 0x5d = 클라이언트 identd가 요청에서 사용자 ID를 확인할 수 없어 요청이 실패했습니다.
  • 필드 3: 임의 바이트 2개, 무시해야 함
  • 필드 4: 임의 바이트 4개, 무시해야 함

SOCKS 5 프로토콜

SOCKS 5는 UDP에 대한 지원을 추가하여 SOCKS 4 모델을 확장하고 범용 회로를 제공합니다. 강력한 인증도메인 이름 및 IPv6 주소에 대한 지원을 추가하여 주소 지정 방법을 확장합니다. 이제 초기 통신 설정은 다음으로 구성됩니다.

  • 클라이언트는 지원되는 인증 방법 목록이 포함된 인사말을 연결하고 보냅니다.
  • 서버는 그 중 하나를 선택합니다(또는 제안된 방법 중 어느 것도 허용되지 않는 경우 요청 실패 응답을 보냅니다).
  • 선택한 방법에 따라 클라이언트와 서버 간에 여러 메시지가 전달될 수 있습니다.
  • 클라이언트는 SOCKS 4와 유사한 연결 요청을 보냅니다.
  • SOCKS 4와 유사하게 서버가 응답합니다.

인증 방법은 다음과 같이 번호가 매겨져 있습니다.

  • 0x00 - 인증이 필요하지 않습니다.
  • 0x01 - GSSAPI
  • 0x02 - 사용자 이름/비밀번호
  • 0x03-0x7F - IANA에 의해 예약됨
  • 0x80-0xFE - 개인 사용 방법용으로 예약됨

고객의 첫 인사말:

  • 필드 2: 지원되는 인증 방법 수, 1바이트
  • 필드 3: 인증 방법 번호, 가변 길이, 지원되는 각 방법당 1바이트

서버는 선택 사항을 보고합니다.

  • 필드 1: SOCKS 버전, 1바이트(이 버전의 경우 0x05)
  • 필드 2: 선택된 인증 방법, 1바이트 또는 허용 가능한 방법이 제안되지 않은 경우 0xFF

후속 식별은 선택한 방법에 따라 다릅니다.

손님 요구:

  • 필드 1: SOCKS 버전 번호(이 버전의 경우 0x05여야 함)
  • 필드 2: 명령 코드, 1바이트:
    • 0x01 = TCP/IP 연결 설정 중
    • 0x02 = TCP/IP 포트 할당(바인딩)
    • 0x03 = UDP 포트 연결
  • 필드 3: 예약된 바이트, 0x00이어야 함
  • 필드 4: 주소 유형, 1바이트:
    • 0x01 = IPv4 주소
    • 0x03 = 도메인 이름
    • 0x04 = IPv6 주소
  • 필드 5: 주소 할당
    • IPv4 주소의 경우 4바이트
    • IPv6 주소의 경우 16바이트
  • 필드 6: 포트 번호, 2바이트

서버 응답:

  • 필드 1: SOCKS 버전 번호, 1바이트(이 버전의 경우 0x05)
  • 필드 2: 응답 코드, 1바이트:
    • 0x00 = 요청 승인됨
    • 0x01 = SOCKS 서버 오류
    • 0x02 = 규칙 세트에 따라 연결이 금지되었습니다.
    • 0x03 = 네트워크를 사용할 수 없음
    • 0x04 = 호스트에 연결할 수 없음
    • 0x05 = 연결이 거부되었습니다.
    • 0x06 = TTL 만료됨
    • 0x07 = 명령이 지원되지 않음/프로토콜 오류
    • 0x08 = 지원되지 않는 주소 유형
  • 필드 3: 예약된 바이트, 0x00이어야 함
  • 필드 4: 후속 주소 유형, 1바이트:
    • 0x01 = IPv4 주소
    • 0x03 = 도메인 이름
    • 0x04 = IPv6 주소
  • 필드 5: 주소 할당
    • IPv4 주소의 경우 4바이트
    • 첫 번째 바이트는 이름의 길이이고, 그 뒤에는 null로 끝나지 않는 도메인 이름이 옵니다.
    • IPv6 주소의 경우 16바이트
  • 필드 6: 포트 번호, 2바이트

구현

  • Sun Java System 웹 프록시 서버 - Solaris, Linux, Windows용 캐싱 프록시 서버입니다. HTTPS, NSAPI I/O 필터, 동적 재구성 및 역방향 프록시를 지원합니다.
  • DeleGate는 다양한 플랫폼에서 실행되는 다기능 애플리케이션 수준 게이트웨이 및 프록시 서버입니다. SOCKS 외에도 HTTP(S), FTP, NNTP, SMTP, POP, IMAP, LDAP, Telnet, DNS 및 기타 프로토콜도 지원합니다.
  • 3proxy - SOCKS 프록시를 지원하는 경량 프록시 서버
  • WinGate는 Windows용 SOCKS를 지원하는 다중 프로토콜 프록시 서버입니다.
  • OpenSSH를 사용하면 SOCKS 프로토콜의 하위 집합을 통해 정의된 터널을 동적으로 생성할 수 있습니다.

또한보십시오

연결

  • RFC 1928 - SOCKS 프로토콜 버전 5
  • RFC 1928(러시아어) - SOCKS 5 프로토콜
  • RFC 1929 - SOCKS V5에 대한 사용자 이름/비밀번호 인증
  • RFC 1961(영어) - SOCKS 버전 5에 대한 GSS-API 인증 방법
  • SOCKS: 방화벽을 통과하는 TCP 프록시용 프로토콜 - SOCKS 4 프로토콜

위키미디어 재단. 2010.

다른 사전에 "SOCKS"가 무엇인지 확인하십시오.

    양말- 클라이언트 서버 응용 프로그램이 네트워크 방화벽 서비스를 투명하게 사용할 수 있도록 하는 인터넷 프로토콜입니다. SOCKS는 SOCKetS [ ]… … 위키피디아의 약자입니다.

    양말- SOCKS는 인터넷 프로토콜을 통해 애플리케이션을 허용하고 빨간색 방화벽 서비스를 투명하게 관리하는 데 사용됩니다. SOCKS는 SOCKETS의 약어입니다. Los clientes que hay detrás… … Wikipedia Español

    클라이언트를 허용하는 네트워크 프로토콜 서버 애플리케이션방화벽 뒤의 서비스를 투명하게 사용합니다. SOCKS는 SOCKetS(소켓)의 약자입니다. 액세스가 필요한 방화벽 뒤에 있는 클라이언트... ... Wikipedia

    양말- 메신저 브리핑 룸 des Weißen Hauses Betty Currie und Socks ... Deutsch Wikipedia

    양말- Sobre el pupitre de la Sala de Prensa de la Casa Blanca. 양말 (en español: Calcetines, marzo de 1989 20 de febrero de 2009) fue el gato de la familia del Presidente de los Estados Unidos Bill Clinton durante su presidencia. Fue la única mascota... ... Wikipedia Español

“SOCKetS”(소켓, 소켓)의 약자인 SOCKS는 TCP 및 UDP 도메인의 클라이언트/서버 응용 프로그램이 방화벽 서비스를 편리하고 안전하게 사용할 수 있도록 설계되었습니다. 이를 통해 사용자는 조직의 방화벽을 우회하고 인터넷에 있는 리소스에 액세스할 수 있습니다. SOCKS는 "애플리케이션 계층 중개자"입니다. 네트워크 수단(예: Telnet 및 Netscape 브라우저) 중앙 서버(프록시 서버)를 사용하여 사용자 컴퓨터를 대신하여 다른 중앙 컴퓨터와 통신합니다.


SOCKS는 수년 전 SGI의 Dave Koblas에 의해 개발되었으며 현재 이 코드는 인터넷에서 무료로 제공됩니다. 최초 출시 이후 이 코드는 몇 가지 주요 수정을 거쳤지만 각각은 완전히 무료로 배포되었습니다. SOCKS 버전 4는 다음을 기반으로 하는 클라이언트/서버 애플리케이션의 안전하지 않은 방화벽 통과 문제를 해결합니다. TCP 프로토콜텔넷, FTP 및 HTTP, WAIS(Wide Area Information Server) 및 GOPHER와 같은 널리 사용되는 정보 프로토콜을 포함합니다. SOCKS 버전 5, RFC 1928은 SOCKS 버전 4의 추가 확장입니다. 이는 UDP를 포함하고, 강력한 일반 인증 체계를 허용하도록 전체 프레임워크를 확장하고, 도메인 이름과 IP v6 주소를 포함하도록 주소 지정 시스템을 확장합니다.

현재 방화벽을 통과하는 들어오고 나가는 IP 멀티캐스트 메시지를 제어하는 ​​메커니즘을 만드는 것이 제안되었습니다. 이는 TCP 및 UDP 유니캐스트 사용자 트래픽에 의한 인증된 방화벽 전환의 기반을 만드는 기존 SOCKS V.5 프로토콜에 대한 확장을 정의함으로써 달성됩니다. 그러나 UDP가 지원된다는 사실로 인해 현재 버전 SOCKS V.5에는 확장성 문제와 기타 단점이 있으며(멀티캐스트로 이동하기 전에 반드시 해결해야 함) 확장은 UDP 기본 확장과 UDP 멀티캐스트 확장의 두 가지 방식으로 정의됩니다.


SOCKS의 기능은 표준 네트워크를 대체하는 것입니다. 시스템 호출응용 프로그램에는 특별 버전이 있습니다. 이러한 새로운 시스템 호출은 잘 알려진 포트(일반적으로 포트 1080/TCP)에 연결하여 SOCKS 프록시(애플리케이션의 사용자 또는 시스템 구성 파일에 의해 구성됨)와 통신합니다. SOCKS 서버와 연결을 설정한 후 애플리케이션은 사용자가 연결하려는 시스템 이름과 포트 번호를 서버에 보냅니다. SOCKS 서버는 실제로 원격 서버와 연결을 설정합니다. 중앙 컴퓨터, 애플리케이션과 원격 시스템 간에 데이터를 투명하게 전송합니다. 이 경우 사용자는 통신 채널에 SOCKS 서버가 있다는 사실조차 의심하지 않습니다.


SOCKS 사용의 어려움은 네트워크 시스템 호출을 SOCKS 버전으로 교체하는 작업을 누군가가 수행해야 한다는 것입니다(이 프로세스를 일반적으로 애플리케이션 "SOCKS화"라고 함). 다행히도 대부분의 평범한 네트워크 애플리케이션(Telnet, FTP, Finger, whois)은 이미 SOCKS 인증을 받았으며 많은 공급업체가 상용 애플리케이션에 SOCKS 지원을 포함하고 있습니다. 또한 SOCKS V.5에는 공유 라이브러리에 이러한 루틴이 포함되어 있습니다. 일부 시스템(Solaris 시스템 등)에서는 라이브러리 검색 문자열( 환경 변수 Solaris 시스템의 경우 LD__LIBRARY_PATH).

인터넷에서의 익명성은 새로운 주제가 아닙니다. 그리고 아마도 컴퓨터에 A4Proxy, SocksChain과 같은 프로그램을 설치했을 것입니다.
등등. 개인적으로 저는 프록시 작업을 위해 별도의 프로그램이 필요한 것을 좋아하지 않습니다. 첫째로
작업 표시줄이나 트레이 아이콘에 창이 너무 많으면 보기 흉합니다. 둘째, 이러한 프로그램에는 크랙이 필요하며,
너무 게으른 나머지 볼 수가 없습니다 :) 그래서 SOCKS5 서버를 지원하는 클래스를 작성했고 이제 사용할 수 있습니다.
귀하의 일부 프로그램에서. 이제 나는 모든 사람에게 방법을 알려주고 싶습니다.

프록시를 통해 액세스할 수 있는 서버와 프로토콜은 다음에 따라 다릅니다.
이 프록시의 유형, 즉 우리가 액세스하는 프로토콜입니다. 프록시에는 여러 유형이 있습니다.
HTTP 프록시, SOCKS4, SOCKS5, SSL CONNECT 등 HTTP 프록시는 가장 일반적이고 인터넷에서 가장 쉽게 찾을 수 있지만 HTTP에서만 작동합니다.
클라이언트의 주소를 요청 헤더에 삽입할 수 있습니다.
익명이 아닙니다. SOCKS 프로토콜은 애플리케이션 프로토콜이 아닌 캡슐화한다는 점에서 가장 주목할 만합니다.
전송 계층, 즉 TCP/IP 및 UDP/IP. 이러한 프로토콜만이 인터넷 작업을 가능하게 하기 때문에,
SOCKS를 통해 동일한 SOCKS를 포함한 모든 서버와 작업할 수 있습니다.
따라서 SOCKS 서버 체인을 구성합니다. 같은 이유로 모든 SOCKS 서버는 익명입니다. 불가능합니다.
TCP/IP 및 UDP/IP 수준에서 상위 작업을 방해하지 않고 추가 정보를 전송합니다.
규약.

우리는 SOCKS5 프로토콜에 중점을 둘 것입니다. 그 설명은
. SOCKS5의 경우 표준 포트는 1080이지만
아무도 표준에 많은 관심을 기울이지 않습니다. 각 SOCKS 연결은 인증 단계를 거치며, 필요한 경우 클라이언트는
명령을 보냅니다. 명령은 다음 세 가지 중 하나일 수 있습니다.
CONNECT - 나가는 TCP 연결 지정된 주소. 이 명령을 사용하는 방법을 살펴보겠습니다.
가장 자주 필요하기 때문에 더 자세히 설명합니다. BIND - 포트를 열고(서버가 포트를 선택하고 주소와 포트를 클라이언트에 보냅니다) TCP 연결을 수락합니다.
서버는 누가 연결할지 알아야 할 수도 있습니다. 이 경우 이 정보를 전달해야 합니다. UDP ASSOCIATE - UDP 포트를 엽니다(서버가 포트를 선택함). 최종 목적의 데이터
호스트와 데이터도 UDP를 통해 이동합니다. SOCKS5의 데이터는 HTTP, SMTP, POP3 등과 같이 텍스트 형식이 아닌 바이너리 형식으로 전송됩니다.

프로토콜 설명

서버에 연결되면 클라이언트는 프로토콜 버전을 나타내는 패킷을 보내고 지원됩니다.
인증 방법. 이 패키지의 형식은 다음과 같습니다.

바이트 버전;
BYTE n방법;
바이트 방법

버전은 5여야 합니다. 각 방법 요소는 인증 방법뿐만 아니라 데이터 암호화 방법도 정의합니다.
사용되는 경우. 서버는 다음 방법 중 하나를 선택합니다. 원하는 수의 방법을 지정할 수 있지만 서버에 인증이 필요하지 않으면 방법이 없습니다.
0x00 이외의 경우(인증이나 암호화를 모두 사용하지 않음)는 필요하지 않습니다. 이에 대한 응답으로 서버는 다음 내용이 포함된 패킷을 보냅니다.

바이트 버전
바이트 방식

여기서 method는 서버에서 선택한 방법이거나 0xFF입니다(제안된 방법 중 어느 것도 지원되지 않음). 메소드가 0x00이면 즉시 명령을 보낼 수 있습니다.

명령 패킷의 형식은 다음과 같습니다.

바이트 버전; // 5
바이트 명령 ; // 1 — 연결
BYTE 예약됨; // 0

바이트 주소;
워드 포트; // 네트워크 순서의 바이트, 즉 htons(Port);

도메인 이름을 사용하는 경우 길이 바이트가 먼저 오고 마지막에 null이 없는 문자열이 옵니다.

서버가 응답을 보냅니다.

바이트 버전; // 5
바이트 담당자 ; // 0 — 확인
BYTE 예약됨; // 0
BYTE A유형; // 1 - IPv4; 3 - 도메인 이름; 4 - IPv6
바이트 주소;
워드 포트;

여기서 주소와 포트는 주소와 포트입니다. 호스트에게 표시됨. 원칙적으로 도메인이 아닌 IP 주소가 반환됩니다.
이름. 이 주소는 우리가 서버에 액세스하는 주소와 다를 수 있습니다. 특히 서버가
의도된 목적, 즉 로컬 영역에서 인터넷으로 나가는 데 사용됩니다. Rep가 0이 아니면(예: 오류) 연결을 닫습니다.
그렇지 않으면 우리는 호스트와 협력합니다. 암호화를 사용하지 않으므로 일반 연결처럼 단순히 데이터를 보내고 받습니다. 당사자 중 하나가 양말 서버에 대한 연결을 닫으면 즉시 다른 쪽 연결도 닫힙니다.
옆. 하나의 양말 연결은 하나의 TCP 연결을 캡슐화하거나 하나를 설정하려고 시도합니다.
따라서 익명 포트 스캐닝을 위해 양말을 사용한다면 이것은
절차는 반나절이 걸릴 수 있습니다.

코딩

양말은 TCP를 캡슐화하므로 양말 연결 클래스를 다음에서 파생시키는 것이 합리적입니다.
소켓 클래스이지만 MFC의 CSocket은 적합하지 않습니다. 그 사람은 모든 방법을 다 갖고 있어
가상이 아닙니다. 우리만의 소켓 클래스를 작성하고 이를 CTSocket이라고 부르자.

#포함하다

클래스 CTSocket
{
공공의:





가상 무효 Close();
가상 서명되지 않은 long GetHost(); // 주소를 알아보세요. 이것이 필요할 수도 있습니다.

사적인:
소켓 양말;
};

누구나 이 클래스의 구현을 직접 작성할 수 있으므로(RTFM MSDN 방법을 모르는 사람) 저는 작성하지 않겠습니다.
고려하다. 이제 양말 연결 클래스를 작성해 보겠습니다. 가장 필요한 세트만 지원합니다.
기능: CONNECT 명령만 지원되며, 인증 및 SOCKS 서버는 지원되지 않습니다.
도메인 이름이 아닌 IP 주소로만 지정됩니다. 한 기사에 더 많은 내용을 담을 수 없습니다.

클래스 CSocksSocket: 공개 CTSocket
{
공공의:
가상 BOOL CreateSocket();
virtual BOOL Connect(서명되지 않은 긴 IP, 서명되지 않은 짧은 포트);
virtual BOOL Connect(LPCSTR 이름, 서명되지 않은 짧은 포트);
virtual int Send(const char* str, int len);
virtual int Recv(char* buf, int max);
가상 BOOL 닫기();
가상 서명되지 않은 long GetHost();

CTSocket* pSocket;
부호 없는 긴 양말_ip;
서명되지 않은 짧은 양말_포트;

사적인:
문자 버퍼; // 이 사이즈면 확실히 충분해요
부호 없는 긴 l_ip; // 함수가 반환한 주소
호스트 가져오기()

};

// 구현
BOOL CSocksSocket::CreateSocket()
{
if (!pSocket->CreateSocket())은 FALSE를 반환합니다.
if (!pSocket->Connect(socks_ip, Socks_port))는 FALSE를 반환합니다.
버퍼 = 5; //버전
버퍼 = 1; // 메소드 1개
버퍼 = 0; //인증 없음
pSocket->Send(버퍼, 3);
int n = pSocket->Recv(버퍼, 2);
(n != 2)인 경우 FALSE를 반환합니다.
방법 0 지원되지 않음
TRUE를 반환합니다.
}

BOOL CSocksSocket::Connect(서명되지 않은 긴 IP, 서명되지 않은 짧은 포트)
{
버퍼 = 5; //버전
버퍼 = 1; // 연결하다
버퍼 = 0; //예약된
버퍼 = 1; //IPv4
*((unsigned long*)(버퍼 + 4)) = ip;
*((unsigned short*)(버퍼 + 8)) = 포트;
pSocket->Send(버퍼, 10);
int n = pSocket->Recv(버퍼, 10);
(n != 10)이면 FALSE를 반환합니다.
if (버퍼 != 0) FALSE를 반환합니다. //
연결할 수 없습니다

TRUE를 반환합니다.
}

BOOL CSocksSocket::Connect(LPCSTR 이름, 서명되지 않은 짧은 포트)
{
버퍼 = 5;
버퍼 = 1;
버퍼 = 0;
버퍼 = 3; // 도메인 이름
int m = strlen(이름);
버퍼 = m; //
길이 바이트
memcpy(버퍼+5, 이름, m); //
null 종료 없이 문자열 복사
*((unsigned short*)(버퍼 + 5 + m)) = 포트;
pSocket->Send(버퍼, m + 7);
int n = pSocket->Recv(버퍼, 10);
(n != 10)이면 FALSE를 반환합니다.
if (버퍼 != 0) FALSE를 반환합니다.
if (버퍼 != 1) FALSE를 반환합니다. //
우리는 그들이 우리에게 다른 것이 아닌 IP를 말하도록 요구할 것입니다.
l_ip = *((unsigned long*)(버퍼 + 4));
TRUE를 반환합니다.
}

int CSocksSocket::Send(const char* str, int len)
{
return pSocket->Send(str, len);
}

int CSocksSocket::Recv(char* buf, int max)
{
pScoket->Recv(buf, max)를 반환합니다.
}

무효 CSocksSocket::Close()
{
pSocket->닫기();
}

서명되지 않은 긴 CSocksSocket::GetHost()
{
l_ip를 반환;
}

//자, 이제 테스트 프로그램
무효 메인()
{
WSADATA wsadata;
CTSocket tsock;
CSocksSocket ssock(&tsock);

WSAStartup(MAKEWORD(2,2), &wsadata);

ssock.socks_ip = inet_addr("10.10.10.10"); // 여기에 원하는 주소를 입력하세요
ssock.socks_port = 1080; //
여기에 포트를 입력하세요

if (!ssock.CreateSocket()) 반환; // 양말에 연결할 수 없습니다
// 또는 인증이 필요합니다.
if (!ssock.Connect("www.mail.ru", htons(80))) return; //
www.mail.ru
//접근불가
LPSTR q = "HEAD / HTTP/1.1\xD\xAHost: www.mail.ru:80\xD\xAUser-Agent: xakep\xD\xA\xD\xA";
ssock.Send(q, strlen(q));

char buf;
int n = ssock.Recv(buf, 1000);
버프[n] = 0;
printf("%s", buf);

프록시로 작업할 때 가능한 문제를 피하고 목표를 달성하려면 작업에 적합한 프록시 유형을 선택하는 것이 매우 중요합니다. 가장 일반적으로 사용되는 것은 HTTP 프록시와 Socks5 프록시입니다. 이들 사이의 차이점은 익명성 정도, 사용된 프로토콜, 프록시로 작업할 때 사용되는 데이터 전송 방법 및 일부 환경에 있습니다. 추가 기능. 각 프록시 유형을 개별적으로 살펴보겠습니다.

HTTP 프록시의 특징

HTTP 프록시부터 시작해 보겠습니다. 작업하는 동안 사이트 방문, 파일 다운로드 및 전송, 이 프로토콜을 사용하여 프록시를 통해 연결하는 일부 프로그램과 작업할 때 사용되는 HTTP 프로토콜을 사용합니다. HTTP 프록시 서버로 작업할 때 생성된 요청은 직접 전송되지 않지만 프록시 서버를 중개자로 사용하여 대신 요청을 보냅니다.

또한 HTTP 프록시 프로토콜에서는 저장된 파일을 사용하여 페이지 로딩 속도를 높이는 캐싱이 가능하며 네트워크 트래픽 모니터링 및 필터링, 속도 제한 설정, 원치 않는 리소스 차단, 로그 저장을 통한 통계 수집 등이 가능합니다.

이 프로토콜의 프록시는 익명성 정도가 다릅니다. 눈에 띄다 다음 유형익명성을 위한 HTTP 프록시:

실제 IP 주소를 가리지 않고 프록시 서버가 리소스에 액세스하는 데 사용된다는 사실을 숨기지 않는 투명 프록시입니다. 이러한 프록시는 주로 사용자를 다른 프록시 서버로 리디렉션하는 데 거의 사용되지 않습니다.

익명 프록시. 프록시가 사용된다는 정보를 전송하지만, 귀하의 IP 주소는 마스킹되고 다른 IP 주소로 대체되어 안정적인 수준의 보안을 제공합니다.

엘리트 프록시. 프록시 사용을 숨기고 IP 주소를 안정적으로 마스킹하므로 HTTP 프록시 중에서 가장 안전합니다. 액세스하려는 서버는 프록시 서버를 사용하지 않고 직접 연결된다고 가정합니다.

별도로, 다음을 사용하는 HTTPS 프록시를 강조할 가치가 있습니다. SSL 프로토콜. 이는 보안 연결을 사용하는 HTTP 프로토콜의 하위 유형입니다. 이러한 프록시에 의해 전송되는 네트워크 트래픽은 안전하게 암호화되어 최고 수준의 익명성을 보장합니다. 일반적으로 이러한 프록시는 보안을 보장하는 데 사용됩니다. 은행 네트워크, 상업 조직에서 안전한 기업 네트워크를 생성하고 보안이 필요한 기타 연결에서. 다른 기능은 HTTP 프로토콜과 동일합니다.

Socks5 프록시의 특징

사용자들에게 인기 있는 또 다른 프로토콜은 Socks5입니다. 이 프로토콜을 사용하는 프록시 서버는 다음을 허용하므로 처음에는 익명입니다. 네트워크 트래픽 HTTP 헤더를 공개하지 않고 순수한 형태로. 따라서 액세스하려는 서버는 귀하가 프록시 서버를 사용하고 있다는 사실을 알지 못하며 귀하의 IP 주소를 수신하지 않습니다.

Socks5 프록시는 다음을 지원합니다. 네트워크 프로토콜: HTTP, HTTPS, FTP 및 해당 기능: 캐싱, SSL 연결,입증. 또한 Socks5 프로토콜 프록시는 UDP 및 TPC 연결을 사용하여 적용 범위를 확장하고 최신 프록시 서버 중 가장 기능적으로 만듭니다. 처음에 Socks5 프로토콜은 소프트웨어와 함께 작동하도록 고안되었습니다. 이러한 이유로 대부분의 프로그램은 프록시를 통한 연결에 이 프로토콜을 지원합니다. Socks5 프록시 서버에는 프록시 서버 체인을 구축할 수 있는 멋진 기능도 있는데, 이는 인터넷에서 작업할 때 일부 문제를 해결하는 데 유용합니다.

HTTP와 Socks5 프록시를 비교하는 경우 후자를 사용하는 것이 좋습니다. 익명성이 높기 때문에 더 많은 기능을 지원하고 프록시를 통한 연결을 지원하는 모든 사이트 및 프로그램과도 작동합니다. 개인 계정으로 주문하시면 저희 웹사이트를 방문하실 수 있습니다.

얼마 전 나는 내 자신의 필요에 맞게, 미래에 사용할 수 있고 크기도 최소화할 수 있는 프록시 서버를 구현하려고 했습니다. 나에게 자연스러운 선택은 어셈블러를 사용한 구현이었습니다. 이 프로그램은 작고 편리해서 앞으로는 자주 사용하게 되었습니다. 그러나 몇 년이 지난 지금, 나는 하나의 프로토콜인 SOCKS4의 가장 간단한 구현을 보여주고 싶습니다. 이 프로토콜은 방화벽 뒤의 로컬 네트워크에 있는 클라이언트가 외부 네트워크에 액세스할 수 있도록 만들어졌습니다. 동시에, 이 경우 클라이언트 요청을 제어하는 ​​것이 가능합니다 :) 구현할 때 가장 먼저 해야 할 일은 이 프로토콜을 설명하는 문서를 읽는 것입니다. "파일로 훼손." 따라서 문서는 다음과 같습니다.

이제 설명을 마쳤으니 시작해 보겠습니다. 프록시 서버의 역할은 특정 형식의 클라이언트 요청을 수락하고 소켓을 생성하여 클라이언트가 요청한 주소에 연결한 다음 서버가 두 소켓을 닫을 때까지 두 소켓 간의 데이터 교환을 보장하는 것입니다. 또는 클라이언트. 구현을 시작해 보겠습니다.

프로그램에 사용되는 매크로 및 데이터 구조

include.inc라는 포함 파일을 만들어 보겠습니다. 안에 이 파일 Windows 프로그램을 작성할 때 SOCKS4 작업을 위한 표준 매크로 + 구조를 넣어 보겠습니다. 여기서는 모든 매크로를 제공하지 않고 주요 문제를 해결하는 데 필요한 설명과 기능만 제공하고 첨부 파일에서 찾을 수 있는 모든 항목을 제공합니다. 소스 코드.
; SOCKS4 – 연결을 요청할 때 클라이언트가 사용하는 구조입니다. 지정된 서버(DSTIP)/포트(DSTPORT)로 CONNECT_SOCK4 Struc VN Db ? CD DB? DSTPORT Dw? DSTIP DD? NULL DB? CONNECT_SOCK4 종료 ; SOCKS4 - 연결에 대한 프록시 서버 응답입니다. RESPONSE_SOCK4 구조 VN DB? CD DB? DSTPORT Dw? DSTIP DD? RESPONSE_SOCK4 종료

대체로 CONNECT_SOCK4 및 RESPONSE_SOCK4 구조는 승인 없이 프로토콜을 구현하므로 다르지 않습니다. 하지만 나중에 개선을 위해 쉽게 변경할 수 있도록 별도로 남겨두기로 결정했습니다. 구조 자체의 VN 변수에는 프로토콜 버전이 표시됩니다. 우리의 경우 SOCKS5의 경우 항상 4가 있어야 하며 이 변수에는 5가 포함됩니다(프로토콜은 기본적으로 유사합니다). CD 변수는 클라이언트가 요청한 주소에 대한 프록시 서버 요청 결과를 클라이언트에 반환하는 데 사용됩니다(90 - 연결 성공 / 91 - 연결 실패).
우리 프로그램에는 실제로 세 단계가 있습니다.
* 먼저 소켓을 초기화하고 소켓에서 클라이언트 요청을 수신한 후 처리 스레드를 생성합니다.
* 두 번째 단계는 클라이언트 요청 분석으로, 클라이언트가 요청한 서버에 소켓을 생성하고 연결하려는 시도입니다.
* 그리고 마지막 세 번째 단계는 클라이언트 소켓과 우리가 생성하고 연결한 소켓 사이에서 요청된 주소로 데이터를 보내는 것입니다.

첫 번째 단계 구현, 프로그램 초기화:

; 주요 절차는 WinMain 프로그램 Proc LOCAL ThreadId, hServSock:DWORD LOCAL 호스트 이름 :BYTE LOCAL _wsa:WSADATA LOCAL _our:sockaddr_in 의 시작 절차입니다. 소켓 작업을 위한 라이브러리를 시작하면서 버전 1.1의 기능을 사용합니다. 최소 호출로 요청합시다 WSAStartup, 0101h, ADDR _wsa .if eax == 0 ; 우리는 주소를 가져와서 서버 소켓을 초기화하기 위한 구조를 준비합니다. Invoke gethostname, ADDR 호스트 이름, 256 Invoke gethostbyname, ADDR 호스트 이름 .if eax == 0 호출 inet_addr, ADDR 호스트 이름 .else mov eax, mov eax, mov eax, .endif mov _our.sin_addr, eax 호출 inet_ntoa, eax mov _our.sin_family, AF_INET mov _our.sin_addr.S_un.S_addr, INADDR_ANY xor eax, eax ; 들어오는 메시지를 수신하려는 포트를 입력하십시오. mov ax, SOCKS_PORT Invoke htons, eax mov _our.sin_port, ax Invoke Socket, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET ; 생성된 서버 소켓을 저장합니다. mov hServSock, eax ; 서버 소켓을 주소에 바인딩하고 필요한 포트 호출을 호출합니다. 대기할 소켓을 시작하여 Listen, hServSock, SOMAXCONN .repeat를 호출합니다. 클라이언트가 도착했습니다. 들어오는 클라이언트 호출이 포함된 소켓을 받습니다. hServSock, NULL, NULL .until eax != INVALID_SOCKET; 현재 클라이언트가 처리될 스레드를 생성합니다. xchg eax, ebx inform CreateThread, NULL, NULL, ADDR SocketThread, ebx, NULL, ADDR ThreadId ; 클라이언트가 jmp @B .endif .endif가 closesocket을 호출하고, hServSock .endif가 ExitProcess를 호출하고, 0 WinMain Endp가 호출될 때까지 기다리기 위해 떠납니다.
이것이 우리의 첫 번째 절차입니다. 코드에 대해 최대한 이해할 수 있도록 주석을 달려고 노력했지만, 여전히 명확하지 않은 부분이 있으면 저나 MSDN에 문의해 주세요. 기본적으로 모든 코드는 MASM 및 WinAPI 구문을 사용하여 작성됩니다. 위 함수의 결과는 다음 중 하나에서 작동하는 소켓이어야 합니다. 네트워크 주소너의 차 ( 현지 주소, 또는 외부 주소실제 IP가 있는 경우) + 클라이언트 연결을 기반으로 이 함수는 들어오는 클라이언트와 작업하는 데 사용되는 별도의 스레드를 생성합니다. 이제 다음으로 넘어가자...

두 번째 단계, 고객의 요청 분석

두 번째 단계에서 수행해야 할 작업은 CONNECT_SOCK4 구조를 수락하고, 소켓을 생성하고, 연결을 시도하고, 클라이언트에 응답을 보내는 것입니다. 구현:

SocketThread Proc sock:DWORD LOCAL lpMem, _csock, ThreadId, dAmount:DWORD LOCAL 원격:sockaddr_in LOCAL wrFds, rdFds:fd_set LOCAL hResp:RESPONSE_SOCK4 ; 소켓에서 데이터를 읽을 준비를 하면 FdZero 호출, ADDR rdFds 호출 FdSet, sock, ADDR rdFds 호출 select, NULL, ADDR rdFds, NULL, NULL, NULL ; 우리는 읽기를 기다리는 데이터의 크기를 얻습니다. 호출 ioctlsocket, sock, FIONREAD, ADDR dAmount ; 데이터 mov lpMem, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, dAmount) 에 대한 메모리를 예약합니다. 소켓 호출에서 요청 데이터 읽기, recv, sock, lpMem, dAmount, 0 ; 요청은 lea edi, hResp mov esi, lpMem ; Esi에는 사용자 요청이 포함되어 있습니다. (여기서는) SOCKS4 버전만 처리합니다. 원칙적으로 SOCKS5는 여기에서 처리될 수 있지만 나중에 처리될 것입니다... Esi 가정: Ptr CONNECT_SOCK4 Edi 가정: Ptr RESPONSE_SOCK4 .if .VN == 4 ; SOX 4 프로토콜 구현 .if .CD == 1 호출 소켓, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET mov _csock, eax ; 클라이언트가 연결하려는 원격 호스트의 데이터를 가져옵니다 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에는 사용자 mov .VN, 0 mov .DSTPORT, cx mov .DSTIP, edx에 대한 답변이 포함되어 있습니다. 우리는 연결을 시도하고 있습니다 원격 서버연결 호출, _csock, ADDR 원격, SIZEOF 원격 .if !eax ; mov .CD, 90을 연결했다는 응답을 준비 중입니다. 연결 시도 호출 send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 의 결과가 포함된 응답을 클라이언트에 보냅니다. 우리는 서버에 대한 정보로 구조를 형성합니다. 연결된 클라이언트 소켓; - 여기서 서버란 클라이언트에 연결된 소켓을 의미합니다. 요청을 보낸 사람 - 클라이언트란 서버에 연결된 소켓을 의미합니다. 클라이언트가 요청한 데이터 mov ebx, @Result(LocalAlloc, LMEM_FIXED or LMEM_ZEROINIT, SIZEOF THREAD_DATA) Ebx 가정: Ptr THREAD_DATA mov eax, _csock mov .Server, eax mov eax, sock mov .Client, eax Ebx 가정: Nothing ; 소켓 처리 스레드(클라이언트에서 읽고 서버 소켓으로 전송)를 시작하여 CreateThread, NULL, NULL, ADDR ClientSock, ebx, NULL, ADDR ThreadId .else를 호출합니다. 연결이 실패하면 클라이언트 소켓을 닫고 closesocket, _csock을 호출합니다. 연결 오류 mov , 91 이 발생했다고 말합니다. 연결 시도 호출 send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 .endif .endif .endif .endif Assume Edi: Nothing Assume Esi: Nothing 의 결과가 포함된 응답을 클라이언트에 보냅니다. 요청에 할당된 메모리를 해제하면 LocalFree, lpMem ret SocketThread Endp가 호출됩니다.
이 절차의 결과는 연결된 소켓뿐 아니라 두 소켓 간의 데이터 교환을 구현하는 생성된 스레드입니다. 간단 해. 프로그래머의 삶을 더 쉽게 만들기 위해 MASM에 도입된 구조 내에서 여러 주소 지정 지점이 여기에서 사용된다는 점만 명확히 하면 됩니다. 첫 번째 포인트는 "Assume" 매크로입니다.
Assume Esi: Ptr CONNECT_SOCK4 행은 컴파일러에게 이 레지스터(Esi)에 CONNECT_SOCK4 구조의 주소가 포함되어 있음을 알려주며, 이는 이 구조 내의 변수에 액세스하는 것을 더욱 단순화합니다. Esi:Nothing이 바인딩을 취소한다고 가정합니다. 더 잘 이해하기 위해 몇 가지 주소 지정 옵션을 나열하면 더 쉬울 수 있습니다.
Esi:Ptr CONNECT_SOCK4 mov al, .VN ; 변수 VN 구조 mov al, .CD 의 바이트 값을 AL에 배치합니다. 가변 CD mov 축을 AL에 배치합니다. .DST포트 ; AX Assume Esi:Nothing에 DSTPORT 변수를 배치합니다.
또는
이동 알, ; AL mov al, ;에 VN 변수의 바이트 값을 배치합니다. 변수 CD mov ax, ; DSTPORT 변수를 AX에 배치합니다.
또는
mov al, 바이트 ptr ; AL mov al, byte ptr에 변수 VN을 배치합니다. AL mov ax, word ptr에 CD 변수를 배치합니다. DSTPORT 변수를 AX에 배치합니다.

저와 마찬가지로 여러분에게도 첫 번째 옵션을 사용하는 것이 더 빠르고 편리하며 명확하다는 것이 분명하다고 생각합니다. 꼭 연락해야 하는 경우에도 가변 구조– 두 번째 옵션도 존재할 권리가 있습니다. 주소의 데이터가 구조화되지 않은 경우에는 세 번째 옵션을 사용하는 것이 더 좋다고 생각합니다. 그러나 아시다시피 모든 탐보프 늑대는 고유한 맛과 색깔을 가지고 있습니다. 귀하에게 가장 편리한 방법을 사용하십시오.
명확히 할 가치가 있는 또 하나의 요점이 있습니다. 결과 매크로. 이 매크로는 WinAPI 함수를 한 줄로 호출하고 실행 결과를 레지스터나 메모리에 쓸 수 있도록 작성되었습니다. 따라서 다음 줄은 다음과 같습니다.
mov lpMem, @Result(LocalAlloc, LMEM_FIXED 또는 LMEM_ZEROINIT, dAmount)
먼저 다음과 같이 호출합니다.
LocalAlloc, LMEM_FIXED 또는 LMEM_ZEROINIT, dAmount 호출
그리고 실행 후 이 전화실행 결과(Eax)는 lpMem 변수에 저장됩니다. 이 특별한 경우에는 메모리가 할당되고 우리에게 할당된 영역이 있는 주소가 변수에 기록됩니다.

3단계, 데이터 전송

이로써 가장 어려운 두 단계가 완료되었습니다. 클라이언트가 도착했고 우리는 그를 원격 서버에 연결했고 이제 가장 간단한 "원숭이" 작업을 할 시간이었습니다. 두 소켓 간에 데이터를 전송합니다. 빠르고 쉽게 해보자:
; 클라이언트 소켓에서 읽어 서버 소켓으로 보내는 스트림.... ClientSock Proc Param:DWORD LOCAL sserver, sclient:DWORD LOCAL rdFds:fd_set LOCAL dAmount, lpBuf: DWORD ; Param에는 서버와 클라이언트 소켓에 대한 정보가 있습니다. 로컬 변수로 전송 mov ebx, Param Ebx 가정: Ptr THREAD_DATA mov eax, .Server mov sserver, eax mov eax, .Client mov sclient, eax Ebx 가정: 없음 ; 메모리 확보를 잊지 마세요. LocalFree, Param @@ 호출: FdZero 호출, ADDR rdFds 호출 FdSet, sserver, ADDR rdFds 호출 FdSet, sclient, ADDR rdFds 호출 select, NULL, ADDR rdFds, NULL, NULL, NULL ; 읽을 데이터가 있는지 확인하세요.if eax == SOCKET_ERROR || eax == 0 ; 데이터 없음 - 종료 jmp @F .endif ; 클라이언트에 전달해야 하는 서버의 데이터가 있습니까? FdIsSet, sserver, ADDR rdFds .if eax 호출; 읽기를 기다리는 데이터의 크기를 얻습니다. ioctlsocket, sserver, FIONREAD, ADDR dAmount를 호출합니다. 데이터를 위한 메모리 예약 mov lpBuf, @Result(LocalAlloc, LMEM_FIXED 또는 LMEM_ZEROINIT, dAmount) inform recv, sserver, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif 호출 send, sclient, lpBuf, eax, 0 호출 LocalFree, lpBuf .endif ; 서버 소켓으로 보낼 클라이언트의 데이터가 있습니까? FdIsSet, sclient, ADDR rdFds .if eax를 호출합니다. 우리는 읽기를 기다리는 데이터의 크기를 얻습니다. 호출 ioctlsocket, sclient, FIONREAD, ADDR dAmount ; 데이터를 위한 메모리 예약 mov lpBuf, @Result(LocalAlloc, LMEM_FIXED 또는 LMEM_ZEROINIT, dAmount) receive recv, sclient, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif 호출 send, sserver, lpBuf, eax, 0 호출 LocalFree, lpBuf .endif ; 새로운 사이클로 가봅시다 jmp @B @@: ; 소켓을 닫고 closesocket을 호출하고, sserver가 closesocket을 호출하고, sclient를 호출합니다. 호출 스레드 종료 ExitThread, 0 ClientSock Endp
처음에 이 프로시저는 스트림에 전달된 구조에서 내부 변수를 초기화하여 사용하기 더 편리하게 만듭니다. 그런 다음 루프에서 소켓에서 읽을 데이터가 있는지 확인한 다음 두 개의 코드 조각(실제로 복사하여 붙여넣기, 여기서는 더 명확하기 때문에 함수를 제거하고 최적화하는 데 신경 쓰지 않았습니다)을 확인합니다. ) 한 소켓에서 읽고 두 번째 소켓으로 보냅니다.
그게 다야, 만세! 컴파일하고 시도해 보겠습니다. 원칙적으로 가장 좋은 옵션은 FireFox입니다. 연결 설정에서 SOCKS4 프록시 서버를 사용해야 한다고 지정합니다. 주소와 해당 주소가 위치한 포트를 표시합니다. 그런 다음 설정을 저장하고 프록시를 통해 3.5KB 크기의 인터넷을 즐깁니다.))) 예, 명확히 하겠습니다. 컴파일을 위해서는 패키지를 설치해야 합니다.



질문이 있으신가요?

오타 신고

편집자에게 전송될 텍스트: