Кремень КД Реклама
Кремень КМ Реклама

Удаленное управление Octoprint или Атыктотакой? Давайдосвидания! Часть 2 - защищаем веб-интерфейс

maniak26
Идет загрузка
Загрузка
29.09.2016
9934
18
Техничка

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

27
Статья относится к принтерам:
RepRap
В первой части мы научились раздавать команды принтеру через telegram.

Штука конечно безопасная, но абсолютно защищенных систем не бывает, особенно чужих. Попробуем исключить это звено из управления принтером.
Удаленное управление Octoprint или Атыктотакой? Давайдосвидания! Часть 2 - защищаем веб-интерфейс
Дано: Orange Pi PC c armbian на борту + D-bot CoreXY.

Задача: открыть снаружи защищенный доступ к Octoprint.

Вопрос: а нафига это нужно?

Ответ: для меня описанное ниже - способ разобраться в вопросе переведя его на более-менее человечески язык.

В общем виде схема выглядит так:
Удаленное управление Octoprint или Атыктотакой? Давайдосвидания! Часть 2 - защищаем веб-интерфейс
- пробрасываем порт на роутере (то есть переадресуем внешние запросы с порта роутера на порт orange pi), узнаем внешний адрес своего роутера (в случае если адрес непостоянный, придется воспользоваться DDNS сервисом), заходим через интернет на него и все.

В Octoprint есть встроенная функция разграничения доступа, но она основана на парольной защите. Сложный пароль придумать можно, но рано или поздно он поддастся простому перебору. Поэтому будем городить огород прибегнем к более надежному способу безопасности. Вдобавок, защита должна быть максимально прозрачной для пользователя - раз настроил и забыл на долгое время, а так же минимально вмешиваться в работу самого octoprint.

Реализовать все задачи можно с помощью программы-посредника между веб-интерфейсом octoprint и внешним миром. В качестве таковой будем использовать nginx - http-сервер/обратный прокси-сервер.

В общем виде теперь схема будет выглядеть так:
Удаленное управление Octoprint или Атыктотакой? Давайдосвидания! Часть 2 - защищаем веб-интерфейс
NginX будет принимать запросы перенаправленные роутером из интернета, проверять авторизацию пользователей, пропускать нужных, отшивать лишних. Авторизация пользователей будет происходить при помощи клиентских ssl сертификатов.

Статья рассчитана для домашнего использования, поэтому все сертификаты будут самоподписанными.

Поехали:

Все действия будут происходить от суперпользователя root. Только ему будут доступны файлы сертификатов и настройка механизма авторизации.

Чтобы не писать перед каждой командой sudo (запуск с правами суперпользователя), перед всеми действиями выполним:

sudo -s



1. Ставим nginx и openssl


apt-get update && apt-get install nginx openssl

добавляем nginx в автозагрузку:

update-rc.d nginx defaults

2. Генерируем нужные сертификаты

В armbian есть папка /root - домашний каталог суперпользователя. В нем и разместим скрипты генерации сертификатов.

создаем все папки и ставим на них самые минимальные права доступа - только пользователю root

mkdir /root/crtgen/ && chmod 700 /root/crtgen/

mkdir /root/crtgen/db && chmod 700 /root/crtgen/db/

mkdir /root/crtgen/db/certs && chmod 700 /root/crtgen/db/certs

mkdir /root/crtgen/db/newcerts && chmod 700 /root/crtgen/db/newcerts

mkdir /root/crtgen/db/usercerts && chmod 700 /root/crtgen/db/usercerts

в папке конфигурации nginx создадим папку для сертификатов:

mkdir /etc/nginx/ssl && chmod 770 /etc/nginx/ssl

создаем корневой доверенный сертификат:

cd /root/crtgen/

openssl req -new -newkey rsa:4096 -nodes -keyout /root/crtgen/ca.key -x509 -days 500 -subj /C=RU/ST=Mordor/L=Barad-dur/O=Octoprint security by maniak26/OU=User/CN=sitename/emailAddress=support@site.com -out /root/crtgen/ca.crt

cp /root/crtgen/ca.crt /etc/nginx/ssl/

создаем сертификат и запрос для nginx-сервера:

openssl genrsa -out /etc/nginx/ssl/server.key 4096

openssl req -new -key /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.csr -subj /C=RU/ST=Mordor/L=Barad-dur/O=Octoprint security by maniak26/OU=User/CN=sitename/emailAddress=support@site.com

Вместо sitename следует указать доменное имя будущего интерфейса octoprint. Бесплатное доменное имя можно взять, к примеру, здесь.

подписываем сертификат сервера нашим корневым сертификатом:

openssl x509 -req -days 500 -in /etc/nginx/ssl/server.csr -CA /root/crtgen/ca.crt -CAkey /root/crtgen/ca.key -set_serial 01 -out /etc/nginx/ssl/server.crt

3. Настраиваем сертификаты клиентов



Для удобства, сертификаты будут генерироваться на 1 год с момента генерации.

touch /root/crtgen/db/index.txt

echo '01' > /root/crtgen/db/serial

echo 'unique_subject = no' > /root/crtgen/db/index.txt.attr

создаем файл конфигурации

nano -w /root/crtgen/ca.conf

со следующими параметрами:

[ ca ]

default_ca = CA_CLIENT # При подписи сертификатов

# использовать секцию CA_CLIENT

[ CA_CLIENT ]

dir = /root/crtgen/db # Каталог для служебных файлов

certs = $dir/certs # Каталог для сертификатов

new_certs_dir = $dir/newcerts # Каталог для новых сертификатов

database = $dir/index.txt # Файл с базой данных подписанных сертификатов

serial = $dir/serial # Файл содержащий серийный номер сертификата (в шестнадцатиричном формате)

certificate = ./ca.crt

private_key = ./ca.key

crl = ./ca.crl

#default_days = 31 # Срок действия подписываемого

# сертификата

default_crl_days = 500 # Срок действия CRL

default_md = sha256 # Алгоритм подписи

policy = policy_anything # Название секции с описанием

# политики в отношении данных

# сертификата

[ policy_anything ]

countryName = optional # Код страны - не обязателен

stateOrProvinceName = optional # ......

localityName = optional # ......

organizationName = optional # ......

organizationalUnitName = optional # ......

commonName = supplied # ...... - обязателен

emailAddress = optional # ......

[ crl_ext ]

authorityKeyIdentifier=keyid:always

Ctrl+O -> Enter -> Crtl+X

следом создадим скрипт, который будет генерировать клиентские сертификаты:

nano -w /root/crtgen/crtgen.sh

Вставляем код:

#!/bin/sh

startDate=`date +%Y%m%d%H%M%S`

endDate=`date --date='+1 year' +%Y%m%d%H%M%S`

check_url='https://127.0.0.1'

wdir=/root/crtgen/db

userCertificatesDir=usercerts

signCertificatesDir=.

name=from-${startDate}-to-${endDate}

# Создание клиентского закрытого ключа и запроса на сертификат (CSR)

openssl req -new -newkey rsa:4096 -nodes -keyout ${wdir}/${userCertificatesDir}/${name}.key -subj /C=RU/ST=Mordor/L=Barad-dur/O='Octiprint security by maniak26'/OU=User/CN=${name} -out ${wdir}/${userCertificatesDir}/${name}.csr

# Подпись запроса на сертификат (CSR) с помощью доверенного сертификата (CA).

openssl ca -config /root/crtgen/ca.conf -in ${wdir}/${userCertificatesDir}/${name}.csr -out ${wdir}/${userCertificatesDir}/${name}.crt -batch -startdate ${startDate}Z -enddate ${endDate}Z

# Создание сертификата в формате PKCS#12 для браузера клиента

openssl pkcs12 -export -in ${wdir}/${userCertificatesDir}/${name}.crt -inkey ${wdir}/${userCertificatesDir}/${name}.key -certfile ./ca.crt -out ${wdir}/${userCertificatesDir}/${name}.p12 -passout pass:

curl --key ${wdir}/${userCertificatesDir}/${name}.key --cert ${wdir}/${userCertificatesDir}/${name}.crt --insecure --url ${check_url}

Ctrl+O -> Enter -> Crtl+X

Подготовим crl файл

openssl ca -gencrl -config /root/crtgen/ca.conf -out /root/crtgen/ca.crl

cp /root/crtgen/ca.crl /etc/nginx/ssl/ca.crl

добавляем права на запуск

chmod +x /root/crtgen/crtgen.sh

и запускаем генерацию ключа клиента:

./crtgen.sh



4. Отзываем лишние сертификаты


создадим скрипт отзыва сертификатов

nano -w /root/crtgen/revoke.sh

#!/bin/sh

name=$1

wdir=/root/crtgen/db

userCertificatesDir=usercerts

signCertificatesDir=.

#отозвать сертификат клиента

openssl ca -config /root/crtgen/ca.conf -crldays 500 -revoke ${wdir}/${userCertificatesDir}/${name}.crt

#получить список отозванных сертификатов

openssl crl -in ./ca.crl -text -noout

#отправить файл отозванных сертификатов в конфигурацию nginx

cp ./ca.crl /etc/nginx/ssl/

# перезагрузить конфигурацию nginx

service nginx reload



Ctrl+O -> Enter -> Crtl+X


Даем права на запуск скрипта:

chmod +x /root/crtgen/revoke.sh

Как пользоваться:

В файле cat /root/crtgen/db/index.txt хранятся сведения обо всех выданных сертификатах. выбираем имя нужного и запускаем скрипт через пробел добавив имя сертификата:

./revoke.sh имя_сертификата_без_расширения

После этого еще раз смотрим /root/crtgen/db/index.txt - в строчке с отозванным файлом сменился флаг с V (валидный) на R (отозванный). С этого момента владелец сертификата на страницу уже не попадет.



5. Настраиваем nginx


в файле /etc/nginx/nginx.conf меняем

access_log /var/log/nginx/access.log;

на

access_log off;

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

Создаем файл виртуального хоста для octoprint:

nano -w /etc/nginx/sites-available/octoprint

Вставляем текст конфигурации:

server {

listen 80 default_server;

listen [::]:80 default_server;

server_name _;

return 301 https://$host$request_uri; # - принудительная переадресация на https

}

server {

listen 443 ssl;

server_name _;

ssl_certificate /etc/nginx/ssl/server.crt;

ssl_certificate_key /etc/nginx/ssl/server.key;

ssl_client_certificate /etc/nginx/ssl/ca.crt;

ssl_crl /etc/nginx/ssl/ca.crl;

ssl_verify_client on;

location / {

proxy_pass http://127.0.0.1:5000;

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_cache off;

}

}

Ctrl+O -> Enter -> Crtl+X

Удаляем стандартный файл виртуального хоста и включаем виртуальный хост в nginx, перезапускаем сервер:

rm /etc/nginx/sites-enabled/default

ln -s /etc/nginx/sites-available/octoprint /etc/nginx/sites-enabled/

service nginx restart

Проверка настроек:

Заходим браузером по адресу:

http://адрес_нашей_orangepi

Должно перенаправить по адресу (при этом будет ругаться на сертификат, но все равно разрешит подключиться с осознанием рисков):

https://адрес_нашей_orangepi

Если вместо интерфейса octoprint видим следующую картину:
Удаленное управление Octoprint или Атыктотакой? Давайдосвидания! Часть 2 - защищаем веб-интерфейс
- все настроено верно. Враг не пройдет, но и мы пока тоже. Нужно поставить клиентский сертификат.



6. Настройка клиентов.


Чтобы настроить клиента, ему нужно передать файл с расширением .p12. Проще всего достать его из Orange PI PC при помощи протокола SCP - передачи файлов по ssh. Рекомендую программу WinSCP. Файлы сертификатов находятся в папке /root/crtgen/db/usercerts.

После устанавливаем его в устройство. Инструкции для разных систем:

Android iOS ChromeПосле этого получаем без проблем доступ к веб-интерфейсу Orange PI откуда угодно, а другие нет =).

Благодарю за внимание! Вопросы/предложения/пожелания приветствуются.

Подпишитесь на автора

Подпишитесь на автора, если вам нравятся его публикации. Тогда вы будете получать уведомления о его новых статьях.

Отписаться от уведомлений вы всегда сможете в профиле автора.

27
Комментарии к статье