Пользователь пока ничего не рассказал о себе

Достижения

Все достижения (7)

Наибольший вклад в теги

Все теги (48)

Лучшие ответы пользователя

Все ответы (40)
  • Почему разные выходные значения Java и Python?

    Vamp
    @Vamp
    Причина в том, что второй вызов метода вычисляется в значение, не влезающее в тип данных long. То есть возникает классический integer overflow. В java и php старшие биты, не поместившиеся в long, просто отбрасываются. В python и ruby на уровне языка поддерживается bignum арифметика, поэтому результат другой. То есть числа могут быть сколь угодно велики без опасности возникновения переполнения. В php такое тоже возможно при помощи модуля bcmath или gmp. В java аналогичную арифметику предоставляет класс BigInteger:

    import java.math.BigInteger;
    
    public class A {
        public static void main(String[] args) {
            BigInteger output_1 = generate(400732734464L, -74, 12);
            BigInteger output_2 = generate(1641401281110016L, 100, 14);
    
            System.out.println(output_1);
            System.out.println(output_2);
        }
    
        public static BigInteger generate(long val1, int val2, int val3) {
            return BigInteger.valueOf(val2 & 255)
                .add(BigInteger.valueOf(val1))
                .shiftLeft(val3);
        }
    }
    Ответ написан
  • Как обезопаситься от шеллов на сервере?

    Vamp
    @Vamp
    Для начала необходимо разделить сайты друг от друга физически. Сами скрипты сайта, временные файлы и файлы сессий.

    Например, структура может быть такая:
    /var/www
      + toster.ru
      |  + site
      |  + sessions
      |  + temp
      + example.com
      |  + site
      |  + sessions
      |  + temp
      + остальные сайты


    В папке site расположены скрипты сайта. Обычно эта папка (или одна из вложенных) является document root сайта.

    В sessions находятся файлы сессий посетителей сайта. Если их не разделять, то взлом одного сайта автоматически дискредитирует сессии всех пользователей остальных сайтов. То есть, взломав example.com, можно стырить сессию администратора toster.ru. Путь к этой папке настраивается директивой session.save_path.

    А в temp находятся временные файлы, загружаемые пользователями через html формы (директива upload_tmp_dir). Туда же неплохо направить и остальные временные файлы, генерируемые функциями tmpfile(), tempnam(), самостоятельным образом (используя результат функции sys_get_temp_dir() для построения пути) или любой другой функцией, которая использует системную временную директорию. К сожалению, директива sys_temp_dir, ответственная за это, появилась только в php 5.5.0. Если у вас более ранняя версия, тогда нужно учитывать момент, что сайты могут ходить в /tmp и нельзя блокировать доступ к этой папке.

    ---

    Далее необходимо настроить нормальные права доступа. Часто в интернете можно видеть советы "делайте chmod 777 на всё". Так делать нельзя. Подобные права доступа как раз наихудшим образом сказываются на безопасности, потому что дают возможность отредактировать любой скрипт на сайте и встроить маленький бэкдор в самый незаметный скрипт, принадлежащий CMS. Надежно избавиться от такого довеска можно будет только полной переустановкой CMS. Или можно загнать весь сайт в систему контроля версий, как предложил Максим Гречушников, и одной командой узнать какие скрпиты были заражены. Тем не менее, одно другое не исключает. Система контроля версий позволит выявить заражение постфактум, а нормальные права не дадут возможности заразить файл в принципе.

    Я рекомендую на папки устанавливать права 755, а на файлы 644. При этом, владельцем всех папок и файлов должен быть кто угодно, но не пользователь, из-под которого запущен веб-сервер или php (например, пользователь, под которым вы сами заходите на сервер по ssh). Но такие права на всё устанавливать тоже нельзя. Сайт в процессе своей работы может генерировать свои временные файлы (например, кешировать что-то в файл, компилировать шаблоны, хранить какие-нибудь настройки), поэтому для папок, в которые сайт может что-то записать, права должны быть другие. Вот здесь уже можно ставить 777 для папок и 666 для файлов. Это довольно кропотливая работа, потому что у каждого сайта (особенно если они на разных CMS) свои папки и часто определение таких папок нетрвиально.

    И права доступа не решают всех проблем. Злоумышленник может встроить вредоносный код в скомпилированный шаблон или отравить кеш. Тогда не помогут ни права (так как для нормальной работы сайту нужно иметь права на запись в такие файлы), ни система контроля версий (так как подобные файлы слишком часто меняются и, как правило, не хранятся в репозитории). Хотя надо сказать, этот способ внедрения сложнее и недолговечнее, чем встраивание в нормальный скрипт.

    И ещё автоматическое обновление сайта перестанет работать. Если CMS позволяет обновить себя через кнопку в веб-интерфейсе админки, то такое обновление не будет работать, так как права доступа не разрешают веб-серверу модифицировать скрипты. Обновлять скрипты теперь можно только вручную от имени пользователя, которому принадлежат все файлы. Безопасность и удобство - разные концы одной палки.

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

    ---

    После раскидывания сайтов по своим папкам и настройки прав, необходимо ограничить доступ сайтов друг к другу. Проще всего это сделать настройкой php директивы open_basedir. Эта директива определяет список директорий, внутри которых (а так же во всех вложенных папках) скрипты могут читать и писать. Доступ за пределы этих директорий будет пресекаться. То есть нужно каждому сайту прописать в open_basedir путь к своей папке и к /tmp (если версия php < 5.5.0 и нельзя установить sys_temp_dir).

    Для Apache с mod_php конфигурация прописывается в httpd.conf:

    <VirtualHost *:80>
      ServerName example.com
      php_admin_value open_basedir /var/www/example.com/:/tmp/
      php_admin_value upload_tmp_dir /var/www/example.com/temp/
      php_admin_value sys_temp_dir /var/www/example.com/temp/
      php_value session.save_path /var/www/example.com/sessions/
    </VirtualHost>


    Для php-fpm в конец php.ini файла вписывается специальная секция, определяющая индивидуальную конфигурацию для каждого сайта:

    [HOST=example.com]
    open_basedir /var/www/example.com/:/tmp/
    upload_tmp_dir /var/www/example.com/temp/
    sys_temp_dir /var/www/example.com/temp/
    session.save_path /var/www/example.com/sessions/
    
    [HOST=toster.ru]
    ; конфиг для toster.ru и т.д.


    У open_basedir есть недостатки:

    1. Замедление файловых операций, так как необходимо проверить вхождение каждого открываемого файла в список open_basedir. Если проекты не highload, то некритично.
    2. Есть варианты обхода. Но их далеко не всегда удаётся эксплуатировать. Тем более они закрываются со временем в новых версиях php.
    3. Realpath cache не работает вместе с включенной open_basedir.

    ---

    Есть вариант запускать каждый сайт от своего пользователя. В apache это делается опцией AssignUserId. В php-fpm - отдельной конфигурацией pool. Но в любом случае нужно для каждого сайта создавать не только отдельного юзера, но и группу. При этом права на основную папку сайта (/var/www/example.com) должны быть 750, а группа должна соответствовать той, от которой будет запускаться процесс apache (или пул php-fpm), ответственный за обслуживание сайта.

    Проще показать на примере. После имени файла я буду указывать права, владельца и группу в формате (права, владелец:группа)
    /var/www         (755, root:root)
      + toster.ru    (750, my_user:toster)
      |  + site      (755, my_user:toster)
      |  + sessions  (777, my_user:toster)
      |  + temp      (777, my_user:toster)
      + example.com  (750, my_user:example)
      |  + site      (755, my_user:example)
      |  + sessions  (777, my_user:example)
      |  + temp      (777, my_user:example)
      + остальные сайты - всё аналогично


    my_user - это пользователь, под которым ни в коем случае нельзя запускать веб-сервер и php. Это может быть ваш собственный пользователь, под которым вы заходите на сервер по ssh. В этом случае у вас будут все права на сайт, а у сайта только необходимый минимум.

    <VirtualHost *:80>
      ServerName example.com
      AssignUserId exapmle example
    </VirtualHost>
    <VirtualHost *:80>
      ServerName toster.ru
      AssignUserId toster toster
    </VirtualHost>


    Разумеется, в системе должны быть заранее созданы пользователи с именами toster, example и с одноимёнными основными группами.

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

    ---

    Более сложным и предпочтительным вариантом является упаковка каждого сайта в свой отдельный виртуальный контейнер lxc/docker. Я не смогу в двух словах описать как это добро настраивать, но эффект будет такой, как будто каждый сайт работает на своём собственном VPS сервере.

    ---

    Ещё немного про базу. Для доступа к базе у каждого сайта должен быть свой собственный логин с паролем. Причем, доступ должен ограничиваться исключительно той базой, в которой находятся данные сайта. И права должны быть не все подряд, а только SELECT, INSERT, UPDATE, DELETE. В редких случаях CMS может самостоятельно создавать таблицы для своих нужд в процессе своей работы (не в процессе первичной установки). В этом случае можно добавить права CREATE, ALTER, INDEX юзеру этого сайта. Иногда бывает в базе есть какие-то процедуры/функции. Для их вызова требуются права EXECUTE.

    ---

    Безопасность - дело большое и очень разнообразное. И уж точно не простое. Всё что я здесь написал - это далеко не полный список. Есть ещё настройки уровня операционной системы (особенно фаервол) и прочего установленного в системе софта. Так же отдельным пунктом идёт система мониторинга и оповещения, которые почему-то никто не делает - не считают нужным разбираться ещё и в этом. Так что если у вас нет хорошего админа в запасе, то проще будет заказать услугу администрирования прямо у того же хостера, у которого вы арендуете VPS. Или найти админа-фрилансера. Или же перевезти сайты на shared хостинг, где администрирование уже включено в ценник, да и сам переезд хостеры часто предлагают сделать бесплатно силами своих админов.
    Ответ написан
  • Где можно почитать/посмотреть про принципы проектирования и написания ПО для стратегически важных объектов?

    Vamp
    @Vamp
    Такие стандарты существуют. Наиболее известные - MISRA C и MISRA C++. Как можно догадаться, для языков С и С++, соответственно. Изначально созданы для автомобильной промышленности, но распространились и на аэрокосмическую отрасль, медицинскую технику, военных и прочие критичные к надёжности области. В том числе и АЭС.

    Из MISRA C выросли SEI CERT C/C++, AUTOSAR General Software Specification, JPL Institutional Coding Standard for the C (стандарт NASA) и ещё куча других.

    Вся суть этих стандартов в том, чтобы максимально ограничить используемые фичи языка - чтобы код был максимально прост (даже скорее примитивен) и доступен для анализа. Как правило, запрещено использовать бесконечные циклы, рекурсию, макросы, аллокации из кучи - вобщем, любые потенциально опасные операции, в которых чаще всего находятся ошибки. Так же накладываются ограничения на размер функции (в строках кода), цикломатическую сложность, покрытие автотестами и т.п.

    Помимо этого, существует ворох стандартов, описывающих подходы к организации процесса разработки и контроля качества. У каждой отрасли свои стандарты. Например, AS9100.

    Если вы интересуетесь вопросом чтобы применять подобные техники в повседневном программировании, то не стоит - никакого удовольствия и конкурентного преимущества вы от этого не получите. Если конечно ваше повседневное программирование не включает в себя разработку панели управления АЭС.
    Ответ написан
  • Зачем /dev/null, если можно без него?

    Vamp
    @Vamp
    Крон умеет отправлять на почту вывод выполняемой команды, поэтому и делают перенаправление в /dev/null, если вывод программы ни в почте, ни в текстовых файлах никого не интересует.

    Разумеется, если у программы есть флаги для отключения вывода, то можно воспользоваться ими, но не у всех они есть. Даже если есть, нужно ещё разобраться какие. Приходится читать ман. Перенаправление в /dev/null делается одинаково для любой запускаемой команды, поэтому чаще пользуются им.
    Ответ написан
  • Как разобраться с тем, что такое TCP/IP?

    Vamp
    @Vamp
    Как я понял, есть четыре уровня:
    1. Прикладной
    2. Транспортный
    3. Сетевой
    4. Канальный

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

    Есть такой плагин JSON Server. Там база данных на json. Но если я допустим захочу использовать вместо JSON Server - OpenServer, смолу ли я это сделать?

    Упомянутый вами JSON Server работает на основе протокола HTTP. То есть на 7 (прикладном) уровне. Вы вполне можете вместо JSON Server взять OpenServer, так как он тоже работает на этом же уровне, только вам придётся написать скрипты, которые будут принимать и обрабатывать JSON запросы так же как это делает JSON Server. Вот после этого и можно будет свободно переключаться между JSON Server и OpenServer, так как между ними появится совместимость не только на уровне HTTP, но и ещё на уровне API.

    Можно ли подключаться к базе SQL по REST API или вообще как это?

    Нет. Как правило, у каждой базы свой собственный протокол. Попытка отправить HTTP запрос MySQL серверу закончится ошибкой, так как протоколы разные, хоть и находятся на одном (прикладном) уровне.

    Чтобы понять как работают и для чего нужны протоколы более низких уровней, вам необходимо превратиться в админа, так как взаимодействовать с этими протоколами как программист вы не можете. Все они работают не на уровне прикладных программ (OpenServer, Apache, node.js, MySQL), а на уровне операционной системы и оборудования (сетевая карта, роутер).

    Попробую объяснить на пальцах уровни протоколов, начиная с самого базового.

    1. Физический. Протоколы этого уровня определяют как кодировать биты электрическими/световыми сигналами в медном/оптическом кабеле. Грубо говоря, определяют какое напряжение подать в провод, чтобы устройство на другом конце провода поняло, что мы отправляем 0 или 1.

    2. Канальный уровень. Протоколы этого уровня позволяют общаться с несколькими устройствами, связанными локальной сетью. Здесь работает MAC-адрес, о котором вы наверняка уже слышали, - уникальный идентификатор, зашитый производителем в чип сетевой карточки. По MAC адресам сетевые устройства понимают на каких проводах какие компьютеры сидят и передают электрические сигналы по нужному проводу в зависимости от MAC.

    3. Сетевой уровень. Практически то же самое, что и канальный, только вместо физических адресов (МАС) используются виртуальные (IP), что позволяет общаться компьютерам из разных локальных сетей. Ваш домашний компьютер находится в локальной сети вашего интернет провайдера, а сервера гугла находятся в своей локальной сети, но гуглом вы можете пользоваться только благодаря IP. Вы никак не сможете узнать MAC адреса серверов гугл, впрочем как и гугл - MAC вашего компьютера.

    4. Транспортный уровень. Здесь находятся протоколы UDP и TCP, которые позволяют указать номер порта - то есть какому приложению на удалённой стороне предназначены данные. У протокола TCP есть ещё дополнительные поля вроде порядкового номера пакета, что позволяет организовать доставку данных в том порядке, в котором отправитель их послал. Именно это имеют ввиду, когда пишут что TCP - протокол гарантированной доставки сообщений.

    5 и 6 уровни (сеансовый и представления) расписывать не буду, так как с ними вам вряд ли придётся столкнуться когда-либо.

    7. Прикладной уровень. С этим уровнем вы, как программист, работаете плотнее всего. Это HTTP, TLS, почта (SMTP, POP, IMAP), файловые протоколы (FTP), IP-телефония (SIP, RTP) и куча других.

    От слова транспорт, то есть данные транспортируются, но ведь это происходит еще не на этом уровне? Там же дальше еще 2 уровня?

    С этой точки зрения только уровни с 1 по 3 можно назвать транспортными, от слова "транспорт" со смыслом "перемещение данных с одного компьютера на другой". Транспортный же уровень (который под номером 4), на самом деле не имеет ничего связанного с перемещением данных. Как по мне, данный уровень надо было назвать иначе.
    Ответ написан

Лучшие вопросы пользователя

Все вопросы (3)