Octoprint publishing: различия между версиями

Материал из Ender 3 Wiki
Перейти к навигации Перейти к поиску
(черновик 1)
 
(черновик2)
Строка 56: Строка 56:
  
 
<code>htpasswd -c /etc/nginx/.htpasswd secretoctoprintuser</code>
 
<code>htpasswd -c /etc/nginx/.htpasswd secretoctoprintuser</code>
 +
 +
 +
настроим nginx
 +
 +
создадим директорию
 +
 +
<code>mkdir /etc/nginx/snippets</code>
 +
 +
в ней создадим файл /etc/nginx/snippets/self-signed.conf в котором укажем путь до сертификата
 +
 +
<pre>
 +
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
 +
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
 +
</pre>
 +
 +
поскольку на arm архитектуре очень часто нет аппаратной поддержки шифрования aes настроим ssl на алгоритм chacha20 который в 3 раза быстрее aes.
 +
 +
/etc/nginx/snippets/ssl-params.conf
 +
<pre>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";
 +
 +
</pre>
 +
 +
создадим файл с настройками проксирования для octoprint /etc/nginx/snippets/octoprint.conf
 +
 +
октопринт настроен слушать на локальном ip 127.0.0.1 порт 5000
 +
<pre>
 +
        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;
 +
</pre>
 +
 +
 +
отредактируем файл /etc/nginx/sites-enabled/default
 +
 +
раскомментируем строку <code>listen 443 ssl default_server;</code>
 +
 +
а после строки
 +
 +
<pre>
 +
        # include snippets/snakeoil.conf;
 +
</pre>
 +
 +
добавим
 +
 +
<pre>
 +
        include snippets/self-signed.conf;
 +
        include snippets/ssl-params.conf;
 +
</pre>
 +
 +
 +
заменим <code>location /</code> таким содержимым
 +
 +
<pre>
 +
        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;
 +
        }
 +
 +
</pre>
 +
здесь мы так же определили location для mjpg_streamer, который настроим ниже.
 +
 +
создадим пользователя и пароль для доступа к серверу
 +
 +
<code>htpasswd -с /etc/nginx/.htpasswd myoctoprintuser</code>
 +
 +
теперь nginx настроен можно перезапускать
 +
 +
<code>systemctl restart nginx</code>
 +
 +
настроим mjpeg_streamer
 +
 +
для запуска сервиса будем использовать вот такой скрипт /usr/lib/systemd/system/mjpg_streamer\@.service
 +
<pre>
 +
[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
 +
</pre>
 +
 +
для того чтобы mjpg_streamer работал с устройством <code>/dev/video0</code> нужно выполнить
 +
 +
<code>systemctl enable mjpg_streamer\@video0.service</code>
 +
 +
<code>systemctl start mjpg_streamer\@video0.service</code>
 +
 +
настроим octoprint чтобы слушал только локальный ip, после этой операции доступ к octoprint будет только через nginx
 +
 +
в файле конфигурации octoprint, у меня это
 +
 +
/home/octoprint/.octoprint/config.yaml
 +
 +
в секции server:
 +
 +
добавим или заменим два параметра
 +
<pre>
 +
host: 127.0.0.1
 +
port: 5000
 +
</pre>
 +
 +
в секции webcam:
 +
 +
изменим два параметра для видео потока
 +
 +
<pre>
 +
  snapshot: http://127.0.0.1:8080/?action=snapshot
 +
  stream: /video
 +
</pre>
 +
 +
после этого перезапустим octoprint

Версия 18:41, 25 мая 2019

Публикация 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


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

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

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

htpasswd -c /etc/nginx/.htpasswd secretoctoprintuser


настроим nginx

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

mkdir /etc/nginx/snippets

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

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;

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

/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 /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; 


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

раскомментируем строку 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, который настроим ниже.

создадим пользователя и пароль для доступа к серверу

htpasswd -с /etc/nginx/.htpasswd myoctoprintuser

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

systemctl restart nginx

настроим mjpeg_streamer

для запуска сервиса будем использовать вот такой скрипт /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

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

systemctl enable mjpg_streamer\@video0.service

systemctl start mjpg_streamer\@video0.service

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

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

/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