OpenVPN + MySQL

OpenVPN + User/Password аутентификация MySQL с Дневным контролем доступа. ОС Debian/Ubuntu

1. Установка сервера MySQL для проверки подлинности пользователя.

Установка MySQL Server:
apt-get install mysql-server

Авторизация MySQL под root:
mysql -uroot

Добавляем базу ‘openvpn’:
CREATE DATABASE openvpn;

Добавляем MySQL пользователя с именем ‘USERNAME’ и паролем ‘PASSWORD’:
GRANT ALL ON openvpn.* TO 'USERNAME'@"%" IDENTIFIED BY 'PASSWORD';

Выбор только что созданную Базу данных:
USE openvpn;

Создание таблиц пользователей и логов, добавляем пользователя в таблицу:
CREATE TABLE IF NOT EXISTS `user` (
`user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`user_pass` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT '1234',
`user_mail` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_phone` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
`user_online` tinyint(1) NOT NULL DEFAULT '0',
`user_enable` tinyint(1) NOT NULL DEFAULT '1',
`user_start_date` date NOT NULL,
`user_end_date` date NOT NULL,
PRIMARY KEY (`user_id`),
KEY `user_pass` (`user_pass`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE IF NOT EXISTS `log` (
`log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
`log_trusted_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`log_trusted_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
`log_remote_ip` varchar(32) COLLATE utf8_unicode_ci DEFAULT NULL,
`log_remote_port` varchar(16) COLLATE utf8_unicode_ci DEFAULT NULL,
`log_start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`log_end_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`log_received` float NOT NULL DEFAULT '0',
`log_send` float NOT NULL DEFAULT '0',
PRIMARY KEY (`log_id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `user` (
`user_id`, `user_pass`, `user_mail`, `user_phone`,
`user_online`, `user_enable`, `user_start_date`, `user_end_date`
)
VALUES (
'test', '1234', 'test@test.test',
'+79998887766', 0, 1, '2012-01-01', '0000-00-00'
);

Выводим список добавленных таблиц и пользователя:
select * from user;
show tables;

Выход пользователя root:
exit;

2. Установка сервера OpenVPN и создание сертификата.

Установка OpenVPN:
apt install -y openvpn easy-rsa

Копируем скрипты для генерации скриптов в каталог OpenVPN:
cp -R /usr/share/easy-rsa /etc/openvpn/.
cd /etc/openvpn/easy-rsa/

Изменение переменных сертификата:
nano vars

Редактируем файл и изменяем следующие строки:
export KEY_COUNTRY="RU"
export KEY_PROVINCE="MO"
export KEY_CITY="Moscow"
export KEY_ORG="none"
export KEY_EMAIL="test@test.test"

Сохраняем и выходим. Запустите переменный скрипт и очистите его:
source ./vars
./clean-all

Создание публичных и приватных сертификатов. Просто нажмите клавишу Enter или «Yes» по умолчанию:
./build-ca
./build-key-server server
./build-key client
./build-dh
mv keys /etc/openvpn/.

Создание каталога для скриптов ‘/etc/openvpn/script’:
mkdir /etc/openvpn/script
cd /etc/openvpn/script

Создание файла config.sh ‘/etc/openvpn/script/config.sh’:
#!/bin/bash
##Dababase Server
HOST='127.0.0.1'
#Default port = 3306
PORT='3306'
#Username
USER='USERNAME'
#Password
PASS='PASSWORD'
#database name
DB='openvpn'

Создаем файл test_connect_db.sh’/etc/openvpn/script/test_connect_db.sh’:
#!/bin/bash
. /etc/openvpn/script/config.sh
##Test Authentication
username=$1
password=$2
user_id=$(mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -sN -e "select user_id from user where user_id = '$username' AND user_pass = '$password' AND user_enable=1 AND user_start_date != user_end_date AND TO_DAYS(now()) >= TO_DAYS(user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user_end_date) OR user_end_date='0000-00-00')")
##Check user
[ "$user_id" != '' ] && [ "$user_id" = "$username" ] && echo "user : $username" && echo 'authentication ok.' && exit 0 || echo 'authentication failed.'; exit 1

Создаем файл login.sh ‘/etc/openvpn/script/login.sh’:
#!/bin/bash
. /etc/openvpn/script/config.sh
##Authentication
user_id=$(mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -sN -e "select user_id from user where user_id = '$username' AND user_pass = '$password' AND user_enable=1 AND user_start_date != user_end_date AND TO_DAYS(now()) >= TO_DAYS(user_start_date) AND (TO_DAYS(now()) <= TO_DAYS(user_end_date) OR user_end_date='0000-00-00')")
##Check user
[ "$user_id" != '' ] && [ "$user_id" = "$username" ] && echo "user : $username" && echo 'authentication ok.' && exit 0 || echo 'authentication failed.'; exit 1

Создаем файл connect.sh ‘/etc/openvpn/script/connect.sh’:
#!/bin/bash
. /etc/openvpn/script/config.sh
##insert data connection to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "INSERT INTO log (log_id,user_id,log_trusted_ip,log_trusted_port,log_remote_ip,log_remote_port,log_start_time,log_end_time,log_received,log_send) VALUES(NULL,'$common_name','$trusted_ip','$trusted_port','$ifconfig_pool_remote_ip','$remote_port_1',now(),'0000-00-00 00:00:00','$bytes_received','$bytes_sent')"
##set status online to user connected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online=1 WHERE user_id='$common_name'"

Создаем файл disconnect.sh ‘/etc/openvpn/script/disconnect.sh’:
#!/bin/bash
. /etc/openvpn/script/config.sh
##set status offline to user disconnected
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE user SET user_online=0 WHERE user_id='$common_name'"
##insert data disconnected to table log
mysql -h$HOST -P$PORT -u$USER -p$PASS $DB -e "UPDATE log SET log_end_time=now(),log_received='$bytes_received',log_send='$bytes_sent' WHERE log_trusted_ip='$trusted_ip' AND log_trusted_port='$trusted_port' AND user_id='$common_name' AND log_end_time='0000-00-00 00:00:00'"

Добавляем файлы конфигурации OpenVPN, сервер OpenVPN будет сканировать .conf файлы в/etc/OpenVPN при запуске. Для каждого файла он разветвляет демон. В нам нужна поддержка UDP и TCP. Создаем два файла конфигурации для двух демонов, отвечающих за UDP и TCP соответственно. При необходимости можно оставить или добавить один необходимый конфиг сервера OpenVPN.

Создаем файл server-tcp-443.conf ‘/etc/openvpn/server-tcp-443.conf’ для порта 443 сервера OpenVPN:
##protocol port
port 443
proto tcp
dev tun
##ip server client
server 10.4.0.0 255.255.255.0
##key
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh1024.pem
##option
persist-key
persist-tun
keepalive 5 60
reneg-sec 432000
##option authen.
comp-lzo
user nobody
#group nogroup
client-to-client
username-as-common-name
client-cert-not-required
auth-user-pass-verify /etc/openvpn/script/login.sh via-env
##push to client
max-clients 50
push "persist-key"
push "persist-tun"
push "redirect-gateway def1"
#push "explicit-exit-notify 1"
##DNS-Server
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
##script connect-disconnect
script-security 3 system
client-connect /etc/openvpn/script/connect.sh
client-disconnect /etc/openvpn/script/disconnect.sh
##log-status
status /etc/openvpn/log/tcp_443.log
log-append /etc/openvpn/log/openvpn.log
verb 3

Создать файл server-udp-53.conf ‘/etc/openvpn/server-udp-53.conf’ для порта 53 сервера OpenVPN:
##protocol port
port 53
proto udp
dev tun
##ip server client
server 10.5.0.0 255.255.255.0
##key
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/server.crt
key /etc/openvpn/keys/server.key
dh /etc/openvpn/keys/dh1024.pem
##option
persist-key
persist-tun
keepalive 5 60
reneg-sec 432000
##option authen.
comp-lzo
user nobody
#group nogroup
client-to-client
username-as-common-name
client-cert-not-required
auth-user-pass-verify /etc/openvpn/script/login.sh via-env
##push to client
max-clients 50
push "persist-key"
push "persist-tun"
push "redirect-gateway def1"
push "explicit-exit-notify 1"
##DNS-Server
push "dhcp-option DNS 8.8.8.8"
push "dhcp-option DNS 8.8.4.4"
##script connect-disconnect
script-security 3 system
client-connect /etc/openvpn/script/connect.sh
client-disconnect /etc/openvpn/script/disconnect.sh
##log-status
status /etc/openvpn/log/udp_53.log
log-append /etc/openvpn/log/openvpn.log
verb 3

Создаем директорию для логов ‘/etc/openvpn/log’ и добавляем файлы логов:
mkdir /etc/openvpn/log
touch /etc/openvpn/log/openvpn.log
touch /etc/openvpn/log/tcp_443.log
touch /etc/openvpn/log/udp_53.log

Изменение разрешения файлов:
chmod -R 755 /etc/openvpn

Тест проверки подлинности имя пользователя и пароль ‘1234’:
/etc/openvpn/script/test_connect_db.sh test 1234

Старт сервиса OpenVPN:
/etc/init.d/openvpn start

Редактируем файл /etc/sysctl.conf раскомментируем строку : #net.ipv4.ip_forward=1

Редактируем файл /etc/rc.local добавляем перед exit 0;:
echo "1" > /proc/sys/net/ipv4/ip_forward
echo "1" > /proc/sys/net/ipv4/ip_dynaddr
iptables -A INPUT -i tun0 -j ACCEPT
iptables -A FORWARD -i tun0 -j ACCEPT
iptables -A INPUT -i tun1 -j ACCEPT
iptables -A FORWARD -i tun1 -j ACCEPT
iptables -A INPUT -p udp --dport 53 -j ACCEPT
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 3306 -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.4.0.0/24 -o eth0 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.5.0.0/24 -o eth0 -j MASQUERADE

* eth — это сетевая которая смотрит в Интернет, имя своей сетевой карты можно посмтореть при помощи каманы ifconfig

Запускаем скрипт Iptables для шары интернета:
/etc/rc.local
iptables-save

3. Конфиг для клиента.

Конфиг для TCP порт 443:
client
dev tun
proto udp
remote 192.168.0.1 443 tcp
443 tcp
nobind
auth-user-pass
resolv-retry infinite
ca ca.crt
comp-lzo
user nobody
verb 1

Конфиг для UDP порт 53:
client
dev tun
proto udp
remote 192.168.0.1 53 udp
53 udp
nobind
auth-user-pass
resolv-retry infinite
ca ca.crt
comp-lzo
user nobody
verb 1

* Параметр remote указываем IP адрес своего сервера

Скопировать сертификат ca.crt (/etc/openvpn/keys/ca.crt) для Аунтификации клиента