At skrive en simpel SOCKS4-server i Assembler-sprog. Hvad er en SOCKS-server, og hvorfor er den nødvendig?

Artiklen er afsat til SOCKS5-protokollen - dens interne struktur, praktisk ansøgning, samt SOCKS-servere og -klienter, der er tilgængelige for Unix-platformen

[Valentin Sinitsyn (val AT linuxcenter DOT ru)]

"Undskyld, Plys," sagde SAVA. - Tigger tyggede alle ledninger fra mailserveren, og posten kom ikke frem i lang tid...
"Tråde," tænkte Plys vredt. - Strik sokker af disse ledninger.

Andrey Shcherbakov "9600 baud og det er det, det er det, det er det ..."

I denne artikel vil vi tale om SOCKS-protokollen[ fodnote: "sokker" - engelsk. "sokker", "strømper"]. Med dens hjælp kan du løse det meste forskellige opgaver: organisere sikker adgang til tjenester placeret bagved firewall(firewall), skjul din sande IP-adresse, mens du arbejder med uvenlige netværksressourcer, eller implementer en universel proxyserver, der understøtter alle protokoller anvendelsesniveau(HTTP, FTP, POP3/SMTP, ICQ osv.). Desværre, på trods af SOCKS' enkelhed og rigdom, er mange systemadministratorer ikke særligt fortrolige med det og har ingen idé om, hvordan det kan være nyttigt. Jeg vil gerne håbe, at efter at have læst dette materiale, vil den ufortjent glemte protokol indtage sin retmæssige plads i deres arsenal. Lad os foretage en reservation med det samme: alle efterfølgende præsentationer vil referere til den femte version af SOCKS, SOCKS5. Den tidligere, fjerde version (SOCKS4) er stadig i omløb på internettet, men dens muligheder er mere begrænsede.

Navnet på protokollen har i øvrigt intet at gøre med de trikotagevarer, der er nævnt i epigrafen og er en simpel forkortelse for "SOCK-et-S" - "sockets", eller i en mere velkendt oversættelse til en computerspecialists øre, "fatninger". Udtrykket blev foreslået af skaberne som en arbejdsmulighed, og det holdt fast. Som du ved, er sockets grundlaget for enhver API, der implementerer netværkskommunikation - Unix, Winsock osv. For at sende data over netværket skal en applikation blot skrive den til en socket, svarende til hvad man gør, når man gemmer information i en lokal fil. I begge tilfælde behøver programmet ikke bekymre sig om, hvad der sker bag kulisserne – tilføjelse af brugerdata officielle oplysninger, bryde ind i segmenter med deres efterfølgende indkapsling i datagrammer og fysisk afsendelse udføres af andre dele af operativsystemet - TCP / IP-stakken og enhedsdrivere, som applikationen ikke ved noget om. Denne "arbejdsdeling" giver dig mulighed for at ændre meddelelsesleveringsproceduren som ønsket, forudsat at applikationsprogrammeringsgrænsefladen forbliver konstant. Det er denne funktion, der ligger til grund for SOCKS-ideologien. Hovedopgaven for denne protokol er at introducere i den "normale" dataudvekslingsproces en bestemt mellemmand kaldet en SOCKS-server eller SOCKS-proxy. Når en klient (en applikation, der understøtter SOCKS: Mozilla webbrowser, ICQ Miranda IM-klient, etc., se nedenfor) ønsker at sende nogen information over netværket, etablerer den en forbindelse ikke med den rigtige modtager, men med SOCKS-serveren, som igen videresender data til sin destination, men på egne vegne. Fra den "rigtige" servers synspunkt (for eksempel det websted, som brugeren ønsker at se på Mozilla Firefox) SOCKS proxy er den mest almindelige klient. Således er identiteten (IP-adressen) for den sande klient skjult for serveren, der betjener den. Denne meget bekvemme omstændighed er fyldt med potentiel fare (du kan gemme dig Du, men det kan de fra dig), derfor har virkelige SOCKS-servere udviklet adgangskontrolordninger (forbyder indgående og udgående forbindelser til en given adresseliste) og understøtter brugerautorisation ved hjælp af en adgangskode (se nedenfor).

Bemærk, at da SOCKS opererer på et lavere niveau end applikationsniveauet (nemlig transport) i OSI-modellen, vil dets support ikke kræve nogen ændringer i klientens logik, meget mindre serveren. Faktisk er alt, hvad der er nødvendigt, at ændre implementeringen af ​​de funktioner, der er ansvarlige for at skabe netværks forbindelse og sende data: connect(), bind(), send() osv. I praksis opnås dette normalt ved at opsnappe systemopkald med deres efterfølgende udskiftning med SOCKS-understøttende brugeranaloger. Ingen ændringer i kildekoden klientapplikationer, meget mindre adgang til kildeteksterne er som regel ikke påkrævet. Denne kraftfulde procedure er kendt som "soksificering" og vil blive diskuteret i detaljer nedenfor.

Nu hvor vi har en generel forståelse af SOCKS, kan vi gå videre til et mere detaljeret udseende. af denne protokol.

SOCKS5 specifikation

SOCKS5-protokollen er beskrevet detaljeret i RFC1928. I modsætning til monstrøse standarder som HTTP 1.1 passer SOCKS-specifikationen til 9 sider og kan let analyseres af enhver. De oplysninger, der tilbydes her, er et kort resumé af det og er beregnet til at hjælpe dig i denne enkle sag.

Som tidligere nævnt er SOCKS5 en transportlagsprotokol. Dens "naboer" - TCP og UDP bruges direkte til at overføre data, der kommer fra applikationslaget (fra brugerdefinerede applikationer), hvilket betyder, at SOCKS-proxyen skal kunne fungere korrekt med hver af dem. Bemærk også, at ICMP-protokollen, der bruges af ping- og traceroute-værktøjerne, er placeret under transportlaget, og derfor kan den desværre ikke cosificeres.[ Fodnote: der er ikke-standardudvidelser til SOCKS-protokollen, der giver dig mulighed for at arbejde med ICMP, men de vil ikke blive diskuteret i denne artikel].

Før du sender nogen data, skal klienten gennemgå en godkendelsesprocedure på SOCKS-serveren. For at gøre dette åbner den en TCP-forbindelse til port 1080 (standardværdi) på SOCKS-serveren og sender en besked over den, der indeholder kodenumrene for de godkendelsesmetoder, den understøtter. SOCKS-serveren vælger en af ​​metoderne efter eget skøn og rapporterer sit nummer til klienten. En liste over nogle af de mulige værdier er givet i tabel 1. Som du nemt kan se, kan godkendelse være fraværende (i praksis betyder dette højst sandsynligt, at SOCKS-serveren skelner klienter ved deres IP-adresser) eller baseret på et brugernavn og adgangskode. I sidstnævnte tilfælde er det muligt et stort antal af forskellige muligheder, fra den trivielle "Username/Password Authentication" (RFC 1929), som sørger for transmission af en klartekstadgangskode, til den meget mere sikre CHAP (krypteret adgangskode, klare data) og GSSAPI (RFC 1961), som kan bruges til komplet kryptografisk beskyttelse af trafik. Efter vellykket godkendelse er klienten i stand til at sende anmodninger (kommandoer), etablere udgående forbindelser og endda modtage indgående.

Etablering af en udgående TCP-forbindelse

For at etablere en udgående TCP-forbindelse sender klienten en "CONNECT"-anmodning til SOCKS-serveren, som specificerer adressen og leveringsporten. For at identificere modtagerværten kan både IP-adresser (IPv4/IPv6 understøttes) og fuldt kvalificerede domænenavne bruges. I sidstnævnte tilfælde sørger SOCKS-serveren for at løse dem, så det netværk, som klienten opererer i, i princippet kan undvære en DNS-server. I svarmeddelelsen rapporterer SOCKS-serveren en fejlkode (som sædvanligt angiver 0, at operationen var vellykket), samt IP-adressen (BND.ADDR) og TCP-porten (BND.PORT), der vil blive brugt til faktisk at kommunikere med den ønskede knude. Da SOCKS-servere typisk har mere end én netværksgrænseflade, kan denne IP-adresse være forskellig fra den, som kontrolforbindelsen blev etableret med. Klienten åbner derefter en ny TCP-session med BND.ADDR:BND.PORT og sender data. Den udgående TCP-forbindelse afsluttes, når kontrolsessionen lukkes. Bemærk, at en CONNECT-anmodning kan blive afvist af en SOCKS-proxy, hvis kilde- (klient) eller destinations- (server) adresser er forbudt [ Fodnote: eller ikke eksplicit tilladt, afhængigt af den specifikke implementering og valgte politik] skal serviceres af systemadministratoren.

Etablering af en udgående UDP-forbindelse

I modsætning til TCP-streamingprotokollen, som involverer etablering af en session, UDP protokol er datagram, og derfor noget sværere at håndtere. Dens support dukkede kun op i SOCKS5.

Før du sender UDP-datagrammer, anmoder klienten om SOCKS-serveren UDP forening ved at bruge kommandoen "UDP ASSOCIATE". En UDP-association er en slags virtuel session mellem en klient og en SOCKS-server. I den udgående anmodning angiver klienten påståetadressen og porten, der vil fungere som kilden til fremtidige UDP-datagrammer. Hvis disse oplysninger endnu ikke er kendt, når UDP-tilknytningen er etableret, skal klienten bruge kombinationen 0.0.0.0:0 (eller f.eks. x.x.x.x:0, hvis kun portnummeret er ukendt). I svarmeddelelsen angiver SOCKS-serveren IP-adressen (BND.ADDR) og UDP-porten (BND.PORT), som udgående datagrammer skal sendes til. I dette tilfælde er adressen og porten på deres rigtige modtager angivet direkte i kroppen (vi kan sige, at UDP-indkapsling finder sted). E du parametre, sammen med afsenderens adresse og port, bruges til at afgøre, om et datagram kan sendes. Som du nemt kan se, skaber dette en ekstra belastning på SOCKS-serveren: filtreringsregler skal anvendes på hvert UDP-datagram, hvorimod i tilfælde af en TCP-forbindelse vurderes dens legitimitet én gang på det tidspunkt, hvor SOCKS-serveren udfører " CONNECT” kommando. Ifølge standarden skal SOCKS-serveren sikre, at IP-adressen på datagramafsenderen matcher adressen på den vært, der har oprettet UDP-tilknytningen. UDP-tilknytningen ødelægges samtidigt med lukning af TCP-kontrolsessionen, hvor UDP ASSOCIATE-kommandoen blev sendt.

Mange af de eksisterende SOCKS-servere oplever alvorlige problemer, hvis en NAT (Network Address Translation) firewall placeres mellem dem og den klient, der anmoder om UDP-tilknytningen. Årsagen til dette ligger i ændringen i kildeadressen og porten, der sker i det øjeblik UDP-datagrammet krydser firewallen. Som en konsekvens begynder serveren og den intetanende klientapplikation at tale forskellige sprog: den påtænkte kildeadresse og port specificeret i kommandoen "UDP ASSOCIATE" svarer ikke længere til de faktiske parametre for datagrammerne modtaget af SOCKS-serveren. Som følge heraf kasseres de, da de ikke tilhører UDP-foreningen. Problemet kunne løses ved at specificere 0.0.0.0:0 som den tilsigtede kilde (se ovenfor), som skal fortolkes af SOCKS-serveren som "ethvert UDP-datagram, der kommer fra den samme adresse som kommandoen til at oprette tilknytningen." Desværre fortolker de fleste af de faktiske SOCKS-servere standarden mere snævert og giver dig ikke mulighed for samtidig at sætte både den påtænkte adresse og afsenderporten til nul. Af de implementeringer, som forfatteren har testet, tillader "tricket med at videresende UDP gennem NAT" beskrevet her kun én - Dante.

Modtagelse af indgående forbindelser

Denne ret originale funktion kan være nyttig i tilfælde, hvor klienten og den "rigtige" server i skemaet beskrevet ovenfor er byttet om, hvilket for eksempel kan ske i protokoller som FTP. Med henblik på yderligere diskussion vil vi antage, at der allerede er etableret en "direkte" kommunikationskanal mellem "klienten" (den part, der skal acceptere den indgående forbindelse) og "serveren" (den part, der initierer den indgående forbindelse) vha. kommandoen "CONNECT". For at åbne en "omvendt" kanal skal "klienten" sende "BIND"-kommandoen til SOCKS-serveren og angive i dens parametre den IP-adresse og port, som den vil bruge til at modtage den indgående forbindelse. Som svar rapporterer SOCKS-serveren den IP-adresse og port, der er allokeret til den for at opretholde den "omvendte" kanal. "Klienten" forventes at videregive disse parametre til "serveren" ved hjælp af de faciliteter, der leveres af applikationslagsprotokoller (f.eks. FTP "PORT"-kommandoen). Efter at SOCKS-serveren har accepteret (eller afvist) den indgående forbindelse, giver den "klienten" besked igen og fortæller den IP-adressen og porten, der bruges af "serveren". Bemærk, at indgående forbindelser kun kan accepteres af en applikation, hvis udviklere tog sig af SOCKS-support på designstadiet. Ellers (hvis applikationen arbejder med SOCKS-serveren gennem et socket-program), vil den ikke være i stand til at give korrekte oplysninger om adressen på den socket, der venter på "feedback" (dvs. den vil generere den forkerte "PORT"-kommando i FTP-eksemplet beskrevet ovenfor).

"Kæder" SOKKER

Kom nu, kom på arbejde. Seks lejede "ad gangen" routere, som signalet løber igennem. Og alle er ret modstandsdygtige over for hacking.

Sergey Lukyanenko "Labyrinth of Reflections"

Arkitekturen i SOCKS5-protokollen gør det nemt at kombinere SOCKS-servere i kaskader, eller som de også kaldes "kæder". Det er bemærkelsesværdigt, at alle de handlinger, der er nødvendige for dette, kan udføres på klientsiden. Det eneste krav til kædens "led" er, at de skal "stole" hinanden (dvs. tillade etablering af indgående og udgående forbindelser). Hvis SOCKS-serverne, der danner kaskaden, ikke er anonyme (det vil sige, de bruger brugernavn/adgangskode, CHAP eller lignende godkendelsesskemaer), er det også nødvendigt, at brugeren kan gennemføre godkendelsesproceduren på hver af dem.

Lad os antage, at vi har et sæt N SOCKS-servere ved navn socks1, socks2, ..., socksN, der opfylder alle ovenstående krav. Derefter, for at oprette en kaskade, kan klienten gøre følgende:

    Hvornår udgående TCP-forbindelse: klienten opretter forbindelse til socks1, gennemgår godkendelsesproceduren (hvis nødvendigt) og sender "CONNECT"-kommandoen og angiver socks2 som leveringsadresse. Ved at udføre denne anmodning vil socks1 skabe en ny forbindelse med socks2 og vil regelmæssigt overføre al den information, der passerer gennem den, til klienten, mens socks2 ikke engang vil gætte, hvem den faktisk kommunikerer med. Proceduren gentages derefter, indtil der er etableret forbindelse mellem sokker(N-1) og sokkerN. Den sidste server i kaskaden forbinder direkte til den node, der interesserer klienten. Dataoverførsel foregår i normal tilstand: Klienten sender pakken til socks1-serveren, som igen sender den til socks2, ... og så videre indtil slutknuden er nået.

    Hvornår udgående UDP-forbindelse: klienten opretter forbindelse til socks1, gennemgår godkendelsesproceduren og sender sekventielt to kommandoer: "CONNECT" (leveringsadresse - socks2) og "UDP ASSOCIATE". Der skabes således to nye forbindelser: en virtuel UDP-kanal mellem klienten og socks1 og en TCP-session mellem socks1 og socks2. Ved at bruge denne TCP-session sender klienten (på vegne af socks1) kommandoen "UDP ASSOCIATE" til socks2-serveren (åbner en UDP-kanal mellem socks1 og socks2) og "CONNECT" til socks3-serveren. Proceduren fortsætter, indtil virtuelle UDP-kanaler er etableret mellem alle SOCKS-servere i kaskaden. For at sende data, udfører klienten først N-fold indkapsling af UDP-datagrammet, og specificerer sekventielt socks1, socks2, socks3, socksN og adressen på den rigtige modtager som leveringsadresse, og sender den derefter til socks1-serveren. Bemærk det i praksis denne mulighed kaskade er yderst sjældent. Dette skyldes det faktum, at SOCKS-servere, som NAT Firewalls, kan ændre kildeporten for datagrammet, hvilket vil føre til problemer beskrevet i detaljer i afsnittet "Etablering af en udgående UDP-forbindelse".

Ved at bruge kæder af SOCKS-servere, der ikke kræver godkendelse, kan klienten øge anonymiteten ved arbejde på internettet markant (se epigraf). Du kan finde mange programmer på internettet, der implementerer de ordninger, der er beskrevet her. Disse er for eksempel SocksChain (http://www.ufasoft.com/socks/ ) til Windows eller ProxyChains ( ) til Unix. Cascading SOCKS-servere er også en integreret del af nogle soxifiers, især FreeCap (http://www.freecap.ru/ ).

SOCKS servere

Nu hvor vi er godt bekendt med driftsprincipperne for en SOCKS-server, er det tid til at gå fra teori til praksis. Der er et stort antal programmer i verden, der implementerer SOCKS5-protokollen. De dækker alle de populære OS(Unix, Windows, ...) og distributionsmetoder (freeware, shareware, open source osv.). Her vil vi kort overveje de mest berømte (eller interessante fra forfatterens synspunkt) implementeringer.

Lad os starte med SOCKS5 Reference Implementation (http://www.socks.permeo.com/), lavet af NEC og ejet af i øjeblikket Permeo selskab. Nuværende version nummereret 1.0r11 og dateret august 2000. Som du nemt kan gætte ud fra navnet, er denne server en referenceimplementering af protokollen og er generelt set ikke beregnet til industriel brug. Men af ​​årsager, der ikke er særlig klare for mig, blev det inkluderet i FreeBSD-portene, og er derfor en de facto standard på denne platform. Produktet har GSSAPI-understøttelse og distribueres i kildekode, men under en proprietær licens. Kommerciel brug af denne server er forbudt.

Dante, udviklet af det norske firma Inferno Nettverk, er især populær blandt Linux-supportere. Produktet udvikler sig, men ikke særlig hurtigt ( nyeste version, 1.1.15, dateret 31. januar 2005) og er ganske velegnet til praktisk brug. Som tidligere nævnt tillader Dante, at UDP-foreninger fungerer korrekt, selvom de går gennem en NAT Firewall. Programmet distribueres i kildekode under BSD-licensen. Dante inkluderer et bibliotek til gennemsigtig coxification af Unix-applikationer (se nedenfor)

Valentin Sinitsyn (val AT linuxcenter DOT ru) - Universal proxyserver

En sådan proxyserver kontrollerer klientens rettigheder til at få adgang til eksterne ressourcer og sender anmodningen til serveren. SOCKS kan også bruges på den modsatte måde, hvilket giver eksterne klienter mulighed for at oprette forbindelse til servere bag en firewall.

I modsætning til HTTP-proxy-servere transmitterer SOCKS alle data fra klienten uden at tilføje noget fra sig selv, det vil sige fra slutserverens synspunkt er SOCKS-proxyen en almindelig klient. SOCKS er mere universel - den afhænger ikke af specifikke applikationslagsprotokoller (lag 7 af OSI-modellen) og er baseret på TCP/IP-standarden - lag 4-protokollen. Men HTTP-proxy cacher data og kan mere omhyggeligt filtrere indholdet af de overførte data.

Denne protokol blev udviklet af David Koblas, en systemadministrator hos MIPS Computer Systems. Efter at MIPS blev en del af Silicon Graphics (SGI) det år, holdt Koblas et foredrag om SOCKS på Usenix Security Symposium, og SOCKS blev offentligt tilgængelige. Protokollen blev udvidet til version 4 af Ying-Da Lee fra NEC Systems Laboratory.

SOCKS 4 protokol

SOCKS 4 er designet til at fungere gennem en firewall uden godkendelse til klient-server-applikationer, der kører over TCP, såsom TELNET, FTP og populære kommunikationsprotokoller såsom HTTP, WAIS og GOPHER. Grundlæggende kan en SOCKS-server opfattes som en firewall, der understøtter SOCKS-protokollen.

En typisk SOCKS 4-anmodning ser sådan ud (hvert felt er en byte):

Klientanmodning til SOCKS Server:

  • felt 1: SOCKS versionsnummer, 1 byte (skal være 0x04 for denne version)
  • felt 2: kommandokode, 1 byte:
    • 0x02 = TCP/IP-porttildeling (binding)
  • felt 3: portnummer, 2 bytes
  • felt 4: IP-adresse, 4 bytes
  • felt 5: bruger-id, streng med variabel længde, afsluttet med en null-byte (0x00). Feltet er beregnet til at identificere brugeren (se Ident)

Serversvar til SOCKS-klient:

  • felt 1: null byte
  • felt 2: svarkode, 1 byte:
    • 0x5a = anmodning imødekommet
    • 0x5b = anmodning afvist eller ugyldig
    • 0x5c = Anmodningen mislykkedes, fordi identd ikke kører (eller ikke er tilgængelig fra serveren)
    • 0x5d = Anmodningen mislykkedes, fordi klientens identd ikke kunne validere bruger-id'et i anmodningen
  • felt 3: 2 vilkårlige bytes, bør ignoreres
  • felt 4: 4 vilkårlige bytes, bør ignoreres

SOCKS 5 protokol

SOCKS 5 udvider SOCKS 4-modellen ved at tilføje UDP-understøttelse, hvilket giver universelle ordninger stærk autentificering og udvider adresseringsmetoder ved at tilføje understøttelse af domænenavne og IPv6-adresser. Indledende installation Forbindelsen består nu af følgende:

  • Klienten forbinder og sender en hilsen, der inkluderer en liste over understøttede godkendelsesmetoder
  • Serveren vælger en af ​​dem (eller sender et svar på anmodningsfejl, hvis ingen af ​​de foreslåede metoder er acceptable)
  • Afhængigt af den valgte metode kan en række meddelelser passere mellem klienten og serveren
  • Klienten sender en forbindelsesanmodning, der ligner SOCKS 4
  • Server reagerer på samme måde som SOCKS 4

Godkendelsesmetoder er nummereret som følger:

  • 0x00 - ingen godkendelse påkrævet
  • 0x01 - GSSAPI
  • 0x02 - brugernavn/adgangskode
  • 0x03-0x7F - reserveret af IANA
  • 0x80-0xFE - forbeholdt private brugsmetoder

Indledende hilsen fra klienten:

  • felt 2: antal understøttede godkendelsesmetoder, 1 byte
  • felt 3: autentificeringsmetodenumre, variabel længde, 1 byte for hver understøttet metode

Serveren rapporterer sit valg:

  • felt 1: SOCKS version, 1 byte (0x05 for denne version)
  • felt 2: valgt godkendelsesmetode, 1 byte eller 0xFF, hvis der ikke blev foreslået nogen acceptabel metode

Efterfølgende identifikation afhænger af den valgte metode.

Kundeanmodning:

  • felt 1: SOCKS versionsnummer (skal være 0x05 for denne version)
  • felt 2: kommandokode, 1 byte:
    • 0x01 = opsætning af TCP/IP-forbindelse
    • 0x02 = TCP/IP-porttildeling (binding)
    • 0x03 = UDP-porttilknytning
  • felt 3: reserveret byte, skal være 0x00
  • felt 4: adressetype, 1 byte:
    • 0x01 = IPv4-adresse
    • 0x03 = domænenavn
    • 0x04 = IPv6-adresse
  • felt 5: adressetildeling
    • 4 bytes til IPv4-adresse
    • 16 bytes til IPv6-adresse
  • felt 6: portnummer, 2 bytes

Serversvar:

  • felt 1: SOCKS versionsnummer, 1 byte (0x05 for denne version)
  • felt 2: svarkode, 1 byte:
    • 0x00 = anmodning godkendt
    • 0x01 = SOCKS serverfejl
    • 0x02 = forbindelse er forbudt af regelsættet
    • 0x03 = netværk ikke tilgængeligt
    • 0x04 = vært utilgængelig
    • 0x05 = forbindelse nægtet
    • 0x06 = TTL udløbet
    • 0x07 = Kommando ikke understøttet / protokolfejl
    • 0x08 = adressetype understøttes ikke
  • felt 3: Byte reserveret, skal være 0x00
  • felt 4: efterfølgende adressetype, 1 byte:
    • 0x01 = IPv4-adresse
    • 0x03 = domænenavn
    • 0x04 = IPv6-adresse
  • felt 5: adressetildeling
    • 4 bytes til IPv4-adresse
    • den første byte er længden af ​​navnet, efterfulgt af domænenavnet uden et afsluttende null
    • 16 bytes til IPv6-adresse
  • felt 6: portnummer, 2 bytes

Implementeringer

  • Sun Java System Web Proxy Server - caching proxyserver til Solaris, Linux, Windows. Understøtter HTTPS, NSAPI I/O-filtre, dynamisk rekonfiguration og omvendt proxy.
  • DeleGate er en multifunktionel gateway og proxyserver på applikationsniveau, der kører på forskellige platforme. Ud over SOCKS understøtter den også HTTP(S), FTP, NNTP, SMTP, POP, IMAP, LDAP, Telnet, DNS og andre protokoller.
  • 3proxy - letvægts proxyserver med SOCKS-proxy support
  • WinGate er en multi-protokol proxy-server med SOCKS-understøttelse til Windows.
  • OpenSSH giver dig mulighed for dynamisk at skabe tunneler defineret gennem en delmængde af SOCKS-protokollen.

se også

Links

  • RFC 1928 - SOCKS Protocol Version 5
  • RFC 1928 (russisk) - SOCKS 5-protokol
  • RFC 1929 - Brugernavn/adgangskodegodkendelse til SOCKS V5
  • RFC 1961 (engelsk) - GSS-API-godkendelsesmetode for SOCKS version 5
  • SOCKS: En protokol til TCP-proxy på tværs af firewalls - SOCKS 4-protokol

Wikimedia Foundation. 2010.

Se, hvad "SOCKS" er i andre ordbøger:

    SOKKER- er en internetprotokol, der gør det muligt for klientserverapplikationer på en gennemsigtig måde at bruge tjenesterne fra en netværksfirewall. SOCKS er en forkortelse for SOCKetS [ ]… … Wikipedia

    SOKKER- Saltar og navegación, SOCKS er en internetprotokol, som tillader en applikationsklient, der bruger gennemsigtige maneraer til en rød firewall. SOCKS er en forkortelse af SOCKETS. Los kunder que hay detrás… … Wikipedia Español

    En netværksprotokol, der gør det muligt for klient-server-applikationer transparent at bruge tjenester bag firewalls. SOCKS er en forkortelse for SOCKetS (sockets). Klienter bag en firewall, der har brug for adgang til... ... Wikipedia

    Sokker- im Briefing Room des Weißen Hauses Betty Currie und Socks ... Deutsch Wikipedia

    Sokker- sobre el pupitre de la Sala de Prensa de la Casa Blanca. Sokker (en español: Calcetines, marts 1989 20. februar 2009) er en af ​​de amerikanske præsidenter i USA, hvor Bill Clinton var præsident. Fue la única mascota... ... Wikipedia Español

For noget tid siden ville jeg prøve at implementere en proxyserver til mine egne behov, og en der kunne bruges i fremtiden, og også at dens størrelse ville være minimal. Den naturlige mulighed for mig var implementering ved hjælp af assembler. Programmet viste sig at være lille, praktisk, og i fremtiden brugte jeg det meget ofte. Men nu, efter at der er gået flere år, vil jeg gerne vise den enkleste implementering af én protokol, SOCKS4. Denne protokol blev oprettet, så klienter placeret på det lokale netværk bag firewallen kunne få adgang til det eksterne netværk. Samtidig er det i dette tilfælde muligt at styre klientforespørgsler :) Det allerførste du skal gøre ved implementering er at læse dokumentationen der beskriver denne protokol, da vi ønsker at vores protokol skal forstås af standardprogrammer, uden at "underminerer med en fil." Så dokumentationen:

Lad os nu, bevæbnet med en beskrivelse, komme i gang. En proxy-servers opgave er at acceptere en anmodning fra en klient i et bestemt format, generere en socket og forbinde den til den adresse, klienten anmoder om, og derefter sikre udvekslingen af ​​data mellem to sockets, indtil de lukkes af serveren eller klient. Lad os begynde implementeringen.

Makroer og datastrukturer brugt i programmet

Lad os oprette en include-fil, include.inc. I denne fil vi placerer de standard, kl skrive Windows programmerer makroer + strukturer til at arbejde med SOCKS4. Her vil jeg ikke give alle makroerne, jeg vil kun give den beskrivelse og funktionalitet, der er nødvendig for at løse hovedproblemet, alt andet finder du i den vedhæftede fil med kildekoderne.
; SOCKS4 – Den struktur, der bruges af klienten, når den anmoder om en forbindelse; til den angivne server(DSTIP)/port(DSTPORT) CONNECT_SOCK4 Struc VN Db ? CD Db ? DSTPORT Dw ? DSTIP Dd? NULL Db? CONNECT_SOCK4 Slutter ; SOCKS4 - proxyserversvar om forbindelsen. RESPONSE_SOCK4 Struc VN Db ? CD Db ? DSTPORT Dw ? DSTIP Dd? RESPONSE_SOCK4 Slutter

I det store og hele er CONNECT_SOCK4- og RESPONSE_SOCK4-strukturerne ikke anderledes, da vi implementerer protokollen uden autorisation. Men jeg besluttede at lade dem være adskilt, så jeg i fremtiden nemt kunne ændre dem til forbedring. I selve strukturerne, i VN-variablen, er protokolversionen angivet; i vores tilfælde skal der altid være 4; i tilfælde af SOCKS5 indeholder denne variabel 5 (protokollen er grundlæggende ens). CD-variablen bruges til at returnere resultatet af proxyserveranmodningen til klienten til den adresse, klienten anmoder om (90 - forbindelse lykkedes / 91 - forbindelse mislykkedes).
Vi har faktisk tre trin i programmet.
* Først initialiserer vi socket, lytter til socket for klientanmodninger og opretter en behandlingstråd.
* Anden fase er analysen af ​​klientens anmodning, et forsøg på at oprette og forbinde en socket til den server, klienten anmoder om.
* Og det sidste, tredje trin er at sende data mellem klient-socket og socket, der er oprettet og forbundet af os, til den anmodede adresse.

Implementering af første fase, initialisering af programmet:

; Hovedproceduren er startproceduren for WinMain-programmet Proc LOCAL ThreadId, hServSock:DWORD LOCAL værtsnavn :BYTE LOCAL _wsa:WSADATA LOCAL _our:sockaddr_in ; Ved at lancere biblioteket til at arbejde med sockets bruger vi funktionaliteten i version 1.1, ; lad os anmode om det som et minimum kalder WSAStartup, 0101h, ADDR _wsa .if eax == 0 ; Vi tager vores adresse, forbereder en struktur til at initialisere serversocket 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 påkald inet_ntoa, eax mov _our.sin_family, AF_INET mov _our.sin_addr.S_un.S_addr, INADDR_ANY xor eax, eax ; Indtast den port, hvorpå vi vil lytte til indgående beskeder mov ax, SOCKS_PORT invoke htons, eax mov _our.sin_port, ax invoke socket, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET ; Gem den oprettede server socket mov hServSock, eax ; Vi binder serversocket til vores adresse og den nødvendige port kalder bind, hServSock, ADDR _our, SIZEOF sockaddr_in .if eax != SOCKET_ERROR @@: ; Start socket for at vente påkald lyt, hServSock, SOMAXCONN .repeat ; En klient er ankommet, vi modtager en socket med den indgående klient kalder accept, hServSock, NULL, NULL .until eax != INVALID_SOCKET ; Opret en tråd, hvori den aktuelle klient vil blive behandlet xchg eax, ebx invoke CreateThread, NULL, NULL, ADDR socketThread, ebx, NULL, ADDR ThreadId ; Vi lader vente på kunder jmp @B .endif .endif kalder closesocket, hServSock .endif påkalder ExitProcess, 0 WinMain Endp
Dette er vores første procedure, jeg forsøgte at kommentere koden så meget som muligt, så du kan forstå den, men hvis noget stadig ikke er klart, så kontakt enten mig eller MSDN. Grundlæggende er al koden skrevet ved hjælp af MASM og WinAPI syntaks. Resultatet af ovenstående funktion bør være en fungerende socket på en af ​​netværksadresserne på din maskine (lokal adresse eller ekstern adresse, hvis du har en rigtig IP) + baseret på klientforbindelsen opretter funktionen en separat tråd, der bruges til at fungere med den indkommende kunde. Lad os nu gå videre...

Anden fase, analyse af kundens anmodning

I det andet trin er alt, der skal gøres, at acceptere en CONNECT_SOCK4-struktur, oprette en socket, prøve at forbinde den og sende et svar til klienten. Implementering:

SocketThread Proc sock:DWORD LOCAL lpMem, _csock, ThreadId, dAmount:DWORD LOCAL Remote:sockaddr_in LOCAL wrFds, rdFds:fd_set LOCAL hResp:RESPONSE_SOCK4 ; Gør dig klar til at læse data fra soklen kalder FdZero, ADDR rdFds påkalder FdSet, sock, ADDR rdFds påkalder select, NULL, ADDR rdFds, NULL, NULL, NULL ; Vi får størrelsen på de data, der venter på at blive læst påkald ioctlsocket, sock, FIONREAD, ADDR dAmount ; Vi reserverer hukommelse til data mov lpMem, @Result(LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, dAmount) ; Læs anmodningsdata fra socket-invoke recv, sock, lpMem, dAmount, 0 ; Anmodningen kom lea edi, hResp mov esi, lpMem; Esi indeholder en brugeranmodning. Vi håndterer (her) kun SOCKS4 versionen, ; SOCKS5 kan i princippet behandles her, men det kommer senere... Antag Esi: Ptr CONNECT_SOCK4 Antag Edi: Ptr RESPONSE_SOCK4 .if .VN == 4 ; Implementering af SOX 4-protokollen .if .CD == 1 invoke socket, AF_INET, SOCK_STREAM, 0 .if eax != INVALID_SOCKET mov _csock, eax ; Vi tager data fra den eksterne vært, som klienten ønsker at forbinde med mov Remote.sin_family, AF_INET mov ax, .DSTPORT mov Remote.sin_port, axe mov eax, .DSTIP mov Remote.sin_addr, eax mov cx, .DSTPORT mov edx , .DSTIP ; Edi indeholder svaret på brugeren mov .VN, 0 mov .DSTPORT, cx mov .DSTIP, edx ; Vi forsøger at forbinde med fjernserver invoke connect, _csock, ADDR Remote, SIZEOF Remote .if !eax ; Vi er ved at forberede et svar om, at vi har tilsluttet mov .CD, 90 ; Vi sender klienten et svar indeholdende resultatet af forbindelsesforsøget påkald send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 ; Vi danner en struktur med information om serveren og; tilsluttede klientstik; - med server mener jeg her stikket tilsluttet klienten; hvem sendte anmodningen; - med klient mener jeg en socket forbundet til serveren; hvis data blev anmodet af klienten mov ebx, @Result(LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, SIZEOF THREAD_DATA) Antag Ebx: Ptr THREAD_DATA mov eax, _csock mov .Server, eax mov eax, .bxsient mov eax, .bx; Vi starter socketbehandlingstråden (læser fra klienten og sender til serversocket) kalder CreateThread, NULL, NULL, ADDR ClientSock, ebx, NULL, ADDR ThreadId .else ; Hvis forbindelsen mislykkes, luk klientsocket påkald closesocket, _csock ; Vi siger, at der var en forbindelsesfejl mov, 91; Vi sender klienten et svar, der indeholder resultatet af forbindelsesforsøget påkald send, sock, ADDR hResp, SIZEOF RESPONSE_SOCK4, 0 .endif .endif .endif .endif Antag Edi: Intet Antag Esi: Intet ; Frigørelse af den hukommelse, der er allokeret til anmodningen, kalder LocalFree, lpMem ret socketThread Endp
Resultatet af denne procedure er en tilsluttet socket, samt en oprettet tråd, der implementerer dataudveksling mellem to sockets. Det er simpelt. Man skal blot præcisere, at flere adresseringspunkter er brugt her inden for de strukturer, der blev introduceret i MASM for at gøre programmørens liv lettere. Første punkt, "Antag"-makroen.
Linjen Antag Esi: Ptr CONNECT_SOCK4 fortæller compileren, at dette register (Esi) indeholder adressen på CONNECT_SOCK4-strukturen, hvilket yderligere forenkler adgangen til variabler i denne struktur. Antag Esi: Intet annullerer bindingen. For bedre at forstå, kan det være lettere, hvis jeg angiver et par adresseringsmuligheder:
Antag Esi:Ptr CONNECT_SOCK4 mov al, .VN ; Vi placerer i AL byteværdien fra variablen VN struktur mov al, .CD ; Placer den variable CD mov axe i AL. .DSTPORT ; Placer variablen DSTPORT i AX Antag Esi:Nothing
eller
mov al, ; Placer byteværdien fra VN-variablen i AL mov al, ; Placer den variable CD mov ax, ; Placer variablen DSTPORT i AX
eller
mov al, byte ptr; Placer variabel VN i AL mov al, byte ptr ; Placer CD-variablen i AL mov ax, word ptr ; Placer variablen DSTPORT i AX

Jeg tror, ​​det er indlysende for dig, ligesom det er for mig, at det er hurtigere, mere bekvemt og overskueligt at bruge den første mulighed. Selvom det er nødvendigt at henvise til en variabel i strukturen, har den anden mulighed ret til at eksistere. Jeg tror, ​​det er bedre at bruge den tredje mulighed i tilfælde, hvor dataene på adressen ikke er strukturerede. Men som du ved, har hver Tambov-ulv sin egen smag og farve. Brug den metode, der er mest praktisk for dig.
Endnu et punkt, der er værd at afklare. Resultatmakro. Denne makro blev skrevet, så du kan kalde en WinAPI-funktion på én linje og skrive udførelsesresultatet til et register eller hukommelse. Så linjen:
mov lpMem, @Result(LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, dAmount)
Foretag først et opkald som dette:
påkald LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, dAmount
og efter henrettelse dette opkald udførelsesresultatet (Eax) gemmes i variablen lpMem. Heri konkret tilfælde, vil hukommelse blive allokeret, og adressen, hvor det område, der er allokeret til os, er placeret, vil blive skrevet til variablen.

Trin tre, dataoverførsel

Så de to sværeste etaper er gennemført. Klienten ankom, vi sluttede ham til fjernserveren, og det var tid til det enkleste "abe"-arbejde. Overfør data mellem to stik. Lad os gøre det hurtigt og nemt:
; En stream, der læser fra klientsocket og sender den til serversocket.... ClientSock Proc Param:DWORD LOCAL sserver, sclient:DWORD LOCAL rdFds:fd_set LOCAL dAmount, lpBuf: DWORD ; I Param har vi information om serveren og klientsockets; overførsel til lokale variabler mov ebx, Param Antag Ebx: Ptr THREAD_DATA mov eax, .Server mov sserver, eax mov eax, .Client mov sclient, eax Antag Ebx: Intet ; Glem ikke at frigøre hukommelse kalder LocalFree, Param @@: påkald FdZero, ADDR rdFds påkalder FdSet, sserver, ADDR rdFds påkalder FdSet, sclient, ADDR rdFds påkalder vælg, NULL, ADDR rdFds, NULL, NULL, NULL; Tjek om der er data at læse.if eax == SOCKET_ERROR || eax == 0 ; Ingen data - exit jmp @F .endif ; Er der data fra serveren, der skal videregives til klienten? påkald FdIsSet, sserver, ADDR rdFds .if eax; Vi får størrelsen på de data, der venter på at blive læst påkald ioctlsocket, sserver, FIONREAD, ADDR dAmount ; Reserver hukommelse til data mov lpBuf, @Result(LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, dAmount) kalder recv, sserver, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif invoke send, sclient, lpBuf, eax, 0 invoke LocalFree, lpBuf .endif ; Er der data fra klienten at sende? server socket? påkald FdIsSet, sclient, ADDR rdFds .if eax; Vi får størrelsen på de data, der venter på at blive læst, kalder ioctlsocket, sclient, FIONREAD, ADDR dAmount ; Reserver hukommelse til data mov lpBuf, @Result(LocalAlloc, LMEM_FIXED eller LMEM_ZEROINIT, dAmount) kalder recv, sclient, lpBuf, dAmount, 0 .if eax == SOCKET_ERROR || eax == 0 jmp @F .endif invoke send, sserver, lpBuf, eax, 0 invoke LocalFree, lpBuf .endif ; Lad os gå til en ny cyklus jmp @B @@: ; Luk sockets invoke closesocket, sserver invoke closesocket, sclient ; Afslut påkaldetråden ExitThread, 0 ClientSock Endp
Til at begynde med initialiserer denne procedure interne variabler fra strukturen, der sendes til strømmen, for at gøre dem mere bekvemme at bruge. Så bliver der i løkken tjekket om der er data at læse fra soklerne, så i to stykker kode (faktisk copy-paste, her gad jeg ikke fjerne funktionen og optimere den fordi den er mere overskuelig ) læs fra den ene sokkel og send den til den anden.
Det var det, hurra! Lad os kompilere og prøve. I princippet er den bedste mulighed FireFox. I forbindelsesindstillingerne angiver vi, at du skal bruge en SOCKS4 proxyserver. Vi angiver dens adresse og den havn, den er placeret på. Derefter gemmer vi indstillingerne og nyder internettet, passeret gennem vores proxy, 3,5 kbytes i størrelse))) Ja, jeg vil præcisere. Til kompilering er det nødvendigt at have pakken installeret

Goddag kære venner, bekendte, læsere, beundrere og andre personer. I denne artikel, som du forstår ud fra titlen, vil vi tale om, hvad der er SOKKER server og hvorfor det overhovedet er nødvendigt.

Selvfølgelig vil disse oplysninger være mere nyttige for interesserede end for den gennemsnitlige bruger, men i princippet kan viden om sådanne ting også være nyttig for ham... for hvem ved, hvordan livet vil tage sig ud.

Generel og detaljeret beskrivelse af SOCKS

Dette er en protokol, der tillader netværksapplikationer interagere gennem en firewall, der blokerer for direkte forbindelse. I dette tilfælde bruges en speciel mellemserver, som begge klienter har adgang til.

Den transmitterer data modtaget fra den første klient til den anden og tilbage. I modsætning til, igennem SOKKER en proxy kan tillade enhver trafik (f.eks. ). Udover SOKKER transmitterer “rene” data uden at tilføje noget ekstra fra sig selv, så det er sværere at opdage.

I hverdagen SOKKER Proxy bruges oftest til at få adgang til websteder, der er forbudte. I denne situation viser det sig, at du har adgang til serveren og ikke en forbudt internetadresse, så forbindelsen er ikke blokeret.

Den anden grund til at du kan bruge disse servere er for anonymitet, nemlig at skjule. I dette tilfælde er det ikke dig, der etablerer forbindelsen til den eksterne internetserver, men SOKKER proxy, så det er usandsynligt, at slutserveren modtager nogen information om dig og din computer.

Efterord

Det er det. Jeg håber nu, at du i det mindste nogenlunde forstår, hvad det generelt er, og hvorfor det generelt kan være nødvendigt.

Om hvordan man konkret arbejder med SOKKER og andre fuldmagter til at skjule deres IP vil blive skrevet i en separat artikel, medmindre der selvfølgelig er nogen, der har brug for og er interesseret i det.

Som altid, hvis du har spørgsmål, tanker, tilføjelser osv., er du velkommen til at kommentere dette materiale.