Предыстория
Для подключение к компьютерам офиса/ов и VDS (виртуальные машина) в облаке требуется использовать защищённое соединение до сервером и иметь доступ к локальным сетям за ними. Для этой задачи был выбран OpenVPN. В тех точках, куда необходимо было подключаться, был установлен OpenVPN-сервер, уточню, софт ставился на сервера под CentOS 5/6, а не роутеры. Клиентам, которым требовалось подключаться к ресурсам сервера и локальной сети за ним, либо программно, либо через роутеры настраивались OpenVPN-клиенты. Между офисами связь также настраивалась по OpenVPN. Компьютеры за клиентом и сервером видели друг друга без проблем.
NDMS v1
Начиная с 2014, года когда вышла 11 версия прошивки для NDMS v1, активно использовал возможности по установке opkg-пакетов, в последствии от всего многообразия оставил только OpenVPN и Asterisk. Сразу скажу, что с установкой прошивки или openvpn проблем не возникало, то ли так повезло, то ли уже к этому моменту основные проблемы были решены.
OpenVPN использовал в качестве клиента, а точнее сразу трёх, три различные файла конфигурации.
Типовой файлы конфигурации сервера (собирался путём сёрфинга и личного опыта в течение некоторого времени):
Код: Выделить всё
port 3223 # по-умолчанию порт 1194
# на сайте разработчиков рекомендуется использовать udp в том числе
# по соображениям безопасности
proto udp
#указание типа интерфейса и режима работы
#tun = L3-туннель, tap = L2-туннель
dev tap
# работа в режиме сервера
mode server
# главный SSL/TLS сертификат (ca)
# сертификат (cert), частный ключ (key).
# каждый клиент и сервер имеет собственные пары сертификата и ключа.
# Сервер и все его клиенты должны иметь один (ca).
ca "/etc/openvpn/keys/ca.crt"
cert "/etc/openvpn/keys/server.crt"
key "/etc/openvpn/keys/server.key" # Этот файл хранить в секрете!
dh "/etc/openvpn/keys/dh1024.pem"
# включаем TLS аутификацию
tls-server
# указываем tls-ключ, и указываем 0 для сервера, а 1 для клиента
tls-auth "/etc/openvpn/keys/ta.key" 0
# таймаут до реконекта
tls-timeout 120
auth MD5
# задаем IP-адрес сервера и маску подсети
server 172.16.31.0 255.255.255.0
# добавляем маршрут сервер-клиент
route 192.168.17.0 255.255.255.0 172.16.41.2
route 10.1.1.0 255.255.255.0 172.16.41.3
# путь сохранения IP-адресов клиентов, файл собирается самим OpenVPN
ifconfig-pool-persist "/etc/openvpn/config/ipp.txt"
# config-файлы для клиентов, в этих файлах можно дополнительно указать правила роутинга, например
# ifconfig-push 172.16.41.2 255.255.255.0 - зададим адрес клиенту
# push "route 10.1.1.0 255.255.255.0 172.16.41.1" - добавим клиенту путь для сети 10.1.1.0/24
# и т.д.
client-config-dir /etc/openvpn/ccd
# удерживать соединение (полезно при работе через nat, proxy и т.п.)
keepalive 10 120
# включаем шифрацию пакетов
cipher BF-CBC
# включить сжатие
comp-lzo
# максимум клиентов
max-clients 5
user nobody
group nobody
# Не перечитывать ключи после получения
# SIGUSR1 или ping-restart
persist-key
# Не закрывать и переоткрывать TUNTAP
# устройство, после получения
# SIGUSR1 или ping-restart
persist-tun
# клиенты могут "видеть" друг друга (для tun)
#client-to-client
status "/etc/openvpn/log/status.log"
log "/etc/openvpn/log/openvpn.log"
log-append "/etc/openvpn/log/openvpn.log"
# уровень детализации отчетов
verb 3
Типовой файл конфигурации клиента:
Код: Выделить всё
client
dev tap2
proto udp
# IP-адрес и порт сервера OpenVPN
remote 1.2.3.4 3223
resolv-retry infinite
nobind
persist-key
persist-tun
# Пути до ключей и сертификатов
ca "/opt/etc/openvpn/keys/h1/ca.crt"
cert "/opt/etc/openvpn/keys/h1/office.crt"
key "/opt/etc/openvpn/keys/h1/office.key"
tls-client
tls-auth "/opt/etc/openvpn/keys/h1/ta.key" 1
tls-timeout 120
auth MD5
#Это еще одна защита, на этот раз от "man in the middle" атаки
ns-cert-type server
comp-lzo
status "/opt/etc/openvpn/log/h1/status.log"
log "/opt/etc/openvpn/log/h1/openvpn.log"
log-append "/opt/etc/openvpn/log/h1/openvpn.log"
# уровень детализации отчетов
verb 3
Как видно из конфигурации всегда использовался tap L2-туннель. Проблем с установкой не возникало. Все ключи генерировались на сервере и потом размещались у клиентов. К основным настройкам приведены комментарии.
Чтобы увидеть сеть за сервером использовал iptables:
Код: Выделить всё
#!/bin/sh
IPF="/sbin/iptables"
NAT="/sbin/iptables -t nat"
MNG="/sbin/iptables -t mangle"
# VPN-интерфейс (у вас может быть другой)
VPN_IF=tap0
# разрешаем трафик между локальными сетями только через VPN-интерфейс
$IPF -A FORWARD -i $VPN_IF -o $VPN_IF -d 192.168.17.0/24 -s 10.1.1.0/24 -j ACCEPT
$IPF -A FORWARD -i $VPN_IF -o $VPN_IF -s 192.168.17.0/24 -d 10.1.1.0/24 -j ACCEPT
Аналогичный код размещался на клиентах (роутерах либо серверах, которые также выступали в роли VPN-клиентов).
Для кинетика с NDMS v1 использовался скрипт запуска (путь /opt нужно заменить на /media/DISK_A1/system):
Код: Выделить всё
#!/bin/sh
MOUNT="/opt"
WORK=$MOUNT/etc/openvpn
export PATH=$MOUNT/bin:$MOUNT/sbin:$MOUNT/usr/bin:$MOUNT/usr/sbin:/sbin:/usr/sbin:/bin:/usr/bin
export LD_LIBRARY_PATH=$MOUNT/lib:$MOUNT/usr/lib:/lib:/usr/lib
success() {
[ -n $1 ] && echo "success" || echo "$1: success"
}
failure() {
[ -n $1 ] && echo "failed" || echo "$1: failed"
}
start() {
echo ""
echo "Loading OpenVPN kernel modules:"
insmod /lib/modules/2.6.22-tc/tun.ko
# Make sure IP forwarding is enabled
echo 1 > /proc/sys/net/ipv4/ip_forward
# Proxy arp usuaslly is not needed
# echo 1 > /proc/sys/net/ipv4/conf/br0/proxy_arp
# Make device if not present (not devfs)
if ( [ ! -c /dev/net/tun ] ) then
# Make /dev/net directory if needed
if ( [ ! -d /dev/net ] ) then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
fi
echo ""
echo -n "Starting OpenVPN in daemon mode...."
cd $WORK
# Start every .conf in $WORK
errors=0
successes=0
for c in `/opt/bin/ls *.conf 2>/dev/null`; do
$MOUNT/sbin/openvpn --cd $MOUNT/etc/openvpn --daemon --config $c > /dev/null 2>&1
ret=$?
if [ $ret -eq 0 ]; then
successes=1
else
errors=1
fi
done
if [ $errors = 1 ]; then
failure; echo
else
success; echo
fi
#$MOUNT/usr/sbin/openvpn --cd $MOUNT/etc/openvpn --daemon --script-security 2 --config openvpn.conf > /dev/null 2>&1
#ret=$?
#[ $ret -eq 0 ] && success || failure
}
stop() {
echo ""
echo -n "Killing OpenVPN processes...."
if [ -n "`pidof openvpn`" ]; then
killall openvpn 2>/dev/null
fi
ret=$?
[ $ret -eq 0 ] && success || failure
sleep 1
echo ""
echo "Unloading OpenVPN kernel modules... "
#rmmod tun
}
restart() {
stop
sleep 3
start
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
link_up)
;;
ppp_up)
;;
link_down)
;;
ppp_down)
;;
*)
echo "Usage: $0 {start|stop|restart|link_up|link_down|ppp_up|ppp_down}"
;;
esac
Данный скрипт был размещен на старом форуме http://forum.zyxmon.org/topic110-openvpn-keenetic.html
Сервис работал стабильно, сбоев за 2 года использования не припомню (не забывайте обновлять ключи).
Теперь про NDMS v2
При выборе нового модема решили проверить на каком этапе сейчас находится NDMS v2 с прошивкой Entware Keenetic.
Установка NDMS v2 и Entware Keenetic совсем несложное дело, всё делается через веб-интерфейс. После установка EK, заходим по SSH и также устанавливаем пакеты.
Код: Выделить всё
opkg install openvpn-opensll libopenssl
Процесс практически идентичен как и в первой версии. Но, есть отличия.
Поменялись системные правила iptables, теперь маскарадинг (по-простому скрытие внутреннего IP и работа через адрес шлюза) включен для всех нелокальных интерфейсов, взято здесь http://forums.zyxmon.org/viewtopic.php?f=5&t=5344. По-большому счёту это ничего не меняет, на OpenVPN-сервере нужно дополнительно прописать одно правило, оно позволяет принимать пакеты с VPN-интерфейса на локальном интерфейсе в соответствующих сетях. В данном случае 192.168.17.0/24 - локальная сеть, 172.16.41.0/24 - VPN-сеть.
Код: Выделить всё
$IPF -A FORWARD -i $VPN_IF -o $LOCAL_IF -d 192.168.17.0/24 -s 172.16.41.0/24 -j ACCEPT
Прошу учитывать, что все адреса и подсети в вашем случае будут другие!
Также для прошивки версии NDMS v2 v2.06(AAFS.2)C0 + Entware Keenetic в веб-интерфейсе на вкладках
Домашняя сеть > Устройства, а также Системный монитор > Соединения || Клиенты Wi-Fi
стала появляться ошибка
unable to find tap1 in Network::Interface::IP container
Это ошибка именно веб-интерфейса, а не OpenVPN, он работает также стабильно.
Важно, поменялся скрипт запуска OpenVPN для нескольких файлов конфигураций. Теперь нужно будет поработать руками, вариантов реализации может быть несколько. Самый простой сделать несколько файлов сервисов для OpenVPN как указано здесь http://forum.keenetic.net/topic/19-openvpn/?page=2, либо собрать файл самостоятельно, что загружалось всё одним разом (приводит к небольшому дублированию кода)
Код: Выделить всё
#!/bin/sh
#
# Startup script for openvpn server
#
ACTION=$1
CALLER=$2
ansi_red="\033[1;31m";
ansi_white="\033[1;37m";
ansi_green="\033[1;32m";
ansi_yellow="\033[1;33m";
ansi_blue="\033[1;34m";
ansi_bell="\007";
ansi_blink="\033[5m";
ansi_std="\033[m";
ansi_rev="\033[7m";
ansi_ul="\033[4m";
# Make sure IP forwarding is enabled
echo 1 > /proc/sys/net/ipv4/ip_forward
# Make device if not present (not devfs)
if ( [ ! -c /dev/net/tun ] ) then
# Make /dev/net directory if needed
if ( [ ! -d /dev/net ] ) then
mkdir -m 755 /dev/net
fi
mknod /dev/net/tun c 10 200
fi
# Make sure the tunnel driver is loaded
#if ( !(lsmod | grep -q "^tun") ); then
# insmod /opt/lib/modules/tun.ko
#fi
ENABLED=yes
PROCS=openvpn
ARGS="--daemon --cd /opt/etc/openvpn --config openvpn.conf"
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
start() {
[ "$CRITICAL" != "yes" -a "$CALLER" = "cron" ] && return 7
[ "$ENABLED" != "yes" ] && return 8
echo -e -n "$ansi_white Starting $DESC... "
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_yellow already running. $ansi_std"
return 0
fi
$PRECMD > /dev/null 2>&1
# вместо указания файлов в ручную можно взять кусок скрипта из версии v1 с циклом обхода каталога,
# где лежат файлы конфигурации
$PREARGS $PROC --daemon --cd /opt/etc/openvpn --config client_1.conf > /dev/null 2>&1 &
$PREARGS $PROC --daemon --cd /opt/etc/openvpn --config client_2.conf > /dev/null 2>&1 &
$PREARGS $PROC --daemon --cd /opt/etc/openvpn --config client_3.conf > /dev/null 2>&1 &
#echo $PREARGS $PROC $ARGS
COUNTER=0
LIMIT=10
while [ -z "`pidof $PROC`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
$POSTCMD > /dev/null 2>&1
if [ -z "`pidof $PROC`" ]; then
echo -e " $ansi_red failed. $ansi_std"
logger "Failed to start $DESC from $CALLER."
return 255
else
echo -e " $ansi_green done. $ansi_std"
logger "Started $DESC from $CALLER."
return 0
fi
}
stop() {
case "$ACTION" in
stop | restart)
echo -e -n "$ansi_white Shutting down $PROC... "
killall $PROC 2>/dev/null
COUNTER=0
LIMIT=10
while [ -n "`pidof $PROC`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
;;
kill)
echo -e -n "$ansi_white Killing $PROC... "
killall -9 $PROC 2>/dev/null
;;
esac
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_red failed. $ansi_std"
return 255
else
echo -e " $ansi_green done. $ansi_std"
return 0
fi
}
check() {
echo -e -n "$ansi_white Checking $DESC... "
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_green alive. $ansi_std";
return 0
else
echo -e " $ansi_red dead. $ansi_std";
return 1
fi
}
reconfigure() {
SIGNAL=SIGHUP
echo -e "$ansi_white Sending $SIGNAL to $PROC... "
killall -$SIGNAL $PROC 2>/dev/null
}
for PROC in $PROCS; do
case $ACTION in
start)
start
;;
stop | kill )
check && stop
;;
restart)
check > /dev/null && stop
start
;;
check)
check
;;
reconfigure)
reconfigure
;;
*)
echo -e "$ansi_white Usage: $0 (start|stop|restart|check|kill|reconfigure)$ansi_std"
exit 1
;;
esac
done
#logger "Leaving ${0##*/}."
На данный момент Zyxmon посоветовал http://forum.keenetic.net/topic/19-openvpn/?page=2#comment-11086 использовать другие варианты прошивок для устранения ошибки в веб-интерфейсе
Переходите на 2.08 на Giga II (только вышла). Хоть она и неофициальная, но Entware там явно стабильнее работает (лучше сразу перейти на Entware-3x).
По результатам обновлений добавлю комментарий сюда же.
Надеюсь, данный материал окажется полезен сообществу.