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:
Klient nabídne SOCKS-serveru metody, které podporuje. SOCKS-server
z nich vybere jednu. Klient se pak na základě této metody autentizuje.
Metoda může v sobě zahrnovat i požadavek na šifrování a elektronické podepisování
přenášených dat mezi klientem a SOCKS-serverem. V takovém případě po prokázání
totožnosti běží veškerý provoz zabezpečeně (šifrovaně, případně elektonicky
podepisován).
Autentizační dialog závisí na zvolené metodě. Tč. je normalizová
metoda autentizace pomocí jména a hesla uživatele (RFC-1929), metoda GSS-API
(RFC-1961) a pochopitelně metoda bez autentizace (blíže viz přímo RFC-1928).
Metoda bez autentizace je metoda, kdy od klienta není vyžadován žádný autentizační
dialog. Avšak SOCKS-server je přesto schopen provést autentizaci na základě
IP-adresy klienta.
Teprve po autentizačním dialogu SOCKS-server příjme od klienta
požadavek na jehož základě začne pro klienta fungovat jako proxy.
Klient protokolem SOCKS předá požadavky SOCKS-serveru, který běží na hraničním počítači mezi Intranetem a Internetem (jedná se zpravidla o firewall).
Klient vydává požadavek CONNECT či BIND pro protokol TCP a požadavek
ASSOCIATE pro protokol UDP.
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).
Nyní nám zbývá SOCKS-protokol.
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čí.
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 ú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ší:
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).
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ěď.
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.
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.
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!).
socks 1080/tcp
a dále do souboru /etc/inetd.conf přidáme řádek:
socks stream tcp nowait /usr/sbin/sockd sockdPř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]