Octoprint publishing

Материал из Ender 3 Wiki
Версия от 19:41, 25 мая 2019; Linvinus (обсуждение | вклад) (Сгенерируем самоподписанный сертифекат)
Перейти к навигации Перейти к поиску

Публикация octoprint

Печать идёт очень долго, но находиться рядом с принтером не всегда возможно, эта инструкция для тех кто хочет иметь возможность удалённого управления принтером.

Для удалённого управления можно использовать два варианта.

  1. Подключить принтер к компьютеру по usb, а к компьютеру подключаться удалённо по RDP или TeamViewer-у или аналогам.
  2. Подключить принтер к специальному принт-серверу OctoPrint https://octoprint.org

Рассмотрим второй вариант.

О том как правильно удалённо управлять принтером используя OctoPrint есть официальный ответ разработчиков есть тут https://octoprint.org/blog/2018/09/03/safe-remote-access/

Если вкратце то они советуют использовать плагины для OctoPrint, такие как "Polar Cloud", "OctoPrint Anywhere", "Telegram" и другие.

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

Поэтому если у вас нет достаточного понимания в том как работает стек протоколов TCP/IP , что такое firewall и как работает шифрование то вам скорее всего лучше использовать плагины, если вы пользуетесь месседжером Телеграмм то наиболее удобно использовать бота для управления вашим принтером.

Дале инструкция для тех у кого уже есть установленный OctoPrint но по какой либо причине необходимо опубликовать свой принтер на своём оборудовании.

Рассмотрим какие могут быть варианты с точки зрения безопасности

Публикация порта Octoprint на роутере без ssl Очень низкая безопасность
Публикация через Nginx с самоподписанным сертификатом Низкая безопасность
Публикация через Nginx с самоподписанным сертификатом + Basic авторизация Достаточно высокая безопасность при соблюдении ряда условий
Публикация через Nginx с сертификатом LetsEncrypt (либо с любым платным сертификатом) + Basic авторизация Высокая безопасность


Стратегия повышения безопасности сводится к тому чтобы отдалить атакующего от ненадёжного приложения, такого как octoprint.

Для этого лучше всего использовать nginx либо любой другой прокси сервер который поддерживает SSL и basic авторизацию, можно и авторизацию по сертификатам, но если вы знаете как это работаете то скорее всего вам эта инструкция не нужна.

Я буду рассматривать вариант "Публикация через Nginx с самоподписанным сертификатом + Basic авторизация" поскольку не у всех есть возможность использовать доменное имя, а какой именно сертификат самоподписанный или любой другой с точки зрения настроек сервера значения не имеет.


В конечном итоге нам нужно сделать так чтобы запрос приходил на наш Nginx, он проверит авторизацию посредством basic авторизации, и если всё верно пропустит до octoprint или mjpg_streamer.

Начнём с установки Nginx и необходимых пакетов, я предполагаю что у вас Debian based образ либо Raspberry либо Armbian.

apt install nginx-light apache2-utils fail2ban


Сгенерируем самоподписанный сертифекат

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

sudo mkdir /etc/nginx/ssl

sudo openssl req -x509 -nodes -days 7300 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

все поля можно заполнять произвольными значениями кроме вопроса

Common Name (e.g. server FQDN or YOUR name) []: my.ender3.club

тут лучше всего указать dns адрес по которому будет доступен ваш принтер в интернете, если у вас такого адреса нет то его нужно придумать (например my.ender3.club).

В последствии самоподписанный сертификат можно импортировать в "корневые доверенные центры сертификации" а dns имя прописать в файле c:\windows\system32\drivers\etc\hosts.

например

my.ender3.club 111.222.111.222

Таким образом вы сможете подключаться к принтеру и будете защищены от подмены сертификата, несмотря на то что сертификат самоподписанный.

Кроме того это единственный способ как заставить работать cura с самоподписанным сертификатом.

настроим nginx

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

sudo htpasswd -c /etc/nginx/.htpasswd secretoctoprintuser


создадим директорию

sudo mkdir /etc/nginx/snippets


в ней создадим файл sudo nano /etc/nginx/snippets/self-signed.conf в котором укажем путь до сертификата

ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

поскольку на arm архитектуре очень часто нет аппаратной поддержки шифрования aes настроим ssl на алгоритм chacha20 который в 3 раза быстрее aes.

sudo nano /etc/nginx/snippets/ssl-params.conf

ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
#ssl_dhparam /etc/nginx/dhparam.pem;
ssl_ciphers                 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:RSA-PSK-CHACHA20-POLY1305:DHE-PSK-CHACHA20-POLY1305:ECDHE-PSK-CHACHA20-POLY1305:PSK-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384';
ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
ssl_session_timeout  10m;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off; # Requires nginx >= 1.5.9
ssl_stapling on; # Requires nginx >= 1.3.7
ssl_stapling_verify on; # Requires nginx => 1.3.7
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Disable strict transport security for now. You can uncomment the following
# line if you understand the implications.
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";

создадим файл с настройками проксирования для octoprint sudo nano /etc/nginx/snippets/octoprint.conf

октопринт настроен слушать на локальном ip 127.0.0.1 порт 5000

        proxy_pass http://127.0.0.1:5000/; # make sure to add trailing slash here!
        proxy_set_header Host $http_host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Scheme $scheme;
        #proxy_set_header X-Script-Name /octoprint;
        proxy_http_version 1.1;

        client_max_body_size 0; 


отредактируем файл sudo nano /etc/nginx/sites-enabled/default

отключим порт 80

#listen 80 default_server;
#listen [::]:80 default_server;

включим порт 443, для этого раскомментируем строку listen 443 ssl default_server;

а после строки

        # include snippets/snakeoil.conf;

добавим

        include snippets/self-signed.conf;
        include snippets/ssl-params.conf;


заменим location / {...} таким содержимым

        auth_basic  "auth:";
        auth_basic_user_file /etc/nginx/.htpasswd;

        location /video {
            proxy_buffering off;
            proxy_pass http://127.0.0.1:8080/?action=stream;
        }

        location / {
                include snippets/octoprint.conf;
        }

здесь мы так же определили location для mjpg_streamer, который настроим ниже.

теперь nginx настроен можно перезапускать

systemctl restart nginx

настроим mjpeg_streamer

для запуска сервиса будем использовать вот такой скрипт sudo nano /usr/lib/systemd/system/mjpg_streamer\@.service

[Unit]
Description=A server for streaming Motion-JPEG from a video capture device
After=network.target
Wants=dev-video0.device
After=dev-video0.device

[Service]
Environment="LD_LIBRARY_PATH=/usr/lib/mjpg-streamer"
User=mjpg_streamer
#ExecStart=/usr/bin/mjpg_streamer -i '/usr/lib/mjpg-streamer/input_uvc.so -d /dev/%I -r 1280x720   -q 85 -timeout 10 -dv_timings' -o '/usr/lib/mjpg-streamer/output_http.so -l 127.0.0.1 -p 8080 -w /usr/share/mjpg_streamer/www'
ExecStart=/usr/bin/mjpg_streamer -i '/usr/lib/mjpg-streamer/input_uvc.so -d /dev/%I -r 640x480   -q 50' -o '/usr/lib/mjpg-streamer/output_http.so -l 127.0.0.1 -p 8080 -w /usr/share/mjpg_streamer/www'

[Install]
WantedBy=multi-user.target

скрипт запуска имеет зависимость от устройства video0 для того чтобы это работало необходимо чтобы udev сообщил systemd когда это устройство появится

для этого создадим файл sudo nano /etc/udev/rules.d/99-v4lsystemd.rules с таким содержимым

KERNEL=="video*", SUBSYSTEM=="video4linux", SUBSYSTEMS=="usb", TAG+="systemd"

для того чтобы mjpg_streamer работал с устройством /dev/video0 нужно выполнить

systemctl enable mjpg_streamer\@video0.service

systemctl start mjpg_streamer\@video0.service

настроим octoprint

так чтобы слушал только локальный ip, после этой операции доступ к octoprint будет только через nginx

в файле конфигурации octoprint, у меня это

nano /home/octoprint/.octoprint/config.yaml

в секции server:

добавим или заменим два параметра

 host: 127.0.0.1
 port: 5000

в секции webcam:

изменим два параметра для видео потока

  snapshot: http://127.0.0.1:8080/?action=snapshot
  stream: /video

после этого перезапустим octoprint


fail2ban

для того чтобы защититься от подбора пароля настроим fail2ban

sudo nano /etc/fail2ban/jail.d/nginx-http-auth.conf

[nginx-http-auth]
enabled = true

firewall

если у вас сервер octoprint имеет белый ip адрес, т.е непосредственно подключен к сети internet то дополнительно необходимо настроить firewall.

наиболее удобный для этого shorewall

apt install shorewall

о том как он настраивается лучше всего почитать в документации или в статье https://www.opennet.ru/base/net/shorewall.txt.html