Директан ВПН тунел између рачунара преко НАТ-ова провајдера (без ВПС-а, користећи СТУН сервер и Иандек.диск)

Продужетак Чланак о томе како сам успео да организујем директан ВПН тунел између два рачунара која се налазе иза НАТ провајдера. У претходном чланку је описан процес организовања везе уз помоћ треће стране – посредника (изнајмљени ВПС који делује као СТУН сервер и чворни предајник података за везу). У овом чланку ћу вам рећи како сам се снашао без ВПС-а, али су посредници остали а они су били СТУН сервер и Иандек.Диск...
Директан ВПН тунел између рачунара преко НАТ-ова провајдера (без ВПС-а, користећи СТУН сервер и Иандек.диск)

Увод

Након што сам прочитао коментаре претходног поста, схватио сам да је главни недостатак имплементације био коришћење посредника - треће стране (ВПС) који је указивао на тренутне параметре чвора, где и како да се повеже. Узимајући у обзир препоруке за коришћење овог СТУН (којих има доста) за одређивање тренутних параметара везе. Пре свега, одлучио сам да користим ТЦПДумп да погледам садржај пакета када СТУН сервер ради са клијентима и добија потпуно нечитљив садржај. Гуглајући протокол на који сам наишао чланак који описује протокол. Схватио сам да не могу сам да имплементирам захтев на СТУН сервер и ставим идеју у „удаљену кутију“.

Теорија

Недавно сам морао да инсталирам СТУН сервер на Дебиан из пакета

# apt install stun-server

а у зависностима сам видео пакет стун-цлиент, али некако нисам обраћао пажњу на то. Али касније сам се сетио пакета стун-цлиент и одлучио да схватим како функционише, након гуглања и претраживања у Иандек-у, добио сам:

# apt install stun-client
# stun stun.ekiga.net -p 21234 -v

Као одговор добио сам:

СТУН клијент верзија 0.97
Отворен порт 21234 са фд 3
Отворен порт 21235 са фд 4
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 0

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Примљена омамљујућа порука: 92 бајта
Мапирана адреса = <Мој ИП>:2885
СоурцеАддресс = 216.93.246.18:3478
Промењена Адреса = 216.93.246.17:3479
Непознати атрибут: 32800
Име сервера = Вовида.орг 0.98-ЦПЦ
Примљена порука типа 257 ид=1
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 0

Спрема се слање поруке од лен 28 на 216.93.246.17:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 0

Спрема се слање поруке од лен 28 на <Мој ИП>:2885
Примљена омамљујућа порука: 28 бајта
Захтев за промену = 0
Примљена порука типа 1 ид=11
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 0

Спрема се слање поруке од лен 28 на 216.93.246.17:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Примљена омамљујућа порука: 92 бајта
Мапирана адреса = <Мој ИП>:2885
СоурцеАддресс = 216.93.246.17:3479
Промењена Адреса = 216.93.246.18:3478
Непознати атрибут: 32800
Име сервера = Вовида.орг 0.98-ЦПЦ
Примљена порука типа 257 ид=10
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 4

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
Кодирање поруке запрепашћења:
Захтев за промену кодирања: 2

Спрема се слање поруке од лен 28 на 216.93.246.18:3478
тест И = 1
тест ИИ = 0
тест ИИИ = 0
тест И(2) = 1
је нат = 1
мапирани ИП исти = 1
укосница = 1
порт за чување = 0
Примарни: Независно мапирање, филтер зависан од порта, насумични порт, укосница
Повратна вредност је 0к000006

Стринг са вредношћу

Мапирана адреса = <Мој ИП>:2885

само оно што вам треба! Приказао је тренутни статус везе на локалном УДП порту 21234. Али ово је само пола битке, поставило се питање како пренети ове податке на удаљени хост и организовати ВПН везу. Користећи маил протокол, или можда Телеграм?! Постоји много опција и одлучио сам да користим Иандек.диск, пошто сам наишао чланак о раду Цурл преко ВебДав-а са Иандек.диск. Након размишљања о имплементацији, дошао сам до следеће шеме:

  1. Сигнализирајте да су чворови спремни да успоставе везу присуством одређене датотеке са временском ознаком на Иандек.диск;
  2. Ако су чворови спремни, примајте тренутне параметре са СТУН сервера;
  3. Отпремите тренутна подешавања на Иандек.диск;
  4. Проверите присуство и прочитајте параметре удаљеног чвора из датотеке на Иандек.диск;
  5. Успостављање везе са удаљеним хостом користећи ОпенВПН.

Пракса

После малог размишљања, узимајући у обзир искуство из прошлог чланка, брзо сам написао сценарио. Ми требамо:

# apt install openvpn stun-client curl 

Сама скрипта:

оригинална верзија

# cat vpn8.sh

#!/bin/bash
######################## Задаем цветной текст ###
WARN='33[37;1;41m'				#
END='33[0m'					#
RED='33[0;31m'         #  ${RED}		#
GREEN='33[0;32m'      #  ${GREEN}		#
#################################################
####################### Проверяем наличие необходымих приложений #########################################################
al="echo readlink dirname grep awk md5sum shuf nc curl sleep openvpn cat stun"
ch=0
for i in $al; do which $i > /dev/null || echo -e "${WARN}Для работы необходим $i ${END}"; which $i > /dev/null || ch=1; done
if (( $ch > 0 )); then echo -e "${WARN}Ой, отсутствуют необходимые для корректной работы приложения${END}"; exit; fi
#######################################################################################################################

if [[ $1 == '' ]]; then echo -e "${WARN}Введите идентификатор соединения (любое уникальное слово, должно быть одинаковое с двух сторон!) ${END} t
${GREEN}Для запуска в автоматическом режиме при включении компьютера можно прописать в /etc/rc.local строку nohup /<путь к файлу>/vpn8.sh  > /var/log/vpn8.log 2>/dev/hull & ${END}"; exit; fi
ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
############################### Проверка наличия секретного ключа ##################################
key="$DIR/secret.key"
if [ ! -f "$key" ]; then
				echo -e "${WARN}Секретный ключ VPN-соединения не найден, для генерации ключа выполните: 
openvpn --genkey --secret secret.key Внимание: ключ используется для авторизации и должен 
быть одинаковым с двух сторон!!!${END}
 # ls -l secret.key
 -rw------- 1 root root 637 ноя 27 11:12 secret.key
 # chmod 600 secret.key";
				exit;
				fi
########################################################################################################################

ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
name=$(uname -n | md5sum | awk '{print $1}')
vpn=$(echo $1 | md5sum | awk '{print $1}')
stun="stun.ekiga.net" 	# STUN сервер
username="Yandex"	# Логин от Яндекс.диска	
password="Password"	# Пароль от Яндекс.диска
localport=`shuf -i 20000-65000 -n 1`	# генерация локального порта

echo "$(date) Создаю папку на Яндекс.диске"
curl -X MKCOL --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn
echo "$(date) Очищаю папку от всякого мусора"
for i in `curl --silent --user "$username:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname" | sed 's/d:displayname//g' | sed 's/>//g' | sed 's/<//' | sed 's////g' | grep -v $(date +%Y-%m-%d-%H-%M)`; do
	echo "$(date) Delete: $i"
	curl -X DELETE --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn/$i
	done

until [ $c ];do

	until [[ $b ]]; do
		echo "$(date) Проверяю папку"
		date=`date +%Y-%m-%d-%H-%M`
		mydata=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep $name | grep $date | grep "d:displayname"`
		if [[ -z $mydata ]]; 	then
						echo "$(date) Файл готовности создан"
					        echo "$date" > "/tmp/$date-$name-ready.txt"
					        curl -T "/tmp/$date-$name-ready.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$date-$name-ready.txt
					else
						echo "$(date) Файл готовности уже существует - $date"
					fi
		remote=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep -v $name | grep $date | grep "d:displayname"`
		if [[ -z $remote ]];	then
						echo -e "$(date) ${RED} Удаленный узел не готов ${END}"
						echo "$(date) Жду"
						sleep 20
					else
						echo -e "$(date) ${GREEN} Удаленный узел готов ${END}"
						b=1
						a=''
					fi
	done

	until [ $a ]; do
		echo "$(date) Подключение и получение данных от STUN сервера: $stun"
                mydata=`stun $stun -p $localport -v 2>&1 | grep MappedAddress | sort | uniq`
                echo -e "$(date) ${GREEN}Мои данные соединения: $mydata${END}"
                echo "$mydata" > "$DIR/mydata"
                echo "$(date) Загрузка данных на Яндекс.диск"
                curl -T "$DIR/mydata" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$name.txt
		echo "$(date) Получение файла данных удаленного узла"
		filename=$(curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname>" | grep "txt" | grep -v "$name" | grep -v "ready" | sed 's|.*d:displayname>||' | sed 's/</ /g' | awk '{print $1}')
		echo "$(date) Чтение файла данных удаленного узла: $filename"
		address=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | sort | uniq | head -n1 | sed 's/:/ /g')
		echo "$(date) Определение IP-адреса и порта"
		ip=$(echo "$address" | awk '{print $3}')
		port=$(echo "$address" | awk '{print $4}')
		if [[ -n "$ip" && -n "$port" ]]; then
			echo -e "$(date) ${GREEN} Соединение $ip $port ${END}"
       		 	openvpn --remote $ip --rport $port --lport $localport 
	       	 	    --proto udp --dev tap --float --auth-nocache --verb 3 --mute 20 
	       	 	    --ifconfig 10.45.54.2 255.255.255.252 
	       		    --secret "$DIR/secret.key" 
	       		    --auth SHA256 --cipher AES-256-CBC 
	        	    --ncp-disable --ping 10  --ping-exit 30 
	        	    --comp-lzo yes
			echo -e "$(date) ${WARN} Соединение разорвано${END}"
			a=1
			b=''
			else
			a=1
			b=''
			fi
	done
done

Да би скрипта функционисала потребно вам је:

  1. Копирајте у међуспремник и налепите у уређивач, на пример:
    # nano vpn8.sh 
  2. наведите корисничко име и лозинку за Иандек.диск.
  3. у пољу „—ифцонфиг 10.45.54.(1 или 2) 255.255.255.252“ наведите интерну ИП адресу интерфејса
  4. Креирај тајни кључ по команди:
    # openvpn --genkey --secret secret.key 
  5. учините скрипту извршном:
    # chmod +x vpn8.sh
  6. покрените скрипту:
    # ./vpn8.sh nZbVGBuX5dtturD

    где је нЗбВГБуКс5дттурД генерисани ИД везе овде

На удаљеном чвору урадите све исто осим генерисања сецрет.кеи-а и ИД-а везе, они морају бити идентични.

Ажурирана верзија (време мора бити синхронизовано за исправан рад):

cat vpn10.sh

#!/bin/bash
stuns="stun.sipnet.ru stun.ekiga.net"   		# Список STUN серверов через пробел
username=" Login "		# Логин от Яндекс.диска
password=" Password "   	# Пароль от Яндекс.диска
intip="10.23.22.1"		# IP-адрес внутреннего интерфейса
WARN='33[37;1;41m'
END='33[0m'
RED='33[0;31m'
GREEN='33[0;32m'
al="ip echo readlink dirname grep awk md5sum openssl sha256sum shuf curl sleep openvpn cat stun"
ch=0
for i in $al; do which $i > /dev/null || echo -e "${WARN}Для работы необходим $i ${END}"; which $i > /dev/null || ch=1; done
if (( $ch > 0 )); then echo -e "${WARN}Ой, отсутствуют необходимые для корректной работы приложения${END}"; exit; fi
if [[ $1 == '' ]];
then
echo -e "${WARN}Введите идентификатор соединения (любое уникальное слово, должно быть одинаковое с двух сторон!) ${END} t
${GREEN}Для запуска в автоматическом режиме при включении компьютера можно прописать в /etc/rc.local строку nohup /<путь к файлу>/vpn10.sh  > /var/log/vpn10.log 2>/dev/hull & ${END}"
exit
fi
ABSOLUTE_FILENAME=`readlink -f "$0"`                                                    # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"`                                                      # каталог в котором лежит скрипт
key="$DIR/secret.key"
until [[ -n "$iftosrv" ]]
do
echo "$(date) Определяю сетевой интерфейс"; iftosrv=`ip route get 8.8.8.8 | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`
sleep 5
done
timedatectl
name=$(uname -n | md5sum | awk '{print $1}')
vpn=$(echo $1 | md5sum | awk '{print $1}')
echo "$(date) Создаю папку на Яндекс.диске"
curl -X MKCOL --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn
echo "$(date) ID на диске: $vpn"
until [ $c ];do
echo "$(date) Очищаю папку от всякого мусора"
for i in `curl --silent --user "$username:$password" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname" | sed 's/d:displayname//g' | sed 's/>//g' | sed 's/<//' | sed 's////g' | grep -v $(date +%Y-%m-%d-%H-%M)`
do
echo -e "$(date)${RED} Удаляю старый файл: $i${END}"
curl -X DELETE --user "${username}:${password}" https://webdav.yandex.ru/vpn-$vpn/$i
done
echo "$(date) ID на диске: $vpn"
openvpn --genkey --secret "$key"
passwd=`echo "$vpn-tt" | sha256sum | awk '{print $1}'`
openssl AES-256-CBC -e -in "$key" -out "$DIR/file.enc" -k "$passwd" -base64
curl -T "$DIR/file.enc" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/key.enc
rm "$DIR"/file.enc
echo -e "$(date) ${GREEN}Фаза 1 - Получение готовности удаленного узла${END}"
go=3
localport=`shuf -i 20000-65000 -n 1`    # генерация локального порта
start=''
remote=''
timeout1=''
nextcheck=''
timestart=''
until [[ $b ]]
do
echo "$(date) Проверяю папку"
date=`date +%s`
timeout1=60
echo "$(date) Создание файла готовности $date"
echo "$date" > "/tmp/ready-$date-$name.txt"
curl -T "/tmp/ready-$date-$name.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/ready-$name.txt
readyfile=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep -v $name | grep "ready" | grep "d:displayname" | sed 's/<d:displayname>//g' | sed 's/</d:displayname>//g'`
if [[ -z $readyfile ]]
then
echo -e "$(date) ${RED} Удаленный узел не готов ${END}"
echo "$(date) Жду 60 секунд"
sleep $timeout1
else
remote=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$readyfile)
echo -e "$(date) ${GREEN} Удаленный узел готов ${END}"
start=`curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></>n</g' | grep "start" | grep "d:displayname" | sed 's/-/ /g' | awk '{print $2}'`
if [[ -z $start ]]
then
let nextcheck=$timeout1-$date+$remote
let timestart=$date+$timeout1-$nextcheck
go=$nextcheck
echo "$timestart" > "/tmp/start-$date-$name.txt"
curl -T "/tmp/start-$date-$name.txt" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/start-$date-$name.txt
else
echo "$(date) жду $go секунд"
sleep $go
b=1
a=''
fi
fi
done
echo -e "$(date) ${GREEN}Фаза 2 - Обмен данными и установка соединения${END}"
mydata=''
filename=''
address=''
myip=''
ip=''
port=''
ex=0
until [ $a ]; do
until [[ -n "$mydata" ]]; do
k=`echo "$stuns" | wc -w`
x=1
z=`shuf -i 1-$k -n 1`
for st in $stuns; do
if [[ $x == $z ]]; then
stun=$st;
fi;
(( x++ ));
done
echo "$(date) Подключение и получение данных от STUN сервера: $stun"
sleep 5 && for pid in $(ps xa | grep "stun "$stun" 1 -p "$localport" -v" | grep -v grep | awk '{print $1}'); do kill $pid; done &
mydata=`stun "$stun" 1 -p "$localport" -v 2>&1 | grep "MappedAddress" | sort | uniq`
done
echo -e "$(date) ${GREEN}Мои данные соединения: $mydata${END}"
echo "$(date) Загрузка данных на Яндекс.диск"
echo "$mydata" > "$DIR/mydata"
echo "IntIP $intip" >> "$DIR/mydata"
curl -T "$DIR/mydata" --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$name-ipport.txt
rm "$DIR/mydata"
sleep 5
echo "$(date) Получение файла данных удаленного узла"
filename=$(curl --silent --user "${username}:${password}" -X PROPFIND -H "Depth: 1" https://webdav.yandex.ru/vpn-$vpn/ | sed 's/></n/g' | grep "d:displayname>" | grep "ipport" | grep -v "$name" |  sed 's|.*d:displayname>||' | sed 's/</ /g' | awk '{print $1}')
if [[ -n "$filename" ]]
then
echo "$(date) Чтение файла данных удаленного узла: $filename"
address=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | grep "MappedAddress" | head -n1 | sed 's/:/ /g')
intip2=$(curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/$filename | grep "IntIP" | head -n1 | awk '{print $2}')
echo "$(date) Определение IP-адреса и порта: $address $sesid2 $tunid2"
ip=$(echo "$address" | awk '{print $3}')
port=$(echo "$address" | awk '{print $4}')
myip=`ip route get "$ip" | head -n 1 | sed 's|.*src ||' | awk '{print $1}'`
if [[ -n "$ip" && -n "$port" && -n "$myip" && -n "$localport" ]];
then
echo -e "$(date) ${GREEN} Соединение $ip $port ${END}"
echo -e  "`date` ${GREEN} $myip:$localport -> $ip:$port ${END}"
curl --silent --user "$username:$password" https://webdav.yandex.ru/vpn-$vpn/key.enc > "$DIR/secret.enc"
openssl AES-256-CBC -d -in "$DIR/secret.enc" -out "$key" -k "$passwd" -base64
chmod 600 "$key"
rm "$DIR/secret.enc"
openvpn --remote $ip --rport $port --lport $localport 
--proto udp --dev tun --float --auth-nocache --verb 3 --mute 20 
--ifconfig "$intip" "$intip2" 
--secret "$key" 
--auth SHA256 --cipher AES-256-CBC 
--ncp-disable --ping 10 --ping-exit 20 
--comp-lzo yes
a=1
b=''
fi
else
if (( $ex >= 5 ))
then
echo "$(date) Сброс"
a=1
b=''
fi
(( ex++ ))
sleep 5
fi
done
done

Да би скрипта функционисала потребно вам је:

  1. Копирајте у међуспремник и налепите у уређивач, на пример:
    # nano vpn10.sh 
  2. наведите пријаву (2. ред) и лозинку за Иандек.диск (3. ред).
  3. наведите интерну ИП адресу тунела (4. ред).
  4. учините скрипту извршном:
    # chmod +x vpn10.sh
  5. покрените скрипту:
    # ./vpn10.sh nZbVGBuX5dtturD

    где је нЗбВГБуКс5дттурД генерисани ИД везе овде

На удаљеном чвору урадите исто, наведите одговарајућу интерну ИП адресу тунела и ИД везе.

За аутоматско покретање скрипте када је укључена, користим команду „нохуп /<пут до скрипте>/впн10.сх нЗбВГБуКс5дттурД > /вар/лог/впн10.лог 2>/дев/нулл &” која се налази у датотеци /етц/ рц.лоцал

Закључак

Скрипта ради, тестирана на Убунту (18.04, 19.10, 20.04) и Дебиан 9. Можете користити било који други сервис као предајник, али за искуство сам користио Иандек.диск.
Током експеримената је откривено да неки типови НАТ провајдера не дозвољавају успостављање везе. Углавном од мобилних оператера код којих су торенти блокирани.

Планирам да се побољшам у смислу:

  • Аутоматско генерисање сецрет.кеи сваки пут када покренете, шифрујте и копирајте на Иандек.диск за пренос на удаљени чвор (узимајући у обзир у ажурираној верзији)
  • Аутоматско додељивање ИП адреса интерфејсима
  • Шифровање података пре отпремања на Иандек.диск
  • Оптимизација кода

Нека ИПв6 буде у сваком дому!

Ажуриран! Најновији фајлови и ДЕБ пакет овде - иандек.диск

Извор: ввв.хабр.цом

Додај коментар