Задать вопрос
  • Как связаться с автором репозитария на github?

    @xbox
    Чтобы связаться с автором в случае, если нигде в явном виде не указаны его контакты.

    1. Делаете git clone репозитария.
    2. Запускаете команду git log

    В логах в заголовках коммитов будет указан автор коммита и адрес его электронной почты.
    Копируете оттуда email и пишите автору.
    Ответ написан
    Комментировать
  • Есть ли API для получения данных банков?

    @xbox
    Также стоял этот вопрос.

    Сервис ЦБ мне показался не очень удобным.
    Быстро с минимальными затратами по времени на разработку можно получать данные из сервиса Dadata.

    Есть примеры подключения на основных языках программирования, для некоторых есть готовые библиотеки.
    К примеру на питоне импортируете библиотеку, добавляете несколько строк кода и все данные у вас.

    До 10тыс запросов в день бесплатно.
    https://dadata.ru/api/find-bank/
    Ответ написан
    Комментировать
  • Как исправить кодировку при дампе базы данных из django?

    @xbox
    Тоже столкнулся с проблемой неправильной кодировки при экспорте и советы из интернета типа указания "-Xutf8" не помогали.

    Когда мы указываем в команде "> db.json", то все данные сначала направляются на устройство стандартного вывода, а оттуда перенаправляются в файл. В зависимости от операционных систем, программного обеспечения итп кодировка в файле получается не всегда нужная.

    В моем случае я работаю из-под Windows, Django запущен в контейнере Docker (в контейнере Linux), dumpdata пытался делать через консоль в PyCharm. В БД данные в Unicode. В консоль при выводе dumpdata кириллица читается нормально, но при перенаправлении ">" вывода dumpdata в файл, кодировка неправильная.

    Решил эту проблему так. Вместо того, чтобы данные захватывать через устройство стандартного вывода, их можно сохранять напрямую в файл. Для этого используем опцию "-o db.json". При таком использовании данные сохраняются сразу в правильной кодировке (utf-8)

    Полная команда получится такая:
    python manage.py dumpdata --indent=2 --exclude auth.permission --exclude contenttypes -o db.json
    Ответ написан
    Комментировать
  • Как решить проблему с терминалом PyCharm?

    @xbox
    Столкнулся с такой же проблемой, после переустановки PyCharm на новую версию.
    В настройках, как на скриншоте в ответе выше выбрал Shell - "C:\Windows\System32\cmd.exe"
    После этого сообщение исчезло.

    Не уверен, что это правильное решение. Теперь во встроенном окне PyCharm вместо PowerShell будет запускаться обычный "CMD". Но, насколько я понимаю, его обычно достаточно. Может крутым специалистам требуется именно PowerShell, но мне он пока в обычных задачах не требовался и достаточно было CMD.
    Ответ написан
    Комментировать
  • Как исправить ошибку в работе с API?

    @xbox
    Столкнулся с такой же ситуацией.

    Причем в моем случае я пробовал подключиться к главной странице своего пустого сайта.
    При обращении с помощью скрипта на питоне выдавался код ответа 404, а сама страница отличалась от моей 404 страницы. В теле ответа были те самые
    "<!— a padding to disable MSIE and Chrome friendly error page —>"
    "<!— a padding to disable MSIE and Chrome friendly error page —>"

    Страница, которую я пробовал получить, была статическая, отдавал ее веб-сервер NGINX. Никаких хитрых защит на сервере я не настраивал и поэтому очень удивился 404-ответу и начал копать.

    Все оказалось очень просто. Оказывается, я взял скрпит из другого проекта. В заголовках headers в поле host было задано имя домена, которое не соответствовало новому домену, на котором проводились тесты. Как только я установил правильно значение "host" в заголовках запроса (так, чтобы оно совпадало с доменом, к которому обращался), соединение прошло успешно и отдалась правильная страница.

    Так это на питоне можно задать. Переменную headers потом используем при подключении с помощью Requests итп.
    На большинстве языков программирования будет что-то похожее.
    headers["host"]="my_domain.com"
    Ответ написан
    Комментировать
  • Nginx редирект с любого набора сайта на https://www.site.ru с кодами 200, 301?

    @xbox
    С кодом 200 - это не редирект.
    Редирект обычно с кодом 301, 302.

    При "перманентном" редиректе сначала у Вас страница отдает код 301 и указывает новый адрес. А потом уже новая страница открывается и, если все нормально, то отдает код 200.

    Вот пример, как http://site.ru/что_угодно и http://www.site.ru/что_угодно перенаправить с кодом 301 на https://www.site.ru/что_угодно
    Для https://site.ru делается аналогично. (Прописывается конфиг в отдельном блоке "server".)

    server {
    		listen 100.100.100.100:80;					
    		server_name site.ru www.site.ru;
    
    		location / {		
    			rewrite ^(.*)$ https://www.site.ru$1 permanent;
    		}	
    	}


    Если Вам не нужно сохранять путь после домена при редиректе, то можно воспользоваться еще более короткой конструкцией
    location / {
    			return 301  https://www.site.ru;
    			}


    Я не понимаю, зачем Вам 307 редирект. И тем более не понимаю, зачем делать двойной редирект 307=>301=> итп. В этом нет никакого смысла, в том числе SEO. И если кто-то так сделал, в том числе и крупный ресурс, то это не означает, что нужно это копировать. Двойной редирект только увеличивает время отклика страницы.
    В целях SEO используется 301 редирект. Поисковики отлично с ним работают и "склеивают" адреса.

    Ниже описание 307 редиректа из википедии. Для Вашего примера такой редирект разве нужен?
    307 Temporary Redirect — запрашиваемый ресурс на короткое время доступен по другому URI, указанный в поле Location заголовка. Метод запроса (GET/POST) менять не разрешается. Например, POST запрос должен быть отправлен по новому URI тем же методом POST. Этот код был введён вместе с 303 вместо 302-го для избежания неоднозначности. Введено в RFC 2616 (обновление HTTP/1.1).


    Вы пишите:
    Браузер запоминает, что используется https:// и в случае захода на сайте по незащищенному соединению, он осуществляет внутренний переход с кодом 307 на https://.

    На самом деле браузер запоминает не это. Некоторые браузеры запоминают 301 редирект. Это означает, что если страница "A" ссылается на страницу "B" через 301 редирект, то при повторном наборе в браузере адреса "A", браузер сразу грузит адрес "B" без предварительного обращения к "A". То, что в Вашем примере "A" и "B" имеют один и тот же разный адрес, который отличается только протоколом http/https, - это лишь частный случай. Браузеры могли бы точно также запомнить редирект _http//site1.eu/page1 на _https//site2.biz/page2
    Ответ написан
  • Как правильно настроить Firewall и NAT, чтобы IP-АТС Grandsteram UCM6104 могла работать с внешними SIP транками?

    @xbox Автор вопроса
    Для тех кто будет искать решение в подобной ситуации.
    Пробрасывать в NAT нужно только один порт UPD 5060.
    В некоторых случаях провайдеры как альтернативу используют TCP 5065.
    Остальные порты (10000-20000) пробрасывать не нужно. Достаточно их открыть в фаерволе на вход и на выход.
    Ответ написан
    Комментировать
  • Почему в Nginx при 301 редиректе теряется часть URI?

    @xbox
    Попробуйте так. У меня такой вариант работает.
    Я его, например, использую для перенаправления всех запросов с домена domain.ru на домен www.domain.ru. При этом строка с адресом и параметрами после редиректа полностью сохраняется.
    location / {		
    			rewrite ^(.*)$ http://www.domain.ru$1 permanent;
    		}

    (http/https - подставьте нужное)

    Для чистоты эксперимента используем "location /". Остальные локейшены можно на время совсем убрать.
    Вместо переменной $server_name с именем домена используем явное указание домена.
    В регулярном выражении слэш убираем из первой части и из второй. Слэш будет передаваться внутри параметра.

    Если сработает, то после этого можете по очереди приводить к тому виду, как Вы хотите (изменяя location, передавая домен в виде параметра и тп). При этом смотрите, что приводит к отсутствию желаемого результата.

    И еще обратите внимание. Если Вы в адресной строке пишите domain.ru/foo/bar/, то не факт, что этот запрос обработает "location /grid". Есть вероятность, что его обрабатывает другой location, который более точно совпадает с адресом. Проверить, какой локейшн отрабатывает можно, например, так
    location /grid {
       return 503;   
    }

    Ставите для разных локейшнов разный код возврата без всяких дополнительных обработок. Набираете в браузере адрес, получаете код ошибки и понимаете, какой локейшн его отработал.
    Ответ написан
    Комментировать
  • Отваливается php-fpm с сегфолтом libresolv-2.19.so, как поправить?

    @xbox
    Тоже столкнулся с такой проблемой.

    Стали появляться ошибки на сайте в тех местах, где раньше не было.
    Браузер выдает "Nginx - 502 Bad Gateway".
    Поскольку сначала заметил на странице, которая к внешнему скрипту по определению Whois-IP обращалась, подумал, что проблема на стороннем сайте.
    Но потом стал замечать, что и в других местах ошибки стали похожие появляться и со временем ошибка не уходит.
    В логах PHP пула сайта пусто.
    В глобальном логе PHP
    [15-Apr-2016 10:52:27] WARNING: [pool XXX] child 13146 exited on signal 11 (SIGSEGV) after 55.156115 seconds from start


    Стал грешить, что это проблема PHP после одного из недавних апгрейдов пакетов на дебиане. Откатился с версии PHP 5.6.19 на одну из древних - 5.6.3. Это не помогло. Стал дальше искать. И случайно заглянул в messages.log
    А там та же ошибка, что и у Вас.

    Apr 15 10:52:27 ZZZ-Server kernel: [ 4747.868950] php5-fpm[13146]: segfault at 7f9a00000000 ip 00007f9af038a4e9 sp 00007ffedca11790 error 6 in libresolv-2.19.so[7f9af0380000+14000]


    Дописано позже:
    Php настроен с использованием chroot Окружения.
    Файлы, которые обновляются в корне системы, в случае изменения нужно копировать вручную в choot окружение.

    Нужно было всего лишь заменить файл в chroot окружении на обновленный файл из корня системы.
    В моем случае на Debian нужно было заменить старый файл:
    ~~~php_chroot_path/etc/x86_64-linux-gnu/libnss_dns.so.2

    на файл, который обновился вместе с обновлением пакетов.
    /etc/x86_64-linux-gnu/libnss_dns.so.2
    Ответ написан
  • Nginx: Почему редиректит с главной одного домена на другой?

    @xbox
    А зачем Вам вообще этот огород с проверкой через if и редиректами?
    Конструкции if в конфигах nginx использовать не рекомендуется. Они могут тормозить систему и обычно можно без них обойтись.

    Если я правильно понял, то у Вас есть два домена и каждый должен отвечать только на своем IP адресе. Сейчас у Вас оба конфига настроены так, что они слушают на любом ip адресе.
    listen 80;

    А нужно сделать так:
    server {
       listen 115.1.1.1:80;
       server_name domain1.com;
    
       access_log /var/www/logs/nginx-domain1.access.log combined;
       error_log  /var/www/logs/nginx-domain1.error.log;
    
       root /var/www/user1/data/www/domain1.com;
       index index.html;
    
         location / {
           try_files ...;
         }
    
        }


    server {
       listen 115.2.2.2:80;
       server_name domain2.com;
    
       access_log /var/www/logs/nginx-domain2.access.log combined;
       error_log  /var/www/logs/nginx-domain2.error.log;
    
       root /var/www/user2/data/www/domain2.com;
       index index.html;
    
         location / {
           try_files ...;
         }
    
        }


    Главное в этом примере
    listen 115.1.1.1:80;
    Т.е. каждый домен отвечает только на своем IP адресе.
    Если DNS записи в настройках домена правильно настроены, то каждый домен только на один IP адрес все равно запросы пересылает.

    Дополнительно для каждого домена указывается отдельный лог файл.
    Посмотрите, что в логах будет писать. Если обычный лог не помогает, то попробуйте для error_log включить режим debug.

    Лог ошибок может собирать расширенную информацию о работе сервера. Это удобно при отладке и выяснении причин:
    error_log /var/log/nginx/error.log debug;
    Ответ написан
    Комментировать
  • Отдавать файлы как html независимо от расширения, nginx, как?

    @xbox
    Вначале описываете location'ы обычным способом, в которых указываете как обрабатывать различные пути на сайте.

    После обычных локейшенов в самом конце делаете такой локейшн:
    location ~ /*\.(.*) {  			
         root "/var/www/path_to_site/";	
    }

    В приведенном примере путь после root нужно исправить на свой.

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

    Например, Вы можете сначала задать локейшены для html страниц, для php файлов, для jpg файлов, для различных переадресаций в зависимости от адреса запрашиваемой страницы и тп, а потом для всего остального (в данном случае для любых файлов), что не попало под отдельные правила.
    Ответ написан
    Комментировать
  • Можно всё пропустить через прокси?

    @xbox
    Вопрос непонятно составлен.
    Задавая таким образом вопрос, Вы рискуете получить такой же понятный ответ.

    Клиенты, которые подключаются к nginx будут видеть IP адрес сервера, на котором установлен nginx. К порту клиенты будут подключаться к тому, на котором случает nginx.

    А сам nginx может переадресовывать запросы на любой IP адрес, на любой порт.
    Например, клиент подключается к IP 100.100.100.100:80 и будет видеть только этот IP адрес, а nginx будет скрытно подключаться к IP 200.200.200.200:8080.

    Т.е. ответ на Ваш вопрос - можно.
    Ответ написан
    Комментировать
  • Почему любой домен хостинга перенаправляет на страницу ispmanager?

    @xbox
    Если все Ваши домены открывают веб панель на Вашем сервере, то домены на стороне провайдера настроены правильно.
    После того, как кто-то набирает доменное имя в браузере, запрос переадресуется на Ваш физический сервер, а дальше какой-то Web сервер (приложение - apache, nginx итп) в зависимости от доменного имени и настроек показыват/выполняет/переадресует файлы/программы и тп. из разных папок.

    Раз Вы в комментариях пишите, что студент установил nginx, то скорее всего источник проблемы - неправильно установленный nginx.
    Вероятно, что nginx принимает все запросы, которые приходят на 80 порт не зависимо от доменного имени и переадресует их на ISP.
    В nginx нужно создать для кажого доменного имени различные настройки.
    Выглядеть это будет так примерно:
    server {
    		listen IP.XXX.XXX.XXX:80;
    		server_name example.com; 
    ...
    }


    Если после вмешательства студента apache работает на 8080 порту, можно попробовать в браузере открыть Ваш домен examle.com:8080 и example.com:80
    В первом случае за обработку отвечает apache и есть вероятность, что порт открыт и нужный домен откроется правильно, во втором случае отвечает nginx. Если apache открывает старницы правильно, а nginx неправильно, то настраивать нужно nginx.
    Ответ написан
    Комментировать
  • Какой сервер выбрать для отдачи статики в большом количестве?

    @xbox
    Как уже много раз написали, использовать нужно nginx. На мой взгляд здесь без вариантов. Про apache забудьте.

    По сжатию на лету опция
    gzip on;
    nginx.org/ru/docs/http/ngx_http_gzip_module.html
    Степень сжатия не ставьте максимальную.
    Оптимальная степень сжатия 4-5. Иначе процессор сильнее нагружается, а в процентном отношении файл сжимается меньше.
    gzip_comp_level 4;

    Но если файлы не меняются, или меняются не часто, самый лучший вариант использовать опцию
    gzip_static on;
    nginx.org/ru/docs/http/ngx_http_gzip_static_module.html
    Она позволяет отдавать вместо обычного файла, сжимаемого на лету, предварительно сжатый файл с таким же именем и с расширением “.gz”
    С некоторым интервалом запускаете скрипт, который нужно будет написать, и который будет сжимать все файлы с расширением CSS и JS. При этом скрипт может сжимать файлы с максимальной степенью сжатия. После этого nginx будет сразу отдавать сжатые файлы. Процессор вообще при этом нагружаться не будет и скорость еще дополнительно возрастет.

    А еще лучше в скрипте перед сжатием для gzip_static запускать какой-нибудь обработчик, который будет вырезать все комментарии, пробелы и тп из CSS и JS файлов. Это дополнительно уменьшит размер несжатых файлов и сжатых файлов и ускорит их разборку на машине клиента. При этом оригиналы CSS и JS без изменений.
    Обрезанная и сжатая копия их будет храниться в gz файлах.

    У себя я настроил так скрпиты:
    Они похожие, но одан вариант просто сжимает файлы (TXT итп), а второй вариант перед сжатием их обрабатывает, удаляя комментарии итп (файлы JS и CSS)

    ПЕРВЫЙ ВАРИАНТ (ТОЛЬКО СЖАТИЕ)

    /root/scripts/gzip-compress/compress.sh
    #! /bin/sh
    
    EXTENSIONS="txt|htm|html|xml|yml|htc|ico"
    
    if [ -z "$1" ]; then
        DIR="`pwd`"
    else
        DIR="$1"
    fi
    
    find $DIR -type f -regextype posix-egrep -regex ".*\.($EXTENSIONS)\$" -exec `dirname $0`/do-compress.sh '{}' \;

    /root/scripts/gzip-compress/do-compress.sh
    #! /bin/sh
    
    MINSIZE=100
    GZIP="gzip -9 -c"
    AWK=awk
    TOUCH=touch
    CHOWN=chown
    CHMOD=chmod
    
    if [ -n "$1" ]; then
        GZ_NAME="$1.gz"
        DATA_PLAIN=`stat --format "%s %Y" "$1"`
        PLAIN_SIZE=`echo "$DATA_PLAIN" | $AWK '{ print $1}'`
        PLAIN_MTIME=`echo "$DATA_PLAIN" | $AWK '{ print $2}'`
    
        if [ $PLAIN_SIZE -lt $MINSIZE ]; then
    		echo "$1 -  Ignoring file: its size ($PLAIN_SIZE) is less than $MINSIZE bytes"
            exit 0;
    	fi
    	
        if [ -f "$GZ_NAME" ]; then
    		GZIPPED_MTIME=`stat --format "%Y" "$GZ_NAME"`
            if [ $GZIPPED_MTIME -eq $PLAIN_MTIME ]; then
    			echo "$1 -  Ignoring file: already exist with the same mod time"
                exit 0
    		fi
    	fi
    	
        $GZIP "$1" > "$GZ_NAME"
        $TOUCH -r "$1" "$GZ_NAME"
    	
    	 $CHOWN --reference="$1" "$GZ_NAME"
         $CHMOD 640 "$GZ_NAME"
    	 
        echo "Compressed $1 to $GZ_NAME"
    	fi

    ВТОРОЙ ВАРИАНТ (СЖАТИЕ С ПРЕДВАРИТЕЛЬНОЙ ОБРАБОТКОЙ С ПОМОЩЬЮ yui-compressor)

    /root/scripts/gzip-compress/compress-js-css.sh
    #! /bin/sh
    
    EXTENSIONS="css|js"
    
    
    if [ -z "$1" ]; then
        DIR="`pwd`"
    else
        DIR="$1"
    fi
    
    find $DIR -type f -regextype posix-egrep -regex ".*\.($EXTENSIONS)\$" -exec `dirname $0`/do-compress-js-css.sh '{}' \;

    /root/scripts/gzip-compress/do-compress-js-css.sh
    #! /bin/sh
    
    MINSIZE=100
    JV="java -jar /usr/share/yui-compressor/yui-compressor.jar"
    GZIP="gzip -9 -c"
    AWK=awk
    TOUCH=touch
    CHOWN=chown
    CHMOD=chmod
    
    if [ -n "$1" ]; then
        GZ_NAME="$1.gz"
        DATA_PLAIN=`stat --format "%s %Y" "$1"`
        PLAIN_SIZE=`echo "$DATA_PLAIN" | $AWK '{ print $1}'`
        PLAIN_MTIME=`echo "$DATA_PLAIN" | $AWK '{ print $2}'`
    	
    
        if [ $PLAIN_SIZE -lt $MINSIZE ]; then
    		echo "Ignoring file $1: its size ($PLAIN_SIZE) is less than $MINSIZE bytes"
            exit 0;
    	fi
    	
        if [ -f "$GZ_NAME" ]; then
    		GZIPPED_MTIME=`stat --format "%Y" "$GZ_NAME"`
            if [ $GZIPPED_MTIME -eq $PLAIN_MTIME ]; then
    		echo "$1 -  Ignoring file: already exist with the same mod time"
    			exit 0	
    		fi
    	fi
    	
        $JV "$1" | $GZIP  > "$GZ_NAME"
        $TOUCH -r "$1" "$GZ_NAME"
    	
    	 $CHOWN --reference="$1" "$GZ_NAME"
         $CHMOD 640 "$GZ_NAME"
    	 
    	 
     echo "Compressed $1 to $GZ_NAME"
     
    fi

    Чтобы второй вариант работал на сервер нужно установить yui-compressor
    yui.github.io/yuicompressor
    На debian yui-compressor устанавливается так:
    apt-get install yui-compressor

    Запускать срипты из крона примерно так:
    /etc/crontab
    53 4 * * * root nice -n 19 ionice -c2 -n7   /root/scripts/gzip-compress/compress-js-css.sh /var/www/папка_которую/обработать

    Данная команда запускает скрипт по сжатию JS и CSS каждый день в 4:53 утра с правами пользователя root. Можно запускать от имени другого пользователя, если все файлы и папки, которые обрабатываются доступны этому пользователю.
    Обратите внимание, на всякий случай я запускаю эту команду с низким приоритетом, чтобы при большом количестве файлов эта операция отдавала приоритет ресурсов другим приложениями.
    Низкий приоритет процессора
    nice -n 19
    Низкий приоритет по жесткому диску
    ionice -c2 -n7

    Без приоритета ту же команду в кроне можно запускать так:
    53 4 * * * root   /root/scripts/gzip-compress/compress-js-css.sh /var/www/папка_которую/обработать

    Если меняются какие-то оригиналы файлов, для которых предварительно подготовлена gz копия для отдачи сервером nginx, то достаточно удалить gz копию файла и nginx будет отдавать свежий файл. А скрипт, запускаемый по крону, через некоторое время заново создаст gz копию измененного файла.
    Ответ написан
    Комментировать
  • Как сделать отображения русских символов в Bash'e на debian корректно?

    @xbox
    Не понимаю, почему Вас это может беспокоить.
    У меня на хостинге тоже Debian Weezy.

    Попробовал ввести в консоль то же, что и Вы:
    XXX@server:/$ рпе
    ответ:
    -bash: $'\321\200\320\277\320\265': command not found

    Тогда ввожу в консоль второй тест:
    XXX@server:$ echo "рпе"
    Ответ:
    рпе
    Третий пример. Ввожу в консоль команду с использованием кириллицы в строке без кавычек
    XXX@server:$ find тест
    ответ:
    find: `тест': No such file or directory

    Мое резюме:
    В консоли с кодировкой и с кириллицей все нормально. До того момента, как Вы подняли эту тему у меня лично никогда не возникало необходимости вводить команды на русском языке.

    Вероятно, если Вы вводите некорректную команду не на латинице, консоль Вам таким образом дает подсказку. Ведь к примеру может быть команда "ppee" и команда "ppee". Глазом разницу не отличить. Но в первом случае я написал кириллицей, а во втором латиницей. Если Вам консоль не выдаст ответ в кодах, Вы никогда не догадаетесь, что у Вас ошибки из-за того, что забыли регистр переключить и будете биться над исправлением какой-либо ошибки очень долго.
    Ответ написан
  • Как запустить из командной строки одну из функций в action файле в symfony?

    @xbox Автор вопроса
    Сам отвечу на свой вопрос.

    Решил задачу так:
    Генерируем task задачу
    php symfony generate:task --brief-description="Короткое описание." task_name

    В сгенерированный файл, который по-умолчанию находится в папке lib/task пишем то, что нужно запустить.

    Как из task файла запустить функцию, которая располагается в action файле темплейта, я не разобрался. В моем случае я просто скопировал код из action файла и дописал его в task файл.
    {
        list($new, $old) = FilePeer::rescanDirs();    
        $this->getUser()->setFlash('notice', $new . ' файл(ов) добавлено, ' . $old . ' файл(ов) удалено.');
      }

    Все готово.
    Дальше можно запускать задачу из bash скрипта или из крона.
    php symfony task_name
    Ответ написан
    Комментировать
  • Как правильно настроить vsftpd на сервере Nginx + php-fpm?

    @xbox
    ставьте права на файлы 640, на директории 750
    владельцем user1, группа www-data
    При этом nginx должен запускаться от пользователя www-data, а php-fpm от пользователя user1. По Ftp заходите от пользователя user1.
    user1 в группу www-data добавлять не нужно.

    Если у Вас несколько сайтов, то для второго сайта владельцем ставите user2, группу www-data, по ftp подключаетесь от user2.

    Если сайтов несколько то для каждого настраивается свой пул php5-fpm, каждый из которых запускается от разных пользователей.

    Результат: процессы php, а значит и WordPress будут иметь полный доступ к файлам только своего проекта и не будут иметь доступа к файлам соседних по VPS проектов. Nginx будет иметь доступ ко всем проектам только на чтение. По ftp каждый пользователь будет иметь полный доступ только к своим проектам. Лишние права доступа на файлы убраны. Если взломают один из сайтов VPS то хакер обычно получает права доступа того пользователя, от которого запущен пул php-fpm. (Взлом nginx маловероятен) Т.е. при взломе хакер получает полные права на один проект, но не может даже прочитать, а тем более записать в другой проект. Чтобы дополнительно обезопасить сервер, используйте chroot в настройках php5-fpm и ftp. Это очень сильно повышает безопасность. Но настройка chroot в php5-fpm обычно требует дополнительных танцев с бубном (изменение конфигов других сервисов, которые перестают работать из-за изменения путей и т.п.).

    Я раньше легкомыслено относился к настройкам безопасности, пока случайнр не нашел на своем VPS в двух проектах одинаковый шел-скрипт. После того, как я понял, что это за скрпит, я его запустил (просто в браузере набрал адрес соответствующий) и реально обалдел. Шел-скрипт позволял легко ходить по всем папкам проектов (отдельным сайтам), расположенным на VPS, позволял произвольно записывать и удалять файлы в этих проектах, позволял заходить в корень файловой структуры, например в папку /etc и читать все конфиги в этой папке . Хоть конфиги были с доступом только на чтение, реально в них хранится куча конфиденциальной информации. Например, некоторые пароли стандартные сервисы в таких конфигах хранят в незашифрованном виде. Скрипт позволял выводить список запущенных процессов и произвольно убивать процессы, запущенные от того же пользователя и т.п. Кроме этого все основные способы, необходимые для поиска уязвимых мест и дельнейшего вредительства в скрипте автоматизированы. Т.е. через этот шел-скрипт во многих случаях мне было удобнее работать с сервером, чем через putty и winscp. И в дальнейшем этот шел-скрпит я использовал для тестирования безопасности каждого проекта. Т.е. кроме решения локальной задачи, я Вам рекомендую сразу в комплексе безопасность проверить.
    Ответ написан
    1 комментарий
  • Что нужно сделать, что бы ipset после reboot сервера сохранял сеты?

    @xbox
    Простое и рабочее решение, развивая совет "Max_rip".

    "Max_rip" дал отличный совет "/etc/init.d/iptables-persistent, Добавит туда ipset save / ipset restore ". Только из-за того, что в слове "добавит" пропущен мягкий знак смысл его при первом прочтении теряется и кажется, что /etc/init.d/iptables-persistent должен все автоматически делать. Я попробовал - автоматически не получается. iptables-persistent сохраняет настройки iptables, но без напильника не сохраняет сеты ipset.

    Вот что имелось ввиду в совете и то, что мне помогло:

    Для начала должен быть установлен пакет iptables-persistent. На Debian устанавливаем так
    apt-get install iptables-persistent

    Этот пакет нам позволит сохранять командой из консоли правила IPTABLES. После перезагрузки правила iptables сбрасываться перестанут.

    Далее редактируем скрипт запуска /etc/init.d/iptables-persistent
    Находим секуцию save_rules() и дописываем в нее вначале строку
    ipset save > /etc/ipset.rules
    Это будет сохранять сеты IPSET при каждом сохранении правил iptables с помощью iptables-persistent.

    После этого находим секцию load_rules() и добавляем вначале строку
    ipset restore < /etc/ipset.rules
    Это будет загружать сеты IPSET при каждой загрузке правил iptables с помощью iptables-persistent.

    Этот вариант на мой взгляд самый удобный. Одной командой из консоли cохраняются и правила iptables и сеты Ipset. После перезагрузки правила сохранятся.
    service iptables-persistent save

    Удачи.
    Ответ написан
    Комментировать