Octoprint publishing: различия между версиями
Linvinus (обсуждение | вклад) (черновик 1) |
Linvinus (обсуждение | вклад) (черновик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
Печать идёт очень долго, но находиться рядом с принтером не всегда возможно, эта инструкция для тех кто хочет иметь возможность удалённого управления принтером.
Для удалённого управления можно использовать два варианта.
- Подключить принтер к компьютеру по usb, а к компьютеру подключаться удалённо по RDP или TeamViewer-у или аналогам.
- Подключить принтер к специальному принт-серверу 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