Настройка своего прокси-сервера для Telegram за 2.94 €

Описывается пошаговый процесс установки SOCKS5 прокси-сервера Dante в Ubuntu 16.04 на Henzner Cloud VPS и его настройка для работы прокси для мессенджера Telegram.

Регистрируемся на https://console.hetzner.cloud/

--------------2018-04-15---21.47.52

Жмем на блок Default.

--------------2018-04-15---21.48.23

Добавляем сервер:

--------------2018-04-15---21.50.01

  • выбираем датацентр поближе (например новый финский датацентр Hetzner);
  • выбираем OS Image – Ubuntu;

--------------2018-04-15---21.51.12

  • выбираем тариф (можно и дороже, но для прокси хватит и минимального CX11);

--------------2018-04-15---22.10.20

  • вводим публичную часть своего SSH-ключа (можно указать сразу, или указать позже при настройке. Как создать SSH-ключ см. статью про SSH-ключи);

  • указываем другое имя хоста, если хочется;

  • жмем «Create & Buy now»;

  • ждем, когда завершится инициализация сервера.

Проверяем почту, на которую придет логин и пароль для SSH-доступа

Логинимся по SSH на IP, который пришел в письме:
ssh -l root SERVER_IP

Меняем пароль рута на свой
passwd

Обновляем системный софт
apt update && apt upgrade

Добавляем пользователя, чтобы не работать от рута
useradd -s /bin/bash -d /home/username -m username

Добавляем пользователю пароль
passwd username

Добавляем нового пользователя в суперпользователи
gpasswd -a username sudo

Настраиваем минимальную безопасность сервера (запрет логина рутом, смена порта по умолчанию на альтернативный и т.д.)
sudo nano /etc/ssh/sshd_config

Нужно в этом файле:

Заменить:
Port 22 на Port 999
PermitRootLogin yes на PermitRootLogin no
LoginGraceTime 120 на LoginGraceTime 60
TCPKeepAlive yes на TCPKeepAlive no

Добавить cтроки:
ClientAliveCountMax 3
ClientAliveInterval 20
DebianBanner no
AllowUsers username (указать имя добавленного выше пользователя)

Закомментировать строки (добавить # в начале строки):
KeyRegenerationInterval 3600
ServerKeyBits 768
X11Forwarding yes
X11DisplayOffset 10

Затем перезагрузить SSH-cервер и залогиниться новым пользователем
sudo service ssh restart
exit
ssh -l username Server_IP -p 999

Это были самые базовые действия после приобретения сервера, теперь непосредственно установим прокси-сервер.

Настраиваем SOKS5-сервер Dante
Берем с оф.сайта из исходников последнюю версию с авторизацией (готовый пакет очень старый и без авторизации, его использовать не стоит)
cd /opt/
sudo mkdir dante-server
cd dante-server
sudo wget https://www.inet.no/dante/files/dante-1.4.2.tar.gz
sudo tar -xvf dante-1.4.2.tar.gz
cd dante-1.4.2/
sudo apt-get install build-essential libwrap0 libwrap0-dev gcc make
sudo mkdir /home/dante
sudo ./configure --prefix=/home/dante
sudo make
sudo make install

Настраиваем конфиг прокси-сервера Dante
sudo nano /home/dante/danted.conf

Добавляем содержимое файла

logoutput: syslog /var/log/sockd.log

# Адрес сетевого интерфейса, на котором danted слушает входящие соединения
internal: eth0 port = 1080
# IPv6 адрес интерфейса, опционально
# internal: Y::Y port = 1080

# Адрес, через который соединения выходят. Может быть тот же адрес, может быть и другой
external: eth0
# IPv6 адрес, аналогично
# external: Y::Y

# Опционально, если несколько internal/external
# external.rotation: same-same

clientmethod: none
# Если авторизация не нужна, можно поставить socksmethod: none
socksmethod: username

# Для того, чтобы danted мог посмотреть пользователя в /etc/passwd, но подключения не имели прав суперпользователя
user.privileged: root
user.unprivileged: nobody
user.libwrap: nobody

# Разрешить всем клиентам со всех интерфейсов
client pass {
    from: 0.0.0.0/0 to: 0.0.0.0/0
    log: error
}

# Пропускаем только трафик, идущий через адреса, связанные с telegram
# Подсети взяты из реестра IANA
# AS62041, AS44907, AS62014
socks pass {
    from: 0.0.0.0/0 to: 149.154.160.0/20
}

socks pass {
    from: 0.0.0.0/0 to: 91.108.4.0/22
}

socks pass {
    from: 0.0.0.0/0 to: 91.108.8.0/22
}

socks pass {
    from: 0.0.0.0/0 to: 91.108.16.0/21
}

socks pass {
    from: 0.0.0.0/0 to: 91.108.56.0/22
}

socks pass {
    from: ::/0 to: 2001:67c:4e8::/48
}

socks pass {
    from: ::/0 to: 2001:b28:f23c::/48
}

socks pass {
    from: ::/0 to: 2001:b28:f23f::/48
}

socks pass {
    from: 0.0.0.0/0 to: .telegram.org
}

Проверяем, что прокси-сервер работает
sudo /home/dante/sbin/sockd -f /home/dante/danted.conf

Логи можно смотреть в:
sudo tail -f /var/log/sockd.log

Убедиться, что порты прослушиваются прокси-сервером:
sudo netstat -ltupn

Теперь можно подключиться к прокси из Telegram:

IP: IP вашего сервера
Порт: 1080
логин и пароль – логин пользователя Ubuntu (кроме root)

Полезно добавить отдельного пользователя без особых прав только для SOCKS5:
sudo useradd user1234
sudo passwd user1234

Автостарт демона прокси-сервера после перезагрузки Ubuntu:
sudo nano /etc/init.d/danted

Добавляем содержимое файла:

#! /bin/bash
### BEGIN INIT INFO
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Debian SOCKS (v5) proxy control (danted)
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON="/home/dante/sbin/sockd"
DESC="Dante SOCKS 5 daemon"
PID_FILE="/var/run/sockd.pid"
CONFIG_FILE="/home/dante/danted.conf"
PASSWD_FILE="/home/dante/sockd.passwd"

test -f $DAEMON || exit 0
test -f $CONFIG_FILE || exit 0

[ -f /etc/init.d/functions ] && . /etc/init.d/functions
[ -f /etc/default/sockd ] && . /etc/default/sockd
[ -f /etc/default/color ] && . /etc/default/color

LOG_FILE=$(grep '^logoutput' ${CONFIG_FILE} | sed 's/.*logoutput: \(.*\).*/\1/g')

start_daemon_all(){
      if [ -z "$(command -v start-stop-daemon)" ];then
        echo -e "${CRED}start-stop-daemon not exist! ${CEND}"
        return 1
      fi

      if [ -s $PID_FILE ] && [ -n "$( ps aux | awk '{print $2}'| grep "^$(cat $PID_FILE)$" )" ];then
           echo -e "${CRED}Danted Server [ Running;Failed ] ${CEND}"
           return 0
      fi

      if ! egrep -cve '^ *(#|$)' \
         -e '^(logoutput|user\.((not)?privileged|libwrap)):' $CONFIG_FILE > /dev/null
      then
          echo -e "${CRED}Danted Server [ not configured ] ${CEND}"
          return 0
      fi

      cp /dev/null $PID_FILE

      start-stop-daemon --start --quiet --background --oknodo --pidfile $PID_FILE \
                --exec $DAEMON -- -f ${CONFIG_FILE} -D -p $PID_FILE

      sleep 3
      
      if [ -s $PID_FILE ];then
          echo -e "${CGREEN}Danted Server [ Running ] ${CEND}"
      else
          echo -e "${CRED}Danted Server [ Start Failed ] ${CEND}"
      fi
}

stop_daemon_all(){
    if [ -z "$(command -v start-stop-daemon)" ];then
        echo -e "${CRED}start-stop-daemon not exist! ${CEND}"
        return 1
    fi

    if [ ! -s $PID_FILE ];then 
          echo -e "${CRED}Danted Server [ PID.LOST;Unable ] ${CEND}"
    fi

    start-stop-daemon --stop --quiet --oknodo --pidfile $PID_FILE \
        --exec $DAEMON -- -f ${CONFIG_FILE} -p $PID_FILE -N ${Start_Process} ${Sockd_Opts}

    if [ -s $PID_FILE ];then
        [ -n "$( ps aux | awk '{print $2}'| grep "^$(cat $PID_FILE)$" )" ] && \
          echo -e "${CRED}Danted Server [ Stop Failed ] ${CEND}" || \
          echo -e "${CYELLOW}Danted Server [ Stop Done ] ${CEND}"
    fi
}

force_stop_daemon(){
    ps -ef | grep ${DAEMON} | grep -v 'grep' | awk '{print $2}' | \
            while read pid; do kill -9 $pid > /dev/null 2>&1 ;done

    [ -f "$PID_FILE" ] && rm -f $PID_FILE
}

reload_daemon_all(){
    if [ -z "$(command -v start-stop-daemon)" ];then
        echo -e "${CRED}start-stop-daemon not exist! ${CEND}"
        return 1
    fi

    if [ -s $PID_FILE ];then
      if [ -z "$( ps aux | awk '{print $2}'| grep "^$(cat $PID_FILE)$" )" ];then
        echo -e "${CRED}Danted Server [ PID.DIE;Unable ] ${CEND}"
        return 1
      fi
   else
        echo -e "${CRED}Danted Server [ PID.LOST;Unable ] ${CEND}"
        return 1
   fi

   start-stop-daemon --stop --signal 1 --quiet --oknodo --pidfile $PIDFILE \
        --exec $DAEMON -- -f $CONFIGFILE -p $PIDFILE -N ${Start_Process} ${Sockd_Opts}


   [ -n "$( ps aux | awk '{print $2}'| grep "^$(cat $PIDFILE)$" )" ] \
      && echo -e "${CGREEN}Danted Server [ Running ] ${CEND}" \
      || echo -e "${CRED}Danted Server [ Failed ] ${CEND}"

}

status(){
    VERSION=$([ -f "${DAEMON}" ] && ${DAEMON} -v)

    printf "%s\n" "${CCYAN}+-----------------------------------------+$CEND"

    if [ ! -s ${PID_FILE} ];then
        printf "%s\n" "${CRED} Dante Server [ Stop ] ${CEND}"
    else
       ( [ -n "$( ps aux | awk '{print $2}'| grep "^$(cat ${PID_FILE})$" )" ] \
          && printf "%s\n" "${CGREEN} Dante Server [ Running ] ${CEND}" ) \
          || printf "%s\n" "${CRED} Dante Server [ PID.DIE;Running ] ${CEND}"
    fi

    printf "%s\n" "${CCYAN}+-----------------------------------------+$CEND"
    printf "%-30s%s\n"  "${CGREEN} Dante Version:${CEND}"  "$CMAGENTA ${VERSION}${CEND}"
    printf "%-30s\n"  "${CGREEN} Socks5 Info:${CEND}"

    grep '^internal:' ${CONFIG_FILE} | \
        sed 's/internal:[[:space:]]*\([0-9.]*\).*port[[:space:]]*=[[:space:]]*\(.*\)/\1:\2/g' | \
            while read proxy;do
                printf "%20s%s\n" "" "${CMAGENTA}${proxy}${CEND}"
            done

    if [ -s ${PASSWD_FILE} ];then
        SOCKD_USER=$(cat ${PASSWD_FILE} | while read line;do echo ${line} | sed 's/\(.*\):.*/\1/';done)
        printf "%-30s%s\n" "${CGREEN} Socks5 User:${CEND}"  "$CMAGENTA ${SOCKD_USER}${CEND}"
    fi
    printf "%s\n" "${CCYAN}+_________________________________________+$CEND"
}
add_user(){
    local User=$1
    local Password=$2
    ( [ -z "$User" ] || [ -z "$Password" ] ) && \
        echo " Error: User or password can't be blank" && return 0
    [ ! -f "${PASSWD_FILE}" ] && opt=" -c "
    [ -f "/usr/bin/htpasswd" ] && /usr/bin/htpasswd ${opt} -d -b ${PASSWD_FILE} ${User} ${Password} || \
        echo " Error: /usr/bin/htpasswd not exist. please install apache2-utils"
}
del_user(){
    local User=$1
    [ -z "$User" ] && echo " Error: User Name can't be blank" && return 0
    [ -f "/usr/bin/htpasswd" ]  && /usr/bin/htpasswd -D ${PASSWD_FILE} ${User} || \
        echo " Error: /usr/bin/htpasswd not exist. please install apache2-utils"
}
clear_log(){
    [ -f "$PID_FILE" ] && rm -f $PID_FILE
    [ -f "$LOG_FILE" ]  && cp /dev/null $LOG_FILE
}
tail_log(){
    local LOG_FILE="$1"
    [ -f ${LOG_FILE} ] && tail -f ${LOG_FILE}
}
case "$1" in
  start)
    echo "Starting $DESC: "
    start_daemon_all
    ;;
  stop)
    echo "Stopping $DESC: "
    stop_daemon_all
    ;;
  force-stop)
    echo "Stopping $DESC: [Force]"
    force_stop_daemon
    ;;
  reload)
    echo "Reloading $DESC configuration files."
    reload_daemon_all
    ;;
  restart)
    echo "Restarting $DESC: "
    stop_daemon_all
    force_stop_daemon
    sleep 1
    start_daemon_all
    ;;
  status|state)
    clear
    status
    ;;
  adduser)
    echo "Adding User For $DESC: "
    add_user "$2" "$3"
    ;;
  deluser)
    echo "Clearing User For $DESC: "
    del_user "$2"
    ;;
  tail)
     echo "==> ${LOG_FILE} <=="
     tail_log "${LOG_FILE}"
    ;;
  conf)
      echo "==> ${CONFIG_FILE} <=="
      cat ${CONFIG_FILE}
    ;;
  *)
    N=/etc/init.d/sockd
    echo " Usage: $N {start|stop|restart|reload|status|state|adduser|deluser|tail|conf|update}" >&2
    exit 1
    ;;
esac
exit 0

Добавляем скрипт в автозапуск:
sudo update-rc.d danted defaults
sudo update-rc.d danted enable

Готово. Ваш прокси для мессенджера Телеграм работает.

on telegram, ubuntu, dante