или  (пет проект) Если ваши успехи в освоении data science и других наук дошли до стадии, когда вам есть что показать, то самое время глянуть на эту статью. Эта статья совсем не про искусственный интеллект и про искусственный интеллект далее в статье больше ни слова. Эта статья описывает один из способов получить из сети картинку, обработать её и отдать обратно. Как можно дешевле, надёжней, быстрей (это конечно фантастика) Можно и с AI, можно и без AI, главное то, что есть обработчик картинок и есть что показать человечеству! Недостатки этой статьи - простовата до невозможности, нет ни одного решения сложней плинтуса. Откровенный примитив. Всё уже описано, расписано и показано в других статьях. Достоинства этой статьи - применены исключительно простые решения. Все конфиги на пол страницы, все библиотеки многолетней давности и никаких фреймворков. Всё ясно, понятно, обозримо и проверено годами. И работает. Зачем эта статья. Можно скопипастить и будет работать и можно сосредоточиться на главном своём алгоритме. Можно быстро понять какую часть туториалов прочесть, что бы что то переделать. Тут всё в куче, легко найти, просто поменять. Если нужно добавить новый функционал - ясно понятно куда что и как дописывать. Таких статей, как прикрутить web интерфейс к питону в десяток строк, полно, но дьявол то как всегда в мелочах. Если сделать вебморду в 10 строк, работать то оно конечно будет, но вам тогда нужен прямой IP и все боты мира будут в него стучать, отнимать ваше и время процессора. А если вдруг ушлый какой и пролезет! Не годится! Нужно защищать свой компьютер и, особенно, свой код, например нейронной выстраданной сети. Код, свой, ещё не опубликованный и незакопирайченый, здесь главная ценность. Поэтому выносим морду в интернет, защищаем её и строим к ней туннель.  Покупаем/арендуем/берём_в_дар VDS, самый махонький. Я выбрал вариант KVM, чтобы спокойно и уверенно установить там FreeBSD. Их как-то в сети внешней работает много и все сетевые трюки на FreeBSD выглядят просто, достойно и элегантно. (И всё это дело можно уместить в 512, а то и в 128 Мб памяти, что немаловажно по деньгам). Туннелей тоже много разных и хороших, мой выбор - OpenVPN. Бесплатно и просто подключить свой внутренний вычисляющий сервер на любой ОС к внешнему серверу на FreeBSD. Вот тут первый вопрос — а где делать сервер и где клиент? Я выбрал вариант когда во внешнем мире на VDS у меня находится сервер VPN. Казалось бы должно быть наоборот, сервер внутри охраняемого периметра, а клиент вне и клиент подключается к серверу. Но, в моем случае, если потерять внешний сервер, если сервер будет скомпрометирован, то я потеряю всего лишь VDS и не потеряю доступ внутрь, к суперсекретному своему алгоритму и к машине, на которой он есть, в охраняемом периметре. Если же вне будет клиент, а сервер внутри, то при компрометации клиента или взломе его, утекут ключи и хакер получит доступ с серверу с секретным кодом. В варианте внешнего сервера нет никаких открытых и пробрасываемых портов, все наглухо закрыто для доступа извне, доступ только через VPN и только по одному порту для FastCGI. Итак ставим на VSD с FreeBSD обычный web сервер lighttpd, обычный OpenVPN сервер и посредством FastCGI отправляем картинки через openvpn на свой рабочий компьютер для обработки. Первый архитектурный вопрос прояснился и буду рад и готов получить замечания и предложения. Но теперь второй вопрос. Картинку то мы получили, обработку, которую собственно и хотим показать миру, сделали и теперь картинку нужно отдать обратно в мир. Но вот вопрос: - а с какого сервера? Если из своего рабочего, то те же проблемы - прямой IP и соблазн для ботов всего мира. Если не прямой, то нужно с сервера обработки отдать картинку куда то во внешний мир безопасно и оттуда показывать. В данном варианте картинка грузится через VPN с помощью scp обратно на внешний сервер на FreeBSD и оттуда отдаётся тем же lighttpd. Картинку покажем и через 10 минут удалим, так что во внешнем мире не хранится ничего, ни картинки, ни алгоритма. Отдав картинку, lighhtpd показывает страницу опроса с закодированными параметрами картинки - нравится преобразованная картинка или нет или загрузить новую? Ответ вместе с параметрами преобразования картинки и ее именем возвращается по FastCGI на внутренний сервер и записывается в файл. Мало ли, вдруг накопится статистика )) Сделано так, что бы у пользователя было время подумать, отвлекли, пообедать ушёл и т.д. Сессия разорвалась и что бы ответить нужна новая, вот в новом FastCGI запросе и будет новая сессия и вся инфо о картинке будет отправлена. Ну и опять же конечно буду рад и готов получить замечания и предложения. Можно скачать все конфиги и исходники с Github и посмотреть реальную работу: http://107.189.8.250/ Теперь по пунктам и подробно. Ещё раз - буду рад и готов выслушать замечания, правки и критику. Ставим FreeBSD как обычно и немного модифицируем /etc/rc.conf  и первым делом настраиваем файрволл пропускаем извне только ssh, http и vpn (1194 порт). Разрешаем доступ с tun0, это и есть туннель к нашему внутреннему серверу. Форвардинг нам не нужен совсем. Создаём юзера под которым будет подключаться клиент и загружать картинки. Заменяем доступ по ssh на беспарольный доступ по ключу, чтобы scp работал без пароля. Доступ нужен и с рабочего компьютера для настройки и с вычислителя для передачи картинок. Ну и что бы не было каркозябров в названиях файлов, русифицируем FreeBSD, добавляем в /boot/loader.conf: Далее ставим lighttpd и openvpn любым привычным способом. Добавляем нашего юзера в группу www. Он должен иметь права на добавление картинок в папки lighttpd. Добавляем юзера под которым будет работать openvpn, лучше если это будет не root. По умолчанию конфиги lighttpd не соответствуют создаваемым во FreeBSD по умолчанию папкам. Правим /usr/local/etc/lighttpd/lighttpd.conf Эта сложная конструкция в lighttpd.conf всего лишь проверяет URL и если что то не нравится, то отправляет на начальную страницу сайта. Правим там же modules.conf и раскомментируем там же строчку для вызова fastcgi Теперь правим fastcgi.conf, дописываем "192.168.0.66" это адрес внутреннего сервера за периметром. Именно на нем и будут производиться вычисления картинок. Этот адрес может и не принадлежать внутренней сети совсем и к этому серверу вы можете сделать доступ по другому, второму интерфейсу, а этот "192.168.0.66" закрыть для любого обращения, кроме как через VPN через tun0. Ну и порт 8888 выбран не совсем удачно, лучше выбрать другой, если использовать jupyter notebook. Но в данном случае все вычисления на С и порт можно взять любой больше 1024. Создаём папки для хранения страницы сайта и картинок. Напомню, что наш <user> должен быть членом группы www и должен иметь права на запись в папку /usr/local/www/data/images и у группы www должны быть права доступа к этой папке. Далее настраиваем OpenVPN, (вот тут гораздо подробней), создаём папки для openvpn _openvpn - это тот самый юзер, под которым и будет запускаться собственно openvpn и никакой login/shell/home_dir ему не нужен. Можно использовать пользователя nobody. теперь правим /usr/local/etc/openvpn/server.conf Теперь создаём ключи и кладем в указанные папки и не забываем правильно установить права Когда создаём ключи, то нужно обязательно указать правильно CN, оно должно совпадать с именем юзера и именем файла в папке /usr/local/etc/openvpn/ccd/ Точно именно так - все три имени должны совпадать. OpenVPN берет имя юзера из ключей, его настройки из файла /ccd/<user> и вы в системе логинитесь под этим именем при подключении через OpenVPN и получаете соответствующие права доступа. Всё должно совпадать. В файле /usr/local/etc/openvpn/ccd/<user> пишем настройки сети Эта запись означает, что сеть 192.168.0.0 находится за VPN, туда нужно и можно через tun0 слать пакеты. Теперь создаём страницу нашего сайта, которая делает только одно - принимает картинку от посетителя и кладем в файл upload.html Можно выкинуть 5 строчку, она для того, что бы google находил и индексировал страницу и годится только для этого конкретного сайта http://107.189.8.250. Подправьте заголовки, если нужно. Если отправляете не только картинки, то правьте accept="image...". Не смог сделать так, что бы браузер выбирал только одну картинку. Буду рад, если кто подскажет. Сейчас можно выбрать несколько картинок и наш обработчик FastCGI обработает только первую. Но это нарушение архитектуры - если обрабатывает одну картинку, то и выбираться должна только одна. Но не смог ... Теперь перегружаем FreeBSD и смотрим, что же мы там наделали, запустились ли lighttpd, openvpn? Открывается ли страница, можно ли выбрать файл? Можно и нужно проверить порты, всё таки сервер в прямом доступе кулхацкеров и ботов всего мира. Ну и последний штрих это crontab -e и не забудьте поправить <user> на конкретное свое имя, что указывали ранее. Те картинки, что уже показали, нет нужды хранить на внешнем сервере долго. Каждые 10 минут файлы старше 10 минут будут в папке картинок удалены. Т.е. картинка на внешнем сервере храниться не более 20 минут. Если что то не работает, или работает не так как задумывалось - проверяем IP, в статье указан конкретный рабочий действующий адрес. У вас он может быть и должен быть другим. Проверяем права <user>, проверяем папки. Если опять что не так - пишите мне, может я что и пропустил, гляну в действующем примере. Тут настраивать мало совсем и кратко. Нужно создать специальную таблицу маршрутизации для VPN в файле /etc/iproute2/rt_tables Эта новая таблица 200 vpn нужна для того, что бы ответ на пакеты пришедшие с vpn через tun0 отправлялись обратно также через tun0. Просто в любимом редакторе правим файл и добавляем строку. Также рутинная процедура создания ключей (укажите правильное имя <user>) с помощью ssh-keygen -t rsaи также рутинно и просто отправим их на наш FreeBSD ssh-copy-id <user>@10.0.1.1. Где 10.0.1.1 это адрес вашего сервера при доступе через VPN на tun0. Устанавливаем рутинно OpenVPN и создаём два файла в папке /etc/openvpn/client/ это файл конфигурации клиента client_<user>.conf и в то же место кладем ключи. Напомню, что <user> должен быть одинаковым везде, там на FreeBSD в трех местах и тут. Именно этот <user> подключается к FreeBSD и именно у него права и возможность положить обработанную картинку на её место. В той же папке лежит файл /etc/openvpn/client/special_vpn Название произвольное, но смысл его в правильной настройке маршрутизации. OpenVPN адрес 10.0.1.1 присваивает серверу VPN в сети 10.0.1.0, что мы указали на FreeBSD в файле server.conf. Поскольку вычислитель картинок никуда больше ничего не отдает и не берет, то можно отправлять на адрес 10.0.1.1 и через VPN картинка дойдет до места. Больше чем уверен, что в этих конфигах можно найти кучу усовершенствований, лишнего и неправильного. Уверен, что с помощью OpenVPN-AS можно сделать проще и быстрее и надёжней. И у меня эта конструкция не сразу заработала, хотя почти точно такая, но для просто VPN, работает рядом много лет. Если загружать исходники в эту машину и компилировать, то нужно загрузить и все библиотеки и среду. Но можно подготовить бинарник на другой машине и просто запустить два сервиса - OpenVPN и это бинарник. Подготовка бинарника не предмет этой статьи, просто не забудьте ключи для gcc -lopencv_imgcodecs -lopencv_imgproc -lopencv_core -lpthread -lfcgi -lssl -lcrypto И совсем штрих, (fun_house в данном случае имя юзера под которым картинка обрабатывается) прописываем crontab -e И в файле /home/fun_house/funhouse.sh  funhouse - имя программы, которая собственно создана нами и которая и принимает FastCGI запросы, принимает, обрабатывает картинки и отправляет их обратно. Такой crontab будет при перезагрузке запускать программу обработки. Программа обработки состоит из трех логических частей, но в этом случае все они уложены в один длинный код. По этому поводу есть много мнений и почти все они говорят, что так плохо. Но так наглядно и, главное, последовательно видно что и когда, что за кем и как выполняется в деталях. И в нашем случае наглядность всего алгоритма работы сервиса и детализация рассмотрения перевесили другие аргументы. Переделать для себя всё - пара минут. Теперь перейдем к описанию алгоритма работы внутреннего сервера.  Главная программа сервиса обработки внутреннего сервера запускает THREAD_COUNT потоков и ждет. Внешний сервер показал посетителю страницу, тот согласился, выбрал картинку и нажал "Отправить". Lighttpd, согласно своим конфигам, отправляет FastCGI запрос на адрес 192.168.0.66 который через OpenVPN будет доставлен на 8888 порт внутреннего сервера. Вся обработка происходит параллельно в запущенных потоках. Каждый поток ждет когда придет его очередь обрабатывать FastCGI запрос от внешнего сервера.  Как только будет открыто соединение со стороны внешнего сервера, программа принимает по частям в размере буфера данные, парсит эти данные, скачивает по необходимости файл со служебной информацией, сохраняет этот файл картинки или скачивает картинку с диска, далее картинку обрабатывает, сохраняет, отправляет на внешний сервер, формирует HTML страницу ответа и отправляет её на внешний сервер. После закрывает соединение, сохраняет журнал в файл журнала и данные в файл результатов. И так в цикле постоянно. Директория с программой должна содержать поддиректории data/marks, data/imges и log Теперь собственно код и комментарии. Очень красиво и подробно про FastCGI в потоках изложено в статье habr.com/ru/post/154187/ и вся идея и почти весь код про fastcgi взят оттуда. Особое спасибо@janagan Здесь по катом весь source код на почти 1000 строк одним файлом.Наверно это неправильно.  Можно скачать все конфиги и исходники с Github. Под катом громадный в 1000 строк исходник с комментариями. Комментарии наверняка можно и нужно дополнить.