Задать вопрос
Профессионально занимаюсь системным администрированием FreeBSD, Linux (Debian, Ubuntu), CoreOS (RancherOS) и Windows (2003/2008/2012) серверов на протяжении последних 17 лет.

- ​Администрирование ОС FreeBSD, Linux (Debian, Ubuntu), CoreOS и Windows (2008/2012);
- Систем виртуализации на базе VMware, Microsoft Hyper-V, KVM, OpenVZ, Docker;
- Хостинговые системы на Linux (Apache, Nginx + PHP-FMP) с панелями (ISPConfig, DirectAdmin, ISPmanager) и без панелей;
- Баз данных — MySQL (MariaDB, Percona), PostgreSQL, Redis, Memcache, MongoDB, InfluxDB, Yandex.ClickHouse;
- Почтовых систем на Linux (postfix, dovecot). Антиспам (Rspamd) и антивирусы (ClamAV, DrWeb, KAV);
- Мониторинг серверов (Zabbix, Monit, Grafana, CollectD, Prometheus, Netdata);
- Git (GitLab, Gogs, Gitea);
- VPN (OpenVPN, PPTP, L2TP, FreeRADIUS);
- Сетевого оборудования: Cisco, D-Link, TP-Link, Ubiquiti, HP;
- Программирование под Windows (Delphi) и Linux (C, Golang, Shell);
Контакты

Достижения

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

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

Все теги (39)

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

Все ответы (65)
  • Как работает электронная почта?

    Возьмём двух почтовых провайдеров: mail.ru и gmail.com.
    На них зарегистрировались соответственно два пользователя: А@mail.ru и Б@gmail.com
    Чтобы А успешно оправил письмо получателю Б, а тот его принял, происходит следующее.

    Схема довольно проста:

    Отправитель А@mail.ru посылает письмо получателю Б@gmail.com

    Сервер mail.ru (MTA), получив задание с помощью почтового посредника MUA (клиентская почтовая программа (The Bat, Mozilla Thunderbird)) по протоколу SMTP, ищет почтовый сервер gmail.com (MTA) по доменной части адреса (в нашем случае gmail.com) через DNS. SMTP сервер mail.ru ищет в DNS для домена gmail.com запись MX (mail exchange), она и указывает на MTA сервер получателя Б@gmail.com (в простом случае).
    Далее MTA mail.ru связывается с MTA gmail.com по протоколу SMTP, происходит ряд проверок со стороны обоих серверов, если все успешно, то письмо передается в почтовую очередь сервера gmail.com.
    Затем MTA gmail.com доставляет письмо на сервер входящей почты (называющийся MDA, то есть агент доставки электронной почты), который хранит письмо в почтовом ящике пользователя Б@gmail.com в ожидании его приема пользователем. Далее с помощью MUA (клиентская почтовая программа (The Bat, Mozilla Thunderbird)) пользователь Б@gmail.com извлекает из MDA письмо по протоколу POP или IMAP.
    В качестве MUA может выступать веб-интерфейс, использующийся для взаимодействия с сервером входящей почты (MDA) и сервером исходящей почты (MTA).
    Ответ написан
    1 комментарий
  • Какие прорехи в безопасности могут быть в конфигурации nginx?

    1. Постоянный редирект с / на index.php

    location = / {
            rewrite ^ $scheme://$host/index.php permanent;
        }
    
        location / {
            deny all;
            return 404;
        }
        location ~* ^/index\.php$ {
            try_files $uri $uri/ =404;
            fastcgi_index index.php;
            fastcgi_pass php5-fpm-sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include /etc/nginx/fastcgi_params;
        }



    Очень странная логика, особенно использование $host и некорректное использование try_files. Про try_files почитайте тут.

    $host
    в порядке приоритета: имя хоста из строки запроса, или имя хоста из поля “Host” заголовка запроса, или имя сервера, соответствующего запросу


    Если у вас не определен default_server и server_name site.ru; стоит первым в списке, то к вам будут прилетать все запросы с любым полем Host, в том числе пустым, что является очень опасной практикой.
    Лучше использовать переменную $server_name, но все равно, если вам нужно обращения по любым url обрабатывать только через index.php, то правильно это делается так:

    /NONEXISTENTFILE меняете на заранее фейковый файл который не может существовать, например /d7sdhsdhsdf8sfhgsfd8fh438dfjh

    ...
            error_page 404 = @cms;
    
            location / {
                try_files /NONEXISTENTFILE @cms;
            }
    
            location @cms {
                    fastcgi_pass      unix:/var/lib/php5-fpm/xxxxx.sock;
                    fastcgi_index    index.php;
                    fastcgi_param   SCRIPT_FILENAME $document_root/index.php;
                    fastcgi_param   SCRIPT_NAME /index.php;
                    include             /etc/nginx/fastcgi_params;
            }
    ...


    2. Запрещаем любую статику кроме gif|jpg|png|js|css|ttf|woff|ico
    location ~* \.(gif|jpg|png|js|css|ttf|woff|ico)$ {
            try_files $uri =404;
            expires 30d;
        }



    Логичнее и правильнее будет сделать так:

    try_files $uri =404; нам не понадобится, т.к. у нас есть error_page 404 = @cms; который в случае отсутствия картинки перенаправит запрос в @cms

    ...
            error_page 404 = @cms;
    
            location ~* ^.+\.(gif|jpg|png|js|css|ttf|woff|ico)$ {
                    expires 30d;
                    access_log off;
                    log_not_found off;
            }
    
            location / {
                try_files /NONEXISTENTFILE @cms;
            }
    ...


    По поводу json.php и в принципе ограничения доступа, правильнее делать это через map или geo, например так:

    http {
    ....
            geo $my_client_ip $denied {
                    default 1;
                    127.0.0.1 0;
                    XX.XX.XX.XX 0; # <- IP1 с которого можно заходить
                    YY.YY.YY.YY 0;    # <- IP2 с которого можно заходить
            }
    
    server {
            listen       443 ssl;
            server_name  site.ru;
            root         /var/www/html/;
    ...
            set $my_client_ip $remote_addr;
            if ($http_x_forwarded_client_ip ~ "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}") {
                    set $my_client_ip $http_x_forwarded_client_ip;
            }
    
            error_page 403 = @deny;
    
            location @deny {
                    root /var/www/deny;
                    rewrite ^(.*)$ /index.html break;
            }
    
            location ~* ^/json\.php$ {
                    if ($denied) {
                            return 403;
                    }
                    try_files /NONEXISTENTFILE @json;
            }
    
            location @json {
                    try_files       $uri = 404;
                    fastcgi_pass    unix:/var/lib/php5-fpm/xxxxx.sock;
                    fastcgi_index   index.php;
                    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                    include         /etc/nginx/fastcgi_params;
            }
    
    }
    }


    4. Разрешаем доступ к /admin только с 1-го IP, для /admin/phpmyadmin


    Не делайте так! Организуйте для phpMyAdmin отдельный поддомен с отдельным виртуальным сервером и отдельной обработкой php5-fpm через отдельный сокет.
    Никогда не храните "левые" (вспомогательные) утилиты в общем каталоге web-приложения, это плохая практика. К примеру: Если в phpMyAdmin будет найдена критическая уязвимость, то даже в случае ограничения доступа к нему с определенного IP существует вероятность, что она может быть проэксплуатирована и тогда через неё поломают ваше web-приложение - оно вам нужно?

    По поводу location ~* /admin/ аналогично как для json.php.

    Ну и все рекомендации выше от Кирилл Несмеянов относительно hsts, ssl, ciphers, dh, ocsp stapling поддерживаю.
    Ответ написан
    4 комментария
  • Как правильно организовать балансировку нагрузки?

    Если Вы уверены, что Web-приложение справляется с нагрузкой, то возможно на балансировщике стоит увеличить таймауты, добавьте в location /

    proxy_connect_timeout 120s;
    proxy_send_timeout 120s;
    proxy_read_timeout 120s;


    На 3-х вебсерверах если Вы используете php-fpm то лучше работать через unix-сокеты, а не через tcp, через сокеты будет быстрее.

    Возможно стоит посмотреть в сторону параметра least_conn в upstream, то есть запросы сначала будут отправляются бэкенду с наименьшим количеством активных подключений (но с учетом весов). Подробнее тут.
    Если какой-то бэкенд мощнее других, то используйте определение веса через weight
    Так же настройте директивы max_fails и fail_timeout в блоке upstream (в моем примере ниже параметры проставлены для примера).

    Так же включите логи на балансировщике, это сильно упростит отладку:

    http {
        ...
        log_format upstream_log '[$time_local] $remote_addr - $remote_user - $server_name to: $upstream_addr: $request upstream_response_time $upstream_response_time msec $msec request_time $request_time';
    
    upstream servers {
                    least_conn;
                    server ip1;
                    server ip2 max_fails=3 fail_timeout=30s;
                    server ip3 max_fails=5 fail_timeout=30s;
                    keepalive 16;
            }
    
    server {
                    listen 80;
                    access_log /var/log/nginx/servers-access.log upstream_log;
                    error_log /var/log/nginx/servers-error.log debug;
    
                    location / {
                            proxy_pass http://servers;
                            proxy_http_version 1.1;
                            proxy_set_header Connection "";
                            proxy_connect_timeout 120s;
                            proxy_send_timeout 120s;
                            proxy_read_timeout 120s;
            }
    }
    Ответ написан
    Комментировать
  • Заражение вирусами в ОЧЕНЬ большой сети?

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

    А если брать проблему локально, то нужно смотреть каким крипто-локером заразились, к примеру у того же WannaCry или Petya (Not.Petya) есть стоп-файл, наличие которого в определенных местах останавливает работу крипто-локера. Конечно пробежаться по 6 тыс. ПК практически нереально, но....
    Ответ написан
    Комментировать
  • Как убрать No input file specified?

    Причин появления ошибки No input file specified несколько:
    1. У вас не установлена переменная SCRIPT_FILENAME в конфиге nginx;
    2. Задан неправильный аргумент root в конфиге nginx;
    3. Переменная open_basedir в /etc/php5/fpm/php.ini или в конфиге php5-fpm пула содержит путь, который не соответствует аргументу root в конфиге nginx;
    4. Пользователь с правами которого работает php5-fpm или конкретный пул php5-fpm не имеет прав доступа к каталогу или файлу с php-скриптом;

    Пример правильного конфига nginx + php5-fpm:
    server {
    ....
    root /var/www/mysite.com;
    index index.php index.html index.htm;
    
    location / {
            try_files $uri $uri/ =404;
    }
    location ~ \.php$ {
            try_files $uri = 404;
            fastcgi_pass unix:/var/lib/php5-fpm/mysite.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include /etc/nginx/fastcgi_params;
    }
    ...
    }
    Ответ написан
    Комментировать