Метка: defend

Web-интерфейс с нуля на NodeMCU ч. 2

Как повелевать html’ом, не захламляя код

На самом деле существует два варианта, как подцеплять html/css/js и отправлять его в библиотеку ESP8266WebServer. Первый намного удобнее при использовании языка программирования Lua. Нода по сути шьется кодом, который позволяет загрузку файлов прямо в флеш память.

Я решил пойти более примитивным путем — весь код от разных страниц хранится в одном заголовчном файле, например, «html.h».

Примитивненько в коде указываем новую константу, и присваиваем ей массив char-символов.

const char html_code[] PROGMEM = "";

Именно таким решением я воспользовался в первый раз, но возникла небольшая проблема — каждый перенос строки пришлось экранировать обратным слэшем, а также добавить пернос строки с помощью комибнации «\r\n». Такой код выглядел немного нелепо, а редактировать его было неприятно. Вскоре я наткнулся на более приятную фишечку, которая позволила избавиться от столь большого количества бесполезных элементов. Начиная уже с С++11 можно использовать литеру R после символа присваивания, для того, чтобы компилятор воспринимал текст буквально «сырым», то есть raw.

Единственное, о чем нужно позаботиться — указать уникальные делиметеры, которые позволят компилятору успешно скомпилировать код.

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

const char html_code_raw[] PROGMEM = R"delimeter(CHAR_ARRAY_HERE)delimeter";

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

Также уже опыт подсказывает, что Ардуино не очень любит работать с большими объемами данных. Сразу отправляем весь массив данных в Flash-память через модификатор PROGMEM. При наличии больших объемов информации, о RAM-памяти вообще можно не вспоминать, поскольку данные хранятся в другой памяти. А вот чтобы зацепить их оттуда, нужно прибегнуть к следующему медоду:

size_html_code_raw = strlen_P(html_code_raw);
pgm_read_byte_near(html_code_raw + bias);

Пересчитывать символы каким-то другим методом будет несколько бездумно. Сразу цепляем количество символов через процедуру strlen_P(), а затем вытаскиваем посимвольно pgm_read_byte_near() — в аргументе нужно указать сумму из адреса переменной и индекса элемента.

Теперь все просто, собираем наш код так, как нам необходимо и отправляем его в долгое плавание:

server.send(200, "text/html", html);

Зачем тут WebSocket’ы и JSON???

На самом деле данная связка очень хорошо себя проявляет. Буквально полтора-два года назад, WS основательно закрепился в современных браузерах. С помощью JS и WS на клиенте достаточно нескольких десятков строк, для того чтобы обмениваться данными. На ESP8266 оказалось приятным бонусом возможность в одно мгновение написать аналогичное решение.

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

#include <WebSocketsServer.h>
#include <ArduinoJson.h>
#define WEBSOCKETS_SERVER_CLIENT_MAX (20)
WebSocketsServer webSocket = WebSocketsServer(81);

Подключаем все нужные библиотеки и инициализируем класс вебсокетов на 81 порту. В библиотеке настроены некоторые ограничения на количество клиентов — максимум 5 устройств. Меня это не устраивает, так что на третьей строке я изменяю константу, ограничивающую этот параметр.

webSocket.begin();

В setup() выполняем метод begin()

webSocket.loop();

А в цикле loop() обновляем состояние всех сокетов. В моем случае, мне требовалось передавать массив из чисел.

DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
JsonArray& data = root.createNestedArray("data");
for (int i = 0; i != array_size; i++) {
    data.add(*(array + i));
}
root.printTo(*output);

Сначала создадим буффер, в котором мы временно будем хранить JSON-объект. Затем в этом буффере создадим корневой элемент, а в этом корневом элементе создадим необходимый нам массив.

С помощью цикла, заполняем массив используя метод .add(). В качестве аргумента указываем адрес на значение нашего массива.

Чтобы получить результат нашей работы в виде String элемента, нужно воспользоваться методом .printTo() для корневого элемента. После этого, JSON-объект нам уже больше не пригодится.

Отправка готового String-объекта для всех устройств сразу производится одной строчкой:

webSocket.broadcastTXT(*output);

Отправка клиента для определенного клиента выполняется следующим образом:

webSocket.sendTXT(device_id, *output);

Внутри страницы, которую вы передаете клиентам, нужно использовать следующий код:

<script>
var socket = new WebSocket("ws://192.168.1.1:81");
socket.onopen = function () {
    alert('Соединение установлено.');
};
socket.onclose = function (event) {
    if (!event.wasClean) {
        alert('Обрыв соединения'); 
    }
};
socket.onmessage = function (event) {
    var root = JSON.parse(event.data);
    for (i = 1; i < 200; i++) {
        // Каждый элемент теперь доступен через root.data[i]
    }
};
</script>

Теперь у клиента при подключении появится всплываюшее окно с надписью «Соединение установлено», а при разрыве таким же образом будет показано сообщение о обрыве соединения. А в тот момент, когда сервер будет выполнять отправку данных, на клиенте будет вызываться метод socket.onmessage = function (event) {}, в котором можно обрабатывать входные данные.

Это конкретные эпизоды, которые я реализовал на своем ESP8266. Здесь соответственно нет приема данных на ESP8266 через WS, а также нету парсинга JSON. Возможно, что я добавлю это несколько позже, но никто не запрещает вам ознакомиться с этими библиотеками прямо сейчас.

https://github.com/Links2004/arduinoWebSockets

https://github.com/bblanchon/ArduinoJson

Настраиваем свой VPN на основе SoftEther

Привожу пример настройки сервера для CentOS 7 на KVM в общих чертах. Данная инструкция очень сухая — без скриншотов и без тонны разъяснений. Сухая словно сухое вино, хорошо выжатая, насыщенная конкретным алгоритмом, чтобы превратить твой сервак в VPN. Очень полезна при недостатке Spotify, Rutr@cker’a и других ресурсов из сети твоего провайдера. Я использовал мощности Hetzner.com для хостинга своей VPS.

Накатываем на сервак тулзы для сборки VPN:

yum -y groupinstall "Development Tools"
yum -y install gcc zlib-devel openssl-devel readline-devel ncurses-devel
yum -y install system-config-network-tui system-config-firewall-tui
yum -y install policycoreutils-python
yum -y install net-tools

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

cd /tmp/
wget http://www.softether-download.com/files/softether/v4.22-9634-beta-2016.11.27-tree/Linux/SoftEther_VPN_Server/64bit_-_Intel_x64_or_AMD64/softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-x64-64bit.tar.gz
tar zxf softether-vpnserver-v4.22-9634-beta-2016.11.27-linux-x64-64bit.tar.gz

Прямо не отходя от кассы собираем нашего будущего спасителя тырнета:

cd ./vpnserver
make

Возвращаемся на каталог назад, перемещаем сервак в удобную нам локацию и обновляем ему права, дабы защитить от неугодных

cd ..
mv vpnserver /usr/local
cd /usr/local/vpnserver/
chmod 600 *
chmod 700 vpncmd
chmod 700 vpnserver

Теперь нужно запилить службу, чтобы не было больно при каждом ребуте. Создаем следующий скрипт — /etc/init.d/vpnserver. Удобное название для нашего сервера VPN сервера.

#!/bin/sh
### BEGIN INIT INFO
# Provides: vpnserver
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start daemon at boot time
# Description: Enable Softether by daemon.
### END INIT INFO
DAEMON=/usr/local/vpnserver/vpnserver
LOCK=/var/lock/subsys/vpnserver
test -x $DAEMON || exit 0

case "$1" in
    start)
        $DAEMON start
        touch $LOCK
    ;;
    stop)
        $DAEMON stop
        rm $LOCK
    ;;
    restart)
        $DAEMON stop
        sleep 3
        $DAEMON start
    ;;
    *)
        echo "Usage: $0 {start|stop|restart}"
        exit 1
esac
exit 0

Необходимо добавить службу в запуск, чтобы при каждом запуске, система автоматически поднимала наш випиэн.

chmod 755 /etc/init.d/vpnserver
mkdir /var/lock/subsys
systemctl enable vpnserver

Поднимаем сервак и смотрим, как он себя чувствует — если тесты выкидывают Pass, то вы, наверно, все сделали правильно.

/etc/init.d/vpnserver start
cd /usr/local/vpnserver/
./vpncmd
3
check
exit

Переходим к настройке самого VPN сервера.
Начнем со смены пароля админа

cd /usr/local/vpnserver/
./vpncmd
1
Enter
Enter
VPN Server>ServerPasswordSet

Настраиваем сервер под себя, выбираем шифрование, создаем хаб и создаем первого пользователя, а также выключаем логи и включаем L2TP/IPSec:

KeepDisable
ServerCipherSet AES256-SHA
HubDelete DEFAULT
HubCreate VPN
Hub VPN
GgroupCreate
UserCreate 
UserPasswordSet
logdisable packet
IPsecEnable /L2TP:yes /L2TPRAW:no /ETHERIP:no /PSK:<preshared-key> /DEFAULTHUB:VPN
SstpEnable no

Далее создаем и настраиваем локальный мост и сразу же проверим его существование:

BridgeСreate VPN /DEVICE:VPN /TAP:yes
BridgeList

Затем проверим его существование и в системе:

ifconfig tap_vpn

Установим легковесный DNS перенаправитель и DHCP сервер — dnsmasq. И заодно настроим его под наши интересы:

yum -y install dnsmasq

Dnsmasq настраивается через конфиг-файл /etc/dnsmasq.conf:

interface=tap_vpn
dhcp-range=tap_vpn,192.168.200.10,192.168.200.100,2h
dhcp-option=tap_vpn,option:router,192.168.200.1
dhcp-option=tap_vpn,option:dns-server,8.8.8.8,77.88.8.8

А скрипт сервера меняется следующим образом. Не забудь поменять GLOB_IP на ip своей машины, а также и другие переменные, если ты делаешь что-нибудь по своему:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          vpnserver
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Start daemon at boot time
# Description:       Enable Softether by daemon.
### END INIT INFO
DAEMON=/usr/local/vpnserver/vpnserver
LOCK=/var/lock/subsys/vpnserver
TAP_ADDR=192.168.200.1
GLOB_IP=195.201.31.142
test -x $DAEMON || exit 0

refreshnets () {
    iptables -t nat -A POSTROUTING -s 192.168.200.0/24 -j SNAT --to-source $GLOB_IP
    systemctl restart dnsmasq
    echo "iptables and dnsmasq were updated"
}

case "$1" in
    start)
        refreshnets
        sleep 2
        $DAEMON start
        touch $LOCK
        sleep 1
        /sbin/ifconfig tap_vpn $TAP_ADDR
    ;;
    stop)
        $DAEMON stop
        rm $LOCK
    ;;
    restart)
        $DAEMON stop
        sleep 3
        $DAEMON start
        sleep 1
        /sbin/ifconfig tap_vpn $TAP_ADDR
    ;;
    resetnets)
        refreshnets
    ;;
    *)
        echo "Usage: $0 {start|stop|restart|resetnets}"
        exit 1
esac
exit 0

Настраиваем автофорвардинг в системе через файл конфигурации /etc/sysctl.d/ipv4_forwarding.conf:

net.ipv4.ip_forward = 1

А затем применяем настройки в системе:

sysctl --system

Наконец-то все готово, ребутаем сервак, и бежим проверять наш vpn. Сначала проверяем его коммандой systemctl status vpnserver. Должно выбросить что-то типо следующего:

● vpnserver.service - LSB: Start daemon at boot time
 Loaded: loaded (/etc/rc.d/init.d/vpnserver; bad; vendor preset: disabled)
 Active: active (running) since Sat 2018-03-24 20:45:00 CET; 1min 37s ago
 Docs: man:systemd-sysv-generator(8)
 Process: 881 ExecStart=/etc/rc.d/init.d/vpnserver start (code=exited, status=0/SUCCESS)
 CGroup: /system.slice/vpnserver.service
 ├─1077 /usr/local/vpnserver/vpnserver execsvc
 └─1078 /usr/local/vpnserver/vpnserver execsvc

Mar 24 20:44:57 debian-2gb-nbg1-dc3-1 systemd[1]: Starting LSB: Start daemon at boot time...
Mar 24 20:44:57 debian-2gb-nbg1-dc3-1 vpnserver[881]: iptables and dnsmasq were updated
Mar 24 20:44:59 debian-2gb-nbg1-dc3-1 vpnserver[881]: The SoftEther VPN Server service has been started.
Mar 24 20:45:00 debian-2gb-nbg1-dc3-1 systemd[1]: Started LSB: Start daemon at boot time.

Теперь донастраиваем сервак, либо через CLI, либо через GUI, который можно установить опять же с сайта разработчика. Рассматривать тонкости GUI настроек не буду, поскольку уже есть две инструкции. Я лишь сделал свою сборную стайтеку, которая у меня отлично работает.

1 источник | 2 источник | сайт softether

Student App — Две недели работы и…

За две недели работы было произведено не очень много изменений:

  • В первую очередь, произошел первый рефакторинг кода через полгода после создания прототипа. Часть кода была перемещена в классы Old*.java, а также я попытался минимизировать зависимости. Теперь, когда мне предоставят доступ в БД системы, я смогу очень легко реализовать новые классы и методы, которые будут легко взаимодействовать с остальным приложением.
  • Был реализован парсер для http://press.tstu.ru/.
  • Соответственно, контент из парсера теперь будет показывать страница новостей.
    Это заняло больше 50% времени, так как реализация всего для меня была первым опытом.
  • Каждую новость теперь можно просмотреть отдельно, нажав на нее. Данный функционал был сначала сделан одним методом, а после прочтения документации на тему «Android Fragment» был переделан на основе этого класса. Но здесь требуются доработки.
  • Также мне очень хотелось попробовать систему контроля версий Git — я перенес приложение из Google Drive в нее, и теперь не беспокоюсь, что что-то может произойти с исходниками. Теперь я буду стараться выбрасывать на сайт также и changelog’и — это будет намного лучше.

Из видео ниже можно увидеть весь доступный сейчас функционал.

Обновляем компьютер до Kaby Lake’а

Моему компьютеру в этом году уже бы исполнилось девять лет, если бы не одно маленькое происшествие!1343721590_l1klea4qyvg

Конечно не в таких масштабах, но все равно — материнская плата приказала всем остальным долго жить. Соответственно я попытался ее восстановить, нашел убитый MOSFET, поменял его. Затем запустил BIOS и увидел грубую ругань в сторону NVRAM. Узнав через интернет, что это лечится с помощью перепрошивки на программаторе, я все бросил.

Я склонился к смене старой материнской платы на MSI H110 PRO-VD с сокетом LGA1151. Вот что может пощекотать нервы любому человеку, разбирающегося в процессорах:

SkyLake или Kaby Lake, i3 c 2-мя ядрами и HyperThreading’ом или настоящий четырехядерник i5. Все что угодно, от цены и до технологии, добавляло еще больше огня в «костер выбора». В итоге решил стартануть с вот такой новой комбинацией на руках:

  • MSI H110 PRO-VD
  • Intel i5-7400
  • DDR4 8GB RAM

После закупов в Ulmart’e, в тот же день, я решил все незамедлительно и собрать, но и тут меня постигло разочарование. Свеженький Kaby Lake не хотел дружится с материнкой — подавай ей SkyLake. Компьютер не стартовал.

Был необходим процессор Intel 6-ого поколения и только. Конечно я читал про это, но будучи все тем же наивняком, я решительно думал, что у компьютера хотя бы запустится BIOS. Мне пришлось искать вариант прошивки BIOS «по-фасту» — отдавать по гарантии на неделю и более что-то не хотелось.

В результате я получил, как минимум, двойной прирост производительности в сравнении со старым Intel Core 2 Quad 9450 2.55GHz@ 3.2GHz, а также кучу крутых технологий.  Это все хорошо заметно на основе эмулятора Android. Ранее в среде Android Studio мне было легче убиться, чем что-то отладить прямо на компьютере. Сейчас же я могу без проблем запустить эмулятор, а через минуту уже проверять работоспособность приложения.

Scr1

Выходные на HackerRank.com

cropped-wt2-1.pngКак потратить половину дня или 12 из возможных 48ми часов на что-то недостижимое? Достаточно зайти на Hacker Rank и позволить себе уйти с головой программировать разную «шляпу».

Для себя я смог найти там отличный раздел для Java-программистов — материал рассортирован по главам и есть как простые задачи, так и сложные. Задачи короткие, но достаточно своеобразные и оригинальные, которые заставят тебя пошуршать мозгами.

Так же решил побаловать свой одинокий сайт, на который никто не заглядывает, крутой иконкой. Вот и все.

8

Этапы разработки

1 Этап Выбор платформы

Android Studio
Android Studio
XCode
XCode

Выбор платформы имеет свои плюсы и минусы, как в Native, так и в Cross-Platform виде. Предпочтение отдается все таки «нативной» разработке, так как приложение будет зависеть в частности от серверного API. А значит, половина работы будет максимально эффективно выполняться на удаленном сервере.

2 ЭтапРазработка интерфейса для Android и iOS

renovation-instruments-2

 

3 ЭтапСоздание методов для получения новостей с tstu.ru

Кажется, что у новостной ленты, которая расположена на сайте, нету базы данных. Скорее всего придется использовать методы парсинга для получения массива данных о последних событиях. Будем использовать RSS-ленту, которая обеспечивает очень удобный и легкий способ получения новостей! =)

4 ЭтапНаписание собственного API для клиентского приложения

5 ЭтапПодключение клиентского приложения к серверному API

bigstock-loud-computing-conc-44222482

6 ЭтапАдаптация клиентского приложения под пользовательские интересы

С помощью различных методов будет определено, что важно для студента, а что лишь будет «пылиться на полке». В интересах также заинтересовать студента в учебе, через какие-либо функциональные возможности.

7 Этап — Анализ привлекательности TSTU Student App в студенческой среде

7

После публикации приложения, мы сделаем оценку популярности приложения как среди старших курсов, так среди младших. С помощью опросов сравним удобство и привлекательность моб. приложения в сравнении с сайтом. А из пользовательской активности сможем узнать, будет ли увеличиваться тенденция студентов следить за своей успеваемостью.