Stunnel на сервері і клієнті

Завдання
Забезпечити доступ з «всюди, де є інтернет» до якогось. Шифрувати трафік між клієнтською і серверною частиною програми, яка не вміє працювати через SSL. Так само потрібно мати можливість обмежувати доступ деяких користувачів при необхідності. З різних причин основні реалізації VPN відпали. В процесі пошуку рішення натрапив на Stunnel, який ідеально підійшов. В цій статті спробую детально описати процес налаштування.

Стаття по більшій частині складається з робочих нотаток разом з претензіями на туторіал, тому прошу спокійно ставиться до капитанству виду — «Перше, що ми зробимо — оновимо систему».

Загальне уявлення схеми роботи:
клієнт (windows) > Stunnel > Інтернет > Stunnel > ЗА Сервер (linux)


Система: свежеустановленная ubuntu server 14.04 x64.

Додаток трафік якого потрібно шифрувати я називати не буду. Замість нього буду вказувати ssh. Для тіста підходить ідеально, на мій погляд.

Приступимо
Перше, що ми зробимо — оновимо систему:

sudo apt-get update
sudo apt-get upgrade

Налаштуємо і включимо ufw:

sudo ufw allow 22/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Встановимо stunnel:

sudo apt-get install stunnel4

При установці створюються:
— користувач і група stunnel4;
— цікаві нам каталоги:
  • /var/lib/stunnel4 тут буде chroot оточення
  • /etc/stunnel будь-який файл у цьому каталозі закінчується на .conf буде вважатися конфіг
  • /usr/share/doc/stunnel4/examples з прикладом конфига всередині


Проведемо деякі підготовчі заходи.

Дозволимо автозапуск. У файлі /etc/default/stunnel4 замінимо ENABLED=0 на ENABLED=1:

sudo nano /etc/default/stunnel4

Створимо папку для клієнтських сертифікатів. certs — дозволені, crls — заборонені (відкликані). Про самих сертифікатах трохи пізніше.

sudo mkdir /var/lib/stunnel4/certs
sudo mkdir /var/lib/stunnel4/crls

Створимо лог-файл і змінимо власника.

Я не вважаю розміщення логів в місці, відмінному від /var/log гарною ідеєю, але змусити stunnel писати логи за межі оточення мені не вдалося.

sudo touch /var/lib/stunnel4/stunnel.log
sudo chown stunnel4:stunnel4 /var/lib/stunnel4/stunnel.log

Я буду використовувати свій конфіг, але якщо він вам не підходить, можна взяти приклад у /usr/share/doc/stunnel4/examples

Створимо конфігураційний файл:

sudo nano /etc/stunnel/stunnel.conf

З наступним вмістом:

; **************************************************************************
; * Global options *
; **************************************************************************

; Каталог chroot оточення.
chroot = /var/lib/stunnel4/
setuid = stunnel4
setgid = stunnel4

; Створюється в оточенні
pid = /stunnel4.pid

; Рівень балакучості
debug = 7
; Лог-файл
output = /stunnel.log
; Не використовувати syslog
syslog = no


; **************************************************************************
; * Service defaults may also be specified in individual service sections *
; **************************************************************************

; Сертифікат/ключ сервера 
cert = /etc/stunnel/servercert.pem
key = /etc/stunnel/serverkey.pem

; Перевірка сертифіката. 0 - не перевіряти, 1 - перевіряти при наявності, 2 - перевіряти завжди, ...
verify = 2

; Каталог для дозволених сертифікатів. 
; Знаходиться в оточенні. Для кожного сертифіката повинна бути хеш-посилання
CApath = /certs

; Каталог для заборонених (відкликаних) сертифікатів. 
; Знаходиться в оточенні. Для кожного сертифіката повинна бути хеш-посилання
CRLpath = /crls

; Не використовувати SSLv2
options = NO_SSLv2

; **************************************************************************
; * Service definitions (remove all services for inetd mode) *
; **************************************************************************


[ssh]
; Приймати з'єднання на інтерфейс:порт або просто порт. Наприклад accept = 192.168.0.1:443
accept = 443
; Віддавати додатком на інтерфейс:порт або просто порт. Наприклад connect = 127.0.0.1:22
connect = 22


Ключі та сертифікати
Не велике відступ. У нашому випадку stunnel тільки перевіряє коректність пари сертифікат/ключ і наявність сертифікату в дозволених або заборонених. Самоподпісанного сертифіката більш ніж достатньо, і з технічної сторони (stunnel) і з боку поставленої задачі. Немає ніякого сенсу морочитися з власним CA або з присутністю кореневого сертифіката у списку довірених клієнта або сервера.

Нам потрібні пари сертифікат/ключ для сервера і кожного клієнта.

C допомогою openssl створимо пару для сервера:

sudo openssl req-nodes-new-days 365-newkey rsa:1024-x509-keyout serverkey.pem-out servercert.pem

Відповідаємо на питання:

Generating a 1024 bit RSA private key
....................++++++
..............................++++++
writing new private key to 'serverkey.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave blank some
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:MyProvince
Locality Name (eg, city) []:MyCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyCompany
Organizational Unit Name (eg, section) []:IT dep
Common Name (e.g. server FQDN or YOUR name) []:server
Email Address []:

І перемістимо їх за призначенням:

sudo mv serverkey.pem /etc/stunnel/
sudo mv servercert.pem /etc/stunnel/

Як і де зберігати клієнтські сертифікати з ключами (за винятком каталогів certs і crls створених раніше) вирішувати вам. Я просто створю каталог clients в домашній директорії свого користувача та буду зберігати їх там на перших порах.

Створимо каталог і перейдемо до нього:

mkdir /home/myuser/clients
cd /home/myuser/clients

Створимо пару для клієнта:

sudo openssl req-nodes-new-days 365-newkey rsa:1024-x509-keyout clientkey.pem-out clientcert.pem

Як і при створенні сертифіката сервера відповідаємо на запитання. Common Name буде іншим наприклад client.

Створимо ще одну пару:

sudo openssl req-nodes-new-days 365-newkey rsa:1024-x509-keyout dnclientkey.pem-out dnclientcert.pem


Припустимо, що clientcert.pem сертифікат клієнта яким доступ дозволений, а dnclientcert.pem сертифікат клієнта яким доступ заборонений. Скопіюємо сертифікати за потрібне директорій.

sudo cp clientcert.pem /var/lib/stunnel4/certs
sudo cp dnclientcert.pem /var/lib/stunnel4/crls

Для кожного сертифіката потрібно створити хеш-посилання (Можливо «хеш-посилання» не коректне назву, але воно дуже точно передає суть). Це можна зробити за допомогою утиліти c_rehash з пакету openssl. Ми ж створимо невеликий скрипт для цих цілей.

nano /home/myuser/certlink.sh

З наступним вмістом:

#!/bin/sh
#
# usage: certlink.sh filename [filename ...]

for CERTFILE in "$@"; do
# Переконатися, що файл існує і це сертифікат
test-f "$CERTFILE" || continue
HASH=$(openssl x509-noout-hash-in "$CERTFILE")
test-n "$HASH" || continue

# посилання найменший ітератор
for in ITER 0 1 2 3 4 5 6 7 8 9; do
test-f "${HASH}.${ITER}" && continue
ln-s "$CERTFILE" "${HASH}.${ITER}"
test-L "${HASH}.${ITER}" && break
done
done

Можливо буде більш доцільним розмістити certlink.sh де-небудь в /usr/bin. Я поки не став цього робити. Але вибір за вами.
Дамо права:

chmod +x /home/myuser/certlink.sh

Створюємо посилання:

cd /var/lib/stunnel4/certs
sudo /home/myuser/certlink.sh clientcert.pem

cd /var/lib/stunnel4/crls
sudo /home/myuser/certlink.sh dnclientcert.pem


В результаті в каталогах у нас повинні з'явиться посилання виду 7469493f.0.

Запустимо stunnel:

sudo /etc/init.d/stunnel4 start


Stunnel на клієнті
На клієнті будемо використовувати версію stunnel аналогічну серверної. На сервері у нас 4.53. Забираємо з одного з дзеркал.

Якщо пряме посилання перестане працювати, знайти потрібну версію можна так:

  • Йдемо на stunnel.org Завантаження;
  • У розділі Code Repositories вибираємо дзеркало і переходимо. Наприклад, usenix.org.uk;
  • Переходимо архів;
  • Виберіть 4.x;
  • Забираємо потрібну версію.
Скачаний файл stunnel-4.53-installer.exe встановлювати не будемо, просто распакуем вміст в каталог stunnel4. В цей же каталог скопіюємо сертифікат і ключ клієнта, і сертифікат сервера.

Редагуємо файл stunnel.conf. У мене він має наступний вигляд:

debug = 7
; Пара сертифікат/ключ клієнта
cert = clientcert.pem
key = clientkey.pem
verify = 2
; Сертифікат сервера
CAfile = servercert.pem
options = NO_SSLv2

[ssh]
client = yes
accept = 127.0.0.1:22
connect = 192.168.0.1:443

Тут debug = 7 тільки на момент налагодження, потім можна знизити до 3 або 4. Також є опції для «тихого режиму» і приховування значка в треї все є в man'e.

Запускаємо stunnel.exe і пробуємо з допомогою putty підключиться до 127.0.0.1. Тестуємо. Можна спробувати підключиться із забороненим сертифікатом.

Корисні матеріали


Наведені тут інструкції повністю працездатні. Перевірено 26.12.2014 ubuntu 14.04.01, stunnel 4.53.

У даний момент працюю над парсингом логів stunnel з висновком звітів і автоматизацією створення/управління сертифікатами. Так як останнім часом мені цікавий golang, буде реалізовано з допомогою нього. Якщо матеріал на цю тему цікавий — дайте знати.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.