среда, 3 февраля 2021 г.

Про митинги или почему я на них не хожу

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

          Когда в 2012 году происходили митинги на болотной мне было 20 с хером лет и был я молод и горяч. В то время работал я в Ламоде. Весь коллектив у нас был примерно такой же возрастной категории: 25-30. И когда все это началось - все дружно засобирались на митинги. И естественно всех вокруг агитировали. Примерно как в школе - кто не с нами, тот чмо. И был у нас руководитель разработки, А.М. он был лет на 10 постарше нас. Он с ухмылкой на все это посматривал. Когда у него спросили, А.М. а ты пойдешь завтра на митинг, он рассказал как он во время своей молодости ходил на митинги за Ельцина и чуть ли не грудью за демократов ложился. Тоже думал, сейчас вот правда победит - и тогда все счастливо заживем. Чем это закончилось я думаю все помнят. Стала у нас демократия и Ельцин президент. И хотели как лучше а получилось как всегда. 

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

       Первое: кому нужно было его нужно было травить и за чем ? В 2020 году всем явно было не до Навального. Я бы даже сказал что обычным людям вроде меня, не интересующимся политикой на него было глубоко насрать. Ну коррупция, ок. Он 15 лет про это расследует. Это все как-то уже приелось.  И разоблачение номер 100500 уже вряд ли кого-то могло заинтересовать. Но после того как все это было сделано настолько неуклюже и топорно - о нем заговорили все. 

       Второй вопрос: как-то все подозрительно складно получается и в рифму. Сначала его фееричное возвращение на первые полосы газет, отъезд в Германию, встречи с канцлером, триумфальное возвращение, после этого Навальный как заправской шуллер вытаскивает из рукава колоду тузов: расследование о бывшем зяте Путина,  расследование о его отравителях, потом вторая часть про отравителей, потом фильм про дворец Путина. Все это случилось ни до, ни после, а вот прям в эти 30 дней что он ждал суда. То есть тайминг событий - просто лучше не придумаешь. Если сюда добавить еще митингов - давление на лиц, принимающих политические решения - было просто невообразимое. И они явно к этому были не готовы. Неуклюжесть отмазок Путина и его окружения просто зашкаливала. На фоне стройной теории Навального и команды - позиция власть имущих просто не выдерживала никакой критики. 

           Ну и третий вопрос на который у меня нет ответа: если все эти данные про дворец Путина и все остальное уже были у Навального до его отравления - почему он их не опубликовал тогда ? Ждал своего отравления и возвращения ? Если же на тот момент информации этой еще не было - то как он смог находясь в больнице и отходя от болезни подготовить столько высококлассного материала.  Как вообще возможно было подготовить этот материал в условиях постоянной слежки ФСБ ? Ведь все что публиковалось - явно было большой неожиданностью для всех. Да могут люди это сделать без соответствующей подготовки в области конспиралогии и защиты информации. То есть ребят явно кто-то научил как работать чисто. И учили их явно лучше чем сотрудников ФСБ. Те вообще действуют как овцы. Вот за кого реально стыдно. 

     В общем я думаю что ответы на эти вопросы мы узнаем не раньше чем рассекретят соответствующие архивы. А это случится не скоро. А пока достаем попкорн и наблюдаем за схваткой двух тяжеловесов - Путин и его старики разбойники против Навального и всей мировой "справедливости". Пока кажется что товарищи недооценили крепость яиц Путина. Раздавить их не удалось. Но я уверен что через 2.5 года когда Навальный выйдет - нас ждет третий раунд.  

понедельник, 28 декабря 2020 г.

Как ФРАНЦИЯ ВЛЮБИЛА мир в АВТОМОБИЛИ

        В свободное от работы/технологий время я люблю почитать или посмотреть что-нибудь на отвлеченные темы. Что-нибудь не напрягающее мозг, не требующее вдумчивого изучения, и в тоже время не пресное. А интересно-информативное. Из последнего что мне понравилось - Как ФРАНЦИЯ ВЛЮБИЛА мир в АВТОМОБИЛИ от Стаса Асафьева:

Видно что автор не просто зачитал на камеру материал найденный в википедии, я проделал довольно солидную работу. 
     До этого у него же выходили фильмы про автомобилестроение США, Японии и Германии - https://www.youtube.com/watch?v=04ZjgbMTolc&list=PLybBpPCOgFt4IANUx-EvScY8W9mbGpGYo 

среда, 23 декабря 2020 г.

Немного юмора

        Вчера младший сын(6 лет), собираясь на очередное занятие на которое он не хотел идти в сердцах сказал: 

  - У меня собачья жизнь! Я Живу как собака!

На что старший(8 лет) ему ответил: 

   - Да ты что, собаки живут гораздо лучше тебя... их кормят, они гуляют, у них нет никакой учебы....

 В общем утешил так утешил.

среда, 9 декабря 2020 г.

Ошибка, которую я совершил дважды

        Я не так давно закончил свой второй ремонт. Все вроде бы хорошо. Но тут появились соседи. И я понял что звукоизоляции нет вообще никакой. Просто ноль. Люди просто разговаривали у себя в комнате, не орали, не прыгали - просто разговаривали. И у меня все было отлично слышно. Короче это пиздец. Слышно даже как включается свет у соседей. Причем у меня выключатели так не счелкают почему-то. Или я этого не слышу. 

       Самое печальное что уже поздно что-то с этим делать. Раньше нужно было думать. Причем после первого ремонта я столкнулся точно с такой же проблемой - соседи сбоку перенесли ванную комнату и она стала находится у них через стенку от моей спальной.  И каждое утро я просыпался от звука соседского душа. Они по обычно вставали раньше чем я. Но эта история меня ничему не научила.

net::ERR_INCOMPLETE_CHUNKED_ENCODING & PMM (Percona MySQL Monitoring and Management)

            Спустя 3 месяца безоблачной работы Percona MySQL Monitoring and Management (PMM) начал хандрить: Graphana перестала открываться, говорит что  что-то не догрузилось. В Chrome Dev Tools видно что это действительно так - несколько запросов к JS файлам окончились с net::ERR_INCOMPLETE_CHUNKED_ENCODING.
          Вылечил вот так: 

  • Заходим в докер контейнер PMM: docker exec -it <PMM container id> /bin/bash
  • Перезапускаем графану: supervisorctl restart grafana
  • Перезапускаем Nginx: supervisorctl restart nginx
  • Вуаля! и все заработало. 

воскресенье, 29 ноября 2020 г.

Безопасности пост... или безисходности

        В последнее время я все чаще понимаю насколько херово обстоят дела с безопасностью в небольших компаниях, где сервера расположены не в приватной сети а имеют белые адреса. Наличие приватной сети конечно ничего не гарантирует, всегда остаются другие способы ломануть тебя. Если твои программисты слабо понимают что такое SQL-injection, XSS и прочие - значит таких дыр у вас в избытке. Вы просто об этом пока не знаете. Но как только компания растет и становится более заметной - жди сюрпризов. В общем сегодня у меня вечер грустных историй.

           История номер 1: Жила была форма загрузки документов, где-то в жопе админки. Написана хер знает когда и хер знает кем. Она была защищена паролем. Но потом добавили модный self-onboarding, и любой хмырь теперь может создать аккаунт и получить доступ к админке. Но ее конечно никто на уязвимости не проверял. Ей же только "свои" пользуются. Выяснилось что если через эту форму загрузить файл image.jpg.php то форма считает его картинкой, а веб сервер - выполняемым PHP файлом. А потом ты просто загружаешь вместо документа файл с одной единственной строчкой: <?=`$_POST[1]`?> И вуаля - remote code execution и сервер у тебя в кармане. Можешь делать с ним все что хочешь

            История номер 2: мало кто знает/помнит, но у FPM протокола нет авторизации.  И если вы ненароком написали в конфиге PHP-FPM listen=0.0.0.0:9000 или просто listen=9000 то это равнозначно: 


  Так как никакой авторизации нет, ничего не мешает сделать запрос к примеру к /usr/local/lib/php/PEAR.php.  PHP-FPM ничего не знает про root directory. Все эти ограничения проверяются на уровне веб сервера(Nginx). А если ты эту проверку обходишь - ты можешь делать все что тебе заблагорассудится. Доступ к PEAR - это полноценный remote code execution. Только shell за тебя заботливо предустановлена системным администратором. 
          Но мы то думаем что мы все умные, и не будем php-fpm вешать на внешний порт. Мы будем unix socket использовать. Ну или 127.0.0.1 на крайний случай. Но тут на помощь нам приходит Мистер Докер! 

Почти как Мистер Пропер, только наоборот. Мистер Docker понятия не имеет что он запускает. То есть если кто-то внутри контейнера развернул php-fpm который принимает запросы от всех подряд а потом прокинул этот порт наружу - мы снова получаем 

Мораль сей басни такова: 
  • Держи все сервера за высоким забором/VPN. Иначе хер уследишь
  • Проверяй что тебе загружают. Даже если форма доступна только для "своих"
  • Держи то что загружено - на отдельном домене, где нет никакого выполнения PHP кода. Пусть на этом домене все отдается как статика. Это и для производительности не плохо, и для безопасности. В таком случае даже если к тебе загрузят гавно - они смогут его только обратно скачать и ничего более

понедельник, 16 ноября 2020 г.

Ошибки которые мы обожаем повторять - API для мобильных приложений

         Есть определенные типы ошибок которые повторяются из проекта в проект. Куда бы я не пришел - там эти ошибки либо были когда-то, либо есть до сих пор. Сегодня делюсь своими размышлениями по поводу разработки API для мобильных приложений. 

            Ошибки при разработке API для мобильных приложений как правило возникают из-за того что проектируют это API - бэкэнд разработчики. Мобильная разработка - это довольно замкнутая область и люди выросшие в ней как правило мыслят довольно узко. Для них мобильное приложение это то что ставится на сматрфон клиента. Поэтому на проектирование мобильного API они как правило кладут болт. Вы нам данные дайте, а дальше мы сами разберемся. Мобильные разработчики не понимают что бэкэнд мобильного приложения - такая же его часть (не технически, а с точки зрения клиента, а значит и бизнеса).  

            А бэкэнд разаработчики не понимают специфики мобильного приложения - то что зарелизив/опубликовав его однажды - ты уже никак не сможешь его изменить. Ты не можешь "закатить" его назад.  Эта операция, довольно привычная для бэкэнд разработчика, совершенно не возможна в мире мобильной разработки. И отсутсвие этого понимания часто порождает проблемы. Итак перейдем к практической части: о чем необходимо подумать заранее чтобы потом не было мучительно больно? 

Как мы будем обновлять приложение ? 

         Предположим что мы накосячили в релизе и что-то пошло не так. Как мы можем заставить пользователя обновить его приложение (чтобы перейти на новый билд) без ошибки. Здесь как всегда два решения - очевидное и правильное. 

        Первое что приходит на ум(очевидное решение) - сделать ручку которая будет говорить - нужно нам обновляться или нет. Мобильное приложение соответсвенно должно эту ручку время от время дергать и проверять нужно обновляться или нет. Вроде все просто и должно работать. Но в чем же подвох ? Проблема в том что если дергать эту ручку редко (при старте приложения к примеру) то пользователь скорее всего много раз нарвется на баг прежде чем узнает что мобильное приложение стоит обновить. Если дергать ручку слишком часто - то это увеличивает время отклика приложения(перед совершением каких-то важных действий нам нужно проверить - а не пора ли нам обновится ? может быть там уже все поломалось)

          Более правильный подход состоит в том что при каждом запросе мы должны передавать версию мобильного приложения. И ожидать что на любой запрос может прийти ответ с ошибкой и просьбой обновится. В этом случае в мобильном API всегда есть информация - от какого клиента пришел запрос, и в случае если мы знаем что на этой версии приложения что-то сломано, мы всегда, в ответ на любой вопрос можем получить ошибку - "Версия не поддерживается, пожалуйста обновите приложение"

Как мы будем обновлять API приложения?  

Ответ на этот вопрос немного проще - всегда нужно использовать версионирование  хэндлеров мобильного АПИ. Самый простой способ - всегда включать версию  хэндлера в request path. То есть request path должен быть не просто /handler-name/, а либо /v1/handler-name/ либо /handler-name/v1/  Это требование должно быть обязательным вообще для всех API, не только для мобильного API. Но как правило это понимают только те кто ввязался по полной в SOA архитектуру.  В более простых проектах об этом как правило не задумываются.        

А что если данными сессии беда ?

Есть целый класс ошибок в мобильном приложении вызванный тем что операция логина была выполнена одной версией мобильного приложения, а дальнейшая работа с сессионными данными будет выполняться в другой версии мобильного приложения. Да, можно предложить версионировать не только хэндлеры API, а еще и структуры данных хранящихся в сессиях - но тогда ты в версиях закопаешься. Поддерживать такое решение на практике будет - ад. 

Более практичным будет предусмотреть еще одну стандартную ошибку, которую может вернуть любой хэндлер мобильного API: Please login again. То есть если мы сбросили пользователю пароль(иногда такое приходится делать) - мы можем в ответ на любой запрос к API ответить - "пожалуйста авторизуйся еще раз" и проблема решена. Либо если нужно обновить данные которые загружаются один раз при входе в мобильное приложение - мы всегда можем вернуть данный код ошибки и пользователь зайдет в мобильное приложение еще раз.

Про безопасность

Не надо надеятся что запросы мобильного приложения никто не видит. С помощью Burp Suite их можно очень легко посмотреть. И рано или поздно найдется тот кто захочет посмотреть запросы/ответы. И если там вместо сессионного токена будет что-то типа  customer_id=121212, то рано или поздно это всплывет наружу. Не надейтесь на авось - сразу используйте что-то вроде JWT token

Ну и напоследок

Не надо забывать про maintenance. Да, в идеальном мире розовых пони софт должен работать всегда, и сервера должны обновляться без всякого maintenance. Но на практике это к сожалению не так. Время от времени приходится проводить работы в продакшене которые требуют остановки бизнеса. И тут будет полезно иметь какую-то стандартную ошибку, вроде "Мы прямо сейчас не работаем, но мы скоро себя починим." Если у нас maintenance, то мы на все запросы возвращаем данную ошибку. Приложение должно ожидать получить данную ошибку в ответ на любой запрос к серверу. Если мы получаем это сообщение, мы не говорим пользователю "неизвестная ошибка, все пропало, мы все скоро умрем", а сообщаем что у нас запланированные работы и они скоро должны закончится.