Copyright © 1997 RNDr. Libor Dostalek

SOCKS

Poznámka: Tato kapitola se nezabývá Microsoft SOCKS. MS SOCKS je mírně odlišný mechanismus.

Doposud jsme pro každý aplikační protokol spouštěli samostatnou proxy. Proxy mohla být doplněna o wrapper (na následujícím obrázku wrapper není znázorněn).

 Asi vás napadlo, že wrapper je v podstatě šit na míru do prostředí operačního systému UNIX. SOCKS řeší problematiku proxy obecně nezávisle na použitém operačním systému.

 SOCKS-server je proxy, která je společná pro všechny aplikační protokoly.

 SOCKS řeší problematiku komplexně ve čtyřech krocích:

 Jinými slovy: klient (např. program telnet) musí nejprve vést dialog se SOCKS-serverem, kterému sdělí na jaký server chce propojit. Volitelně je možná autentizace klienta.

Podstatné je, že klient vede se SOCKS-serverem dialog. Programy, kterými se realizují klienti, musí být doplněny tak, aby uměly vést tento dialog.

Jsou vytvořeny knihovny podporující SOCKS-protokol, které jsou obdobou standardních socketových knihoven používaných při programování v prostředí TCP/IP. Stačí ve zdrojovém textu programu opravit volání standardní funkcí socketových knihoven za tato volání. Přitom obojí volání mají stejnou syntaxi. Stačí pouze mechanicky zaměnit názvy funkcí:
 
 
Standardní knihovny Knihovny SOCKS
connect() Rconnect()
getsockname() Rgetsockname()
bind() Rbind()
accept() Raccept()
listen() Rlisten()
select() Rselect()

V podstatě ani není třeba opravovat zdrojové texty programů, protože uvedenou substituci je možné zadat při překladu programu (tj. specifikovat v souboru Makefile).

 Máte-li zdrojový text programu klienta, pak jej znovu přeložíte s uvedenou substitucí a získáte klienta pracujícího se SOCKS. Dnešní klienti jsou již konfigurovatelní tak, že je možné zvolit komunikaci přes SOCKS-server (např. Netscape Navigator). 


Na předchozích obrázcích jsem nakreslil klienta ve vnitřní síti jak přistupuje na server v Internetu. Jelikož se provádí autentizace, tak obdobně jako při použití wrapperu je za použití dostatečných kryptografických mechanizmů přistupovat pro vybrané uživatele (kteří se autentizují) přes SOCKS-server z Internetu do vnitřní sítě. SOCKS-server pak zpravidla konfigurujeme tak, že pro přístup: Jak jsem se již zmínil, tak předpokládáme, že SOCKS-server beží na firewallu. Nadále budu v této kapitole místo slova SOCKS-server používat slovo firewall, protože se domnívám, že text bude jasnějiší.

 Nyní nám zbývá SOCKS-protokol.

SOCKS-protokol

SOCKS-protokol používá protokol TCP zpravidla na portu 1080. Důležité je si uvědomit, že i zprostředkování odeslání UDP-datagramu je prováděno protokolem TCP.

Dohoda na autentizační metodě (RFC-1928)

Klient začíná komunikaci s firewallem paketem, ve kterém specifikuje které metody umí:

 Jelikož klient může specifikovat více metod (proměnné množství), tak pole Počet metod určuje kolik metod klient specifikoval, tj. jaká je délka pole Metody.

 Firewall zvolí jednu metodu, kterou klient musí použít k autentizaci. Tuto volbu vrací v paketu tvaru:

Pole Verze v dotazu i odpovědi obsahuje verzi protokolu SOCKS. Tč. je aktuální verze 5.

 Každá metoda se specifikuje jedním bajtem. Tč. se používají metody (šestnáctkově):
 
 
00 Bez autentizace
01 Autentizace GSS-API
02 Autentizace pomocí jména uživatele a hesla
FF Neakceptovatelná metoda

Jelikož se může stát, že klient nabízí metody, ze kterých není ani jedna pro firewall přijatelná, pak firewall vrátí metodu "Neakceptovatelná metoda" a spojení ukončí.
 
 

Autentizační dialog

Po dohodě mezi firewallem a klientem na autentizační metodě dojde na základě zvolené metody k autentizaci. Slovo autentizace není v této souvislosti zcela správné, protože klient se může s firewallem dohodnout na metodě, která nezahrnuje pouze autentizaci, ale i požadavky na privátnost spojení a zajištění integrity přenášených dat mezi klientem a firewallem, tj. šifrování a elektronické podepisování přenášených dat.

 V případě, že firewall požaduje metodu "Autentizace pomocí jména uživatele a hesla", pak klient odešle paket:

 Paket obsahuje verzi autentizačního protokolu. Tč. je aktuální vere 1 pro autentizaci jménem a heslem v protokolu SOCKS verze 5. Dále paket obsahuje jméno uživatele a heslo. Jelikož jak jméno tak heslo mohou mít různou délku, tak každé pole je uvozenou jedním bajtem specifikujicím délku následujícího pole.

Firewall vrací jako odpověď paket obsahující pouze verzi a status. Pole Status nabývá hodnoty nula v případě úspěšné autentizace a nenulové hodnoty v případě neúspěšné autentizace.

Požadavek na zřízení příslušné proxy (RFC-1928)

V případě, že se klient s firewallem v autentizačním dialogu dohodli na metodě, která zahrnuje šifrování (případně elektronické podepisování), pak od okamžiku úspěšného ukončení autentizačního dialogu již vše dále běží šifrováno (případně podepisováno).

 Po úspěšném dokončení autentizačního dialogu vyšle klient firewallu paket, ve kterém specifikuje cílový server se kterým chce skrze firewall komunikovat.

 V paketu pole verze opět obsahuje aktuální verzi protokolu SOCKS. Pole Res. je rezerva - musí obsahovat binární nuly. Ostatní pole jsou zajímavější:

V paketu klient specifikuje cílový server pro který chce, aby mu fireweall umožnil spojení. Jediné co jsme zatím neobjasnil jsou příkazy CONNECT, BIND a ASSOCIATE. K nim se dostaneme po té, co si popíšeme paket, který odešle firewall jako odpověď:

 Pole Odpověď obsahuje nulu v případě kladné odpovědi. Nenulové hodnoty pak specifikují příčinu chyby.

Pole Adresa připojení a Port připojení obsahují adresu a port firewallu na kterém se otevírá pro klienta na firewallu spojení na cílový server. Čili obecně adresa a port na kterém bude firewall umožňovat spojení s cílovým serverem mohou být různé od adresy a portu na kterém klient o toto spojení žádá (na kterém prováděl autentizaci).

Jinou IP-adresu mohou využívat např. firewally, které mají více síťových interfejsů a chtějí optimalizovat rozložení síťového provozu.

 Jiný port se využije např. žádá-li klient o propuštění UDP-datagramu. V tomto případě "žádání" proběhne na portu protokolu TCP a UDP-datagram je vyslán na portu UDP (TCP a UDP porty jsou zásadně různé byť by měly i stejné číslo).
 
 

Příkaz CONNECT

Příkaz CONNECT se používá ve většině případů. Např. pro protokoly TELNET, FTP, HTTP atd.

 V příkazu CONNECT se specifikuje IP-adresa a port cílového serveru se kterým chce klient navázat spojení. Firewall vrací kladnou nebo zápornou odpověď.

Příkaz BIND

Příkazem BIND sděluje klient firewallu, že je připraven akceptovat na uvedeném portu spojení. Příkaz se využívá např. při zřizování datového kanálu protokolu FTP.

 Protokol FTP používá spojení na portu 21. Tímto kanálem se posílají příkazy (např. put, get, dir atd.). V případě, že nějakým příkazem byl požadován přenos dat (přenos souboru), pak se otevírá další kanál (spojení protokolem TCP) implicitně na portu 20. Pro tento druhý kanál klient funguje jakoby server.

 Klient požádá firewall příkazem BIND, aby jeho jménem fungoval jako server. Firewall vrátí v první odpopvědi port na kterém bude příjímat od vzdáleného serveru data. Klient po příkazovém kanálu sdělí číslo tohoto poru vzdálenému serveru. Vzdálený server naváže na tomto portu spojení s firewallem (jako by to byl klient). Po navázání spojení cílového serveru s firewallem firewall vrací další odpověď že došlo ke úspěšnému nebo neúspěšnému spojení mezi firewallem a cílovým serverem.

Příkaz ASSOCIATE

Příkaz ASSOCIATE slouží k vyžádání přenosu UDP-datagramu skrze firewall. Při předávání UDP-datagramu se většinou nehovoří o proxy a o relay.

 Protokolem TCP zpravidla na portu 1080 vyžádá klient od firewallu povolení k odeslání UDP-datagramu. V odpovědi dostane IP-adresu a port na který UDP-datagram odešle. V záhlaví UDP-datagramu je ale IP-adresa a port firewallu. Pro UDP-protokol však nelze zřídit spojení. Jak tedy firewall pozná že se jedná o očekávaný UDP-datagram?

 Řešení spočívá v tom, že údaji o cílovém serveru se uvodí datová část UDP-datagramu. Tj. UDP-datagram obsahuje UDP-záhlaví (na následujícím obrázku neznázorněno) následované údaji o cílovém serveru. Teprve za těmito údaji jsou vlastní přenášená data.

 Frewall vytvoří UDP-datagram, který má v UDP-záhlaví jméno a port cílového serveru a v datové čísti pouze přenášená data.

Komunikace skrze proxy se vzdáleným serverem

Případné zabezpečení přenosu dat zprostředkované protokolem SOCKS je vždy mezi klientem a firewallem, nikoliv mezi firewallem a cílovým serverem.

 SOCKS je tedy nástroj, který umožňuje zejména připojení autentizovaných uživatelů z Internetu do vnitřní sítě. Předpokládáme, že vnitřní síť je natolik bezpečná, že je v ní možný již nezabezpečený přenos dat. SOCKS není určen pro vytváření bezpečných tunelů mezi klientem a cílovým serverem skrze firewall. Klient se vždy autentizuje proti firewallu nikoliv proti cílovému serveru.

 V případě požadavku na zabezpečení přenosu mezi firewallem a cílovým serverem by se musela autentizovat klientská část firewallu proti cílovému serveru, tj. autentizoval by se firewall jako takový (nikoliv jednotliví klienti!).

Konfigurace SOCKS serveru na UNIXu

SOCKS server je jako každý jiný server. Můžeme jej tedy spouštět pomocí super serveru inetd. Bude-li náš SOCKS server očekávat požadavky klientů na portu 1080, pak do souboru /etc/services přidáme řádek:

socks 1080/tcp

a dále do souboru /etc/inetd.conf přidáme řádek:
 
 

socks   stream  tcp     nowait  /usr/sbin/sockd sockd
Předpokládáme, že SOCKS server je realizován programem /usr/sbin/sockd.

Tím máme zajištěno startování SOCKS serveru. Nyní zbývá vytvořit konfiguraci, která je uložena v textovém souboru sockd.conf. Konfigurace se skládá z jednotlivých řádků, které mají obecně syntaxi:
 
 

akce    [seznam uživatelů] adr.odesil. maska_odesil. [adr.příj. maska_příj.][relace port][ : příkaz]