Skip to content

Instantly share code, notes, and snippets.

@nikelborm
Created December 30, 2020 12:39
Show Gist options
  • Save nikelborm/937f08913b9e2af7e5c459e8e3a68793 to your computer and use it in GitHub Desktop.
Save nikelborm/937f08913b9e2af7e5c459e8e3a68793 to your computer and use it in GitHub Desktop.
vpn test
#!/bin/bash
if [[ $1 == '' ]]; then echo -e "Укажите номер порта который нужно слушать"; exit; fi
iface=`ip route get 8.8.8.8 | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`
a=0
until (( $a == 500)); do
packet=`tcpdump -i $iface udp port $1 -vvn -c1 -A`
if [[ "$packet" == *"Ident"* ]]; then
pack=`echo "$packet" | grep -e "udp sum ok" -e "Ident"`
myip=`echo $pack | sed 's/\./ /g' | awk '{print $1"."$2"."$3"."$4}'`
myport=`echo $pack | sed 's/\./ /g' | awk '{print $5}'`
id=`echo $pack | sed 's|.*Ident:||' | awk '{print $1}'`
myname=`echo $pack | sed 's|.*Ident:||' | awk '{print $2}'`
echo "$myip:$myport $myname" > /tmp/vpn2-$id-$myname
echo "MyData $myip:$myport $(cat /tmp/vpn2-$id-* | grep -v $myname | awk {'print $1'})" | nc $myip $myport -u -p $1 -w 1
cat /tmp/vpn2-$id-*
topoint=`cat /tmp/vpn2-$id-* | grep -v "$myname" | sed 's/:/ /g'`
if [[ $topoint != '' ]]; then
ip=`echo $topoint | awk '{print $1}'`
port=`echo $topoint | awk '{print $2}'`
echo "MyData $ip:$port $(cat /tmp/vpn2-$id-* | grep $myname | awk {'print $1'})" | nc $ip $port -u -p $1 -w 1
fi
fi
done
#!/bin/bash
######################## Задаем цветной текст ###
WARN='\033[37;1;41m' #
END='\033[0m' #
RED='\033[0;31m' # ${RED} #
GREEN='\033[0;32m' # ${GREEN} #
#################################################
####################### Проверяем наличие необходымих приложений #########################################################
al="ip echo readlink dirname ps grep awk kill md5sum shuf nc curl sleep openvpn tcpdump cat"
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 /<путь к файлу>/vpn7.sh > /var/log/vpn7.log 2>/dev/hull & ${END}"; exit; fi
ABSOLUTE_FILENAME=`readlink -f "$0"` # полный путь до скрипта
DIR=`dirname "$ABSOLUTE_FILENAME"` # каталог в котором лежит скрипт
############################### Проверка наличия и загрузка конфигурационного файла ##################################
cfg="$DIR/vpn.cfg"
if [[ -f "$cfg" ]]; then
echo "$(date) Загружаю конфигурационный файл $cfg"
source "$cfg"
else
echo "$(date) Конфигурационный файл не обнаружен!"
fi
############################### Проверка наличия секретного ключа ##################################
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
#########################################################################################
localport=`shuf -i 20000-65000 -n 1` # Выбор локального порта
name=`uname -n | md5sum | awk '{print $1}'` # Имя узла
ipsrv="45.141.103.45" # IP-адрес сервера получения данных о второй стороне
portsrv="13013"
############################### Запуск цикла ###########
until [[ $count > 100 ]]; do
#########################################################################################
until [[ -n "$iftosrv" ]]; do echo "$(date) Определяю сетевой интерфейс"; iftosrv=`ip route get $ipsrv | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`; sleep 5; done # Определение интерфейса
netcattosrv="nc -u $ipsrv $portsrv -p $localport -w 1" # Команда посылки пакета NC
tcpdumptosrv="tcpdump -i $iftosrv udp and src port $portsrv and src $ipsrv and dst port $localport -n -c1 -A" # Команда приема пакета
id=`echo $1| md5sum | awk '{print $1}'` # Преобразеум имя узла в md5 что бы не светить реальное имя
##################### Получение данных о себе и удаленного узла ###################################
echo -e "$(date) ${GREEN}Фаза 1 - Получение данных с сервера $ipsrv:$portsrv ${END}"
echo -e "$(date) ${GREEN}Использую интерфейс $iftosrv и локальный порт $localport ${END}"
until [[ -n "$ip" && -n "$port" ]]; do
if [[ -z "$data" ]]; then
sleep 1 && echo "Ident: $id $name" | $netcattosrv > /dev/null &
sleep 4 && pid=`ps xa | grep "$tcpdumptosrv" | grep -v grep | awk '{print $1}'` && if [[ -n $pid ]]; then kill $pid; echo "$(date) Нет ответа от сервера, пробую еще раз..."; fi &
data=`$tcpdumptosrv`
sleep 2
fi
if [[ -n "$data" ]]; then
#echo "Ответ: $data"
data=`echo "$data" | grep "MyData" | sed 's|.*MyData ||' | sed 's/:/ /g'`
myip=`echo "$data" | awk '{print $1}'`
myport=`echo "$data" | awk '{print $2}'`
ip=`echo "$data" | awk '{print $3}'`
port=`echo "$data" | awk '{print $4}'`
data=''
if [[ -z $tst ]]; then echo -e "$(date) ${GREEN}Мой внешний IP: $myip и порт: $myport ${END}"; fi
if [[ -n $localport && -n $myport && -z $tst ]];then
if [[ $localport == $myport ]]; then
echo -e "$(date) ${GREEN}Мой локальный порт $localport и внешний порт $myport одиноковые, используется CONE NAT ${END}"; tst=1
else
echo -e "$(date) ${RED}Мой локальный порт $localport и внешний порт $myport разные, используется SYMMETRIC NAT ${END}"; tst=1
fi
fi
fi
if [[ -n "$ip" && -n "$port" ]]; then
echo -e "$(date) ${GREEN}Получил данные об удаленном узле: IP: $ip Порт: $port, переходим на следующий этап... ${END}";
else
sleep=`shuf -i 30-45 -n 1`;
echo -e "$(date) ${RED}Нет данных удаленного узла, возможно он еще не вышел на связь, ожидаю данных $sleep секунд и проверяю еще раз... ${END}";
sleep $sleep && pid=`ps xa | grep "$tcpdumptosrv" | grep -v grep | awk '{print $1}'` && if [[ -n $pid ]]; then kill $pid; fi &
data=`$tcpdumptosrv`
fi
done
###################### Организация соединения с удаленным узлом
iftopeer=`ip route get "$ip" | head -n 1 | sed 's|.*dev ||' | awk '{print $1}'`
echo -e "$(date) ${GREEN}Фаза 2 - Установка соединения с удаленным узлом $ip:$port${END}"
echo -e "$(date) ${GREEN}Попытка установки соединения: $myip:$myport -> $ip:$port ${END}"
m=0
t=0
connect=0
until (( $connect >= 10 )); do
if [ -z "$oktet" ]; then
echo "$(date) Октета нет, генерирую и сохраняю в $cfg"
oktet=`shuf -i 0-254 -n 1`
echo "oktet=$oktet" >> $cfg
fi
netcattopeer="nc -u $ip $port -p $localport -w 1"
tcpdumptopeer="tcpdump -i $iftopeer udp and port $localport and src "$ip" -n -c1 -A"
until (( $m >= 10 )); do
for w in {1..3}; do
for pid1nc in `ps xa | grep "$netcattopeer" | grep -v grep | awk '{print $1}'`;do kill $pid1nc; done;
echo "445Hi: $m $oktet" | $netcattopeer > /dev/null &
sleep 1
for pidnc in `ps xa | grep "$netcattopeer" | grep -v grep | awk '{print $1}'`;do kill $pidnc; done
done &
sleep 4 && pid=`ps xa | grep "$tcpdumptopeer" | grep -v grep | awk '{print $1}'` && sleep 10 && if [[ -n $pid ]]; then kill $pid && echo -e "$(date) ${RED} Нет ответа от пира, пробую еще раз... ${END}"; fi &
peer=`$tcpdumptopeer`
if [[ -n $peer ]]; then
newport=`echo "$peer" | grep " IP " | sed "s|.* $ip.||" | awk '{print $1}'`
if (( $newport != $port )); then
echo -e "$(date) ${WARN}Порт изменился $port -> $newport ${END}";
port=$newport;
netcattopeer="nc -u $ip $port -p $localport -w 1"
fi
mm=`echo "$peer" | grep "445Hi: " | sed 's|.*445Hi: ||' | awk '{print $1}'`
echo -e "$(date) ${GREEN} Получил: $mm - передаю: $mm+1 ${END}"
if (( $m <= $mm )); then
m=$(( $mm + 1 ));
fi
text=`echo "$peer" | grep "445Hi: " | sed 's|.*445Hi: ||' | awk '{print $2}'`
else
(( t++ ))
echo -e "$(date) ${RED} Данных нет $t раз ${END}"
if (( $t > 5 ));then echo -e "$(date) ${RED} Превышен интервал ожидания, переподключаюсь ${END}"; m=10; connect=1012; ip=''; port=''; fi
fi
done
if (( $connect < 1012 )); then
echo -e "$(date) ${GREEN}Значение: $m ${END}"
if [[ -n $endoktet ]]; then echo "$(date) Обнаружен конечный октет = $endoktet"
if [[ $endoktet == 1 ]]; then
ipaddress="10.$text.$oktet.1"
else
ipaddress="10.$oktet.$text.2"
fi
else
echo "$(date) Не обнаружен конечный октет, генерирую и сохраняю в $cfg"
if [[ $port > $myport ]]; then
ipaddress="10.$text.$oktet.1"
echo "endoktet=1" >> $cfg
else
ipaddress="10.$oktet.$text.2"
echo "endoktet=2" >> $cfg
fi
fi
m=12
for w in {1..9}; do
for pid2nc in `ps xa | grep "$netcattopeer" | grep -v grep | awk '{print $1}'`;do kill $pid2nc; done;
echo "445Hi: $m $oktet" | $netcattopeer > /dev/null; sleep 0.5;
done
for pidnc in `ps xa | grep "$netcattopeer" | grep -v grep | awk '{print $1}'`; do
kill $pidnc && echo -e "$(date) ${RED}Завершен процесс $pidnc (NetCat) для освобождения порта $localport${END}";
done
rpfilter=`cat /proc/sys/net/ipv4/conf/all/rp_filter`
if [[ $rpfilter == 1 ]]; then
echo -e "$(date) ${GREEN}rp_filter=$rpfilter - активна защита от подмены адресов (спуфинга)${END}";
else
echo -e "$(date) ${RED}Внимение, rp_filter=$rpfilter! Включаю (sysctl -w net.ipv4.conf.all.rp_filter=1) «строгий режим» проверки для защиты от подмены адресов (спуфинга) ${END}";
sysctl -w net.ipv4.conf.all.rp_filter=1
fi
echo -e "$(date) ${GREEN} Запускаюсь... IP-адрес: $ipaddress...${END}"
$(which lsmod) | grep tun || $(which modprobe) tun
openvpn --remote $ip --rport $port --lport $localport \
--proto udp --dev tap --float --auth-nocache --verb 3 --mute 20 \
--ifconfig "$ipaddress" 255.255.255.252 \
--secret "$DIR/secret.key" \
--auth SHA256 --cipher AES-256-CBC \
--ncp-disable --ping 10 --ping-exit 40 \
--comp-lzo yes
echo -e "$(date) ${RED} Соединение прервано... ${END}"
m=0
t=0
(( connect++ ));
fi
done
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment