Məzmuna keç
Server və .htaccess

HTTPS-ə Keçdikdən Sonra WordPress-də Mixed Content

HTTPS-ə keçiddən sonra WordPress mixed content xəbərdarlıqlarını təmizləyin: verilənlər bazasında qalan http:// ünvanlarını tapın, onları təhlükəsiz şəkildə əvəz edin və .htaccess faylında https-i məcbur edin.

Nəşr olundu

Sertifikatınız quraşdırılıb, sayt https üzərindən açılır, asma kilid isə hələ də görünmək istəmir. Bu, mixed content problemidir: səhifənin özü https ilə gəlib, amma onun içindəki nəsə — şəkil, üslub faylı, skript — hələ də adi http:// üzərindən istənilir. Bu təlimat həmin ünvanları tapmağı, serializasiya edilmiş məlumatı korlamadan əvəz etməyi, siteurlhome dəyərlərini düzəltməyi və problemin geri qayıda bilməməsi üçün server səviyyəsində https-i məcbur etməyi addım-addım göstərir.

Mixed content əslində nədir

Sertifikat quraşdırmaq bağlantının necə şifrələndiyini dəyişir. Səhifələrinizin nə tələb etdiyini isə dəyişmir. Köçürmədən əvvəl yazıya, vidcetə və ya mövzu parametrinə yazılmış hər bir http://yoursite.com/wp-content/uploads/logo.png ünvanı hələ də verilənlər bazasında oturur və brauzer onu sözəbaxan şəkildə təhlükəsiz olmayan bağlantı üzərindən istəyir.

Brauzerlər iki kateqoriyaya fərqli yanaşır və bu fərq məsələnin nə qədər təcili olduğunu qiymətləndirəndə əhəmiyyət daşıyır:

  • Aktiv mixed content — skriptlər, üslub faylları, iframe-lər, XHR sorğuları. Birmənalı olaraq bloklanır. Https-ə keçiddən sonra saytın heç bir yerdə xəta mesajı olmadan sınmış görünməsinin səbəbi məhz budur: üslub faylı səssizcə rədd edilib.
  • Passiv mixed content — şəkillər, audio, video. Adətən yenə də yüklənir, amma asma kilid aşağı salınır və bəzi brauzerlər «təhlükəsiz deyil» göstəricisi çıxarır.

Hər ikisini düzəltməyə dəyər. Amma yalnız birincisi işləri sındırır.

Addım 1: nəyin hələ də təhlükəsiz olmadığını tapın

Brauzerdən başlayın. Səhifəni açın, tərtibatçı alətlərini açın və konsolu oxuyun. Bloklanan və ya səviyyəsi aşağı salınan hər sorğu orada tam URL-i ilə adlandırılır. Bu, sizə nəyin təhlükəsiz olmadığını deyir; harada saxlandığını isə demir.

Bunun üçün birbaşa verilənlər bazasına baxın. Onu ixrac edin və nüsxədə axtarış aparın:

wp db export dump.sql
grep -o "http://example\.com[^\"']*" dump.sql | sort -u | head -50

WP-CLI mövcud deyilsə, mysqldump eyni faylı yaradır:

mysqldump -u USER -p DBNAME > dump.sql

Geri qayıdan unikal ünvanları oxuyun. Yükləmə yolları yazı məzmununa və metaya işarə edir. Mövzu resurslarının yolları adətən seçimlərə (options) işarə edir. Tanımadığınız domeni olan hər şey xarici yerləşdirmədir və fərqli həll tələb edir (aşağıda əhatə olunub).

Addım 2: əvvəlcə siteurl və home dəyərlərini düzəldin

siteurlhome WordPress-in yaratdığı demək olar ki, bütün daxili ünvanları qurmaq üçün istifadə etdiyi iki seçimdir. Onlardan hər hansı biri hələ də http:// deyirsə, verilənlər bazanızın qalan hissəsi nə qədər təmiz olsa da, WordPress təhlükəsiz olmayan ünvanlar yaymağa davam edəcək.

Onları yoxlayın:

wp option get siteurl
wp option get home

Yaxud sql ilə:

SELECT option_name, option_value
FROM wp_options
WHERE option_name IN ('siteurl', 'home');

Bu ikisi serializasiya edilmiş massiv deyil, adi sətirlərdir, ona görə də burada birbaşa sql yeniləməsi həqiqətən təhlükəsizdir:

UPDATE wp_options
SET option_value = REPLACE(option_value, 'http://example.com', 'https://example.com')
WHERE option_name IN ('siteurl', 'home');

Buna vaxt sərf etməzdən əvvəl bir tələ. Əgər wp-config.php faylı WP_HOME və ya WP_SITEURL sabitlərini təyin edirsə, həmin sabitlər verilənlər bazasını tamamilə üstələyir və yeniləməniz sanki heç nə etməmiş görünəcək:

define( 'WP_HOME', 'https://example.com' );
define( 'WP_SITEURL', 'https://example.com' );

Onları orada yeniləyin, ya da silin və idarəni verilənlər bazasına buraxın. Bunu ilk növbədə yoxlayın — «dəyişdim, amma heç nə olmadı» hallarının çoxunu məhz bu izah edir.

Addım 3: əvəzləmə serializasiyaya uyğun olmalıdır

Verilənlər bazasındakı qalan hər şey əsl riskin dayandığı yerdir və bu, əksər insanın gözlədiyi risk deyil. Təhlükə əvəzləmənin bəzi ünvanları buraxması deyil. Təhlükə odur ki, o, mətn səviyyəsində uğur qazanır və ətrafdakı məlumatı məhv edir.

WordPress massivləri və obyektləri php ilə serializasiya edilmiş sətirlər kimi saxlayır və həmin format özündə olan hər sətrin bayt uzunluğunu qeyd edir:

a:1:{s:4:"logo";s:38:"http://example.com/img/logo.png";}

Kobud sql REPLACE ilə http:// hissəsini https:// ilə əvəz edin — mətn bir bayt uzanır, elan edilmiş uzunluq isə köhnə dəyərində qalır. PHP uzunluğu oxuyur, həmin sayda bayt irəli gedir, gözlədiyi yerdə sonlandırıcını tapmır və bütöv massivi deserializasiya etməkdən imtina edir. Bundan sonra WordPress mövzuya və ya plaginə elə bir dəyər ötürür ki, sanki parametr heç vaxt yadda saxlanmayıb.

Simptom xəta mesajı deyil. Simptom vidcetlərin yox olması, fərdiləşdirmə parametrlərinin sıfırlanması və səhifə qurucusu tərtibatlarının boş göstərilməsidir — üstəlik idarə panelində heç nə səhv getdiyini bildirmir. Ehtiyat nüsxə olmadan bundan bərpa olunmaq həqiqətən ağrılıdır, ona görə də nüsxə götürün:

wp db export backup-before-https-replace.sql

Sonra deserializasiya edən, dekodlanmış struktur daxilində əvəzləmə aparan və düzəldilmiş uzunluqlarla yenidən serializasiya edən alət istifadə edin. Əvvəlcə quru işləmə:

wp search-replace 'http://example.com' 'https://example.com' --dry-run --all-tables --skip-columns=guid

Hesabatı oxuyun. Tanımadığınız cədvəl minlərlə uyğunluq göstərirsə, dayanın və icra etməmişdən əvvəl baxın. Sonra onu real olaraq işlədin:

wp search-replace 'http://example.com' 'https://example.com' --all-tables --skip-columns=guid --report-changed-only

--skip-columns=guid vacibdir: guid lent oxuyucuları üçün daimi identifikatordur, canlı ünvan deyil, və onu yenidən yazmaq abunəçilərin bütün arxivinizi yeni yazılar kimi görməsinə səbəb ola bilər. Nəyisə işə salmazdan əvvəl hansı sütunların adi sql üçün təhlükəsiz olduğunu, hansılarının isə serializasiyanı nəzərə alan yanaşma tələb etdiyini görmək istəyirsinizsə, ifadələri WordPress axtar-əvəz et sql aləti ilə qurun.

Əmr sətrindən istifadə edə bilmirsinizsə, serializasiya edilmiş məlumatı emal etdiyini açıq şəkildə bildirən miqrasiya plagini eyni dekodlama işini idarə panelindən görür. Alət bunu bildirmirsə, etmədiyini fərz edin.

Addım 4: serverdə https-i məcbur edin

Verilənlər bazasını təmizləmək səhifələrinizin təhlükəsiz olmayan resursları istəməsinin qarşısını alır. Amma bu, ziyarətçinin ilk növbədə http:// ünvanına gəlməsinin qarşısını almır. Bu, server səviyyəsində yönləndirmədir və Apache-də onun yeri .htaccess faylıdır:

# BEGIN Force HTTPS
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
# END Force HTTPS

Yerləşdirmə barədə iki qeyd. Bunu # BEGIN WordPress markerlərindən yuxarı qoyun — onların içindəki hər şey kimsə daimi keçidləri yadda saxlayan kimi atılır. Həmçinin bu, yalnız mod_rewrite aktiv olanda və virtual host üstünə yazmağa icazə verəndə (AllowOverride All, ən azı FileInfo) işləyir. Nginx-də .htaccess tamamilə nəzərə alınmır və bunun əvəzinə server blokuna yazılmalıdır.

RedirectMatch bu işi görməyəcək. O, yalnız sorğu yolu ilə uyğunlaşır və cari sorğunun artıq təhlükəsiz olub-olmadığını yoxlaya bilmir, ona görə də https sorğularını yenidən özlərinə yönləndirir. Yuxarıdakı şərtli RewriteRule isə doğru vasitədir.

Yönləndirmə dövrəsi və onun səbəbi

Həmin qaydanı əlavə edən kimi sayt sonsuz yönləndirməyə başlayırsa, deməli TLS bağlantınız yuxarıda bir yerdə — yük balanslaşdırıcısında, tərs proksidə və ya CDN-də — sonlanır və oradan Apache-yə adi http ötürülür. Apache təhlükəsiz olmayan sorğu görür, https ünvanına yönləndirir, proksi yenidən http ötürür və beləcə fırlanır.

Onun əvəzinə ötürülən başlığı yoxlayın:

RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Belə quruluşda WordPress-in özündə də eyni kor nöqtə var — is_ssl() funksiyası proksinin heç vaxt təyin etmədiyi $_SERVER['HTTPS'] dəyərini oxuyur, ona görə də idarə paneli ünvanları http:// şəklində çıxır. Bunu wp-config.php faylına, «redaktəni dayandırın» sətrindən yuxarı əlavə edin:

if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) && 'https' === $_SERVER['HTTP_X_FORWARDED_PROTO'] ) {
	$_SERVER['HTTPS'] = 'on';
}

Risk barədə açıq danışmağa dəyər: X-Forwarded-Proto müştəri tərəfindən göndərilən başlıqdır. Ona etibar etmək yalnız o halda düzgündür ki, sizin nəzarətinizdə olan proksi onu həmişə üstündən yazır. İnternetdən birbaşa əlçatan olan serverdə isə o, saxtalaşdırıla bilər.

Verilənlər bazasında əvəzləmənin düzəltməyəcəyi şeylər

  • Fayllarda sabit yazılmış ünvanlar. functions.php faylına, alt mövzu şablonuna və ya sətiriçi resurs yoluna yazılmış hər şey verilənlər bazasında deyil. Mövzu qovluğunu ayrıca grep edin.
  • Ekranlanmış JSON. Bəzi qurucular ünvanları https:\/\/example.com şəklində saxlayır. Normal formaya görə axtarış onları tamamilə buraxır, ona görə də ekranlanmış sətir üzərində ikinci keçid lazım ola bilər.
  • Xarici resurslar. Yalnız http üzərindən əlçatan olan üçüncü tərəf skripti və ya yerləşdirməsi sizin tərəfinizdən düzəldilə bilməz. Onun https versiyasını tapın, ya da ondan imtina edin.
  • Keşlər. Səhifə keşi, obyekt keşi və CDN nüsxələri düzgün əvəzləmədən sonra da köhnə markup verməyə davam edir. Əvəzləmənin uğursuz olduğu qənaətinə gəlməzdən əvvəl hər üçünü təmizləyin.

Buraxmağa dəyən bir şey: upgrade-insecure-requests Content Security Policy başlığı təhlükəsiz olmayan sorğuları brauzerdə yenidən yazaraq xəbərdarlıqları susduracaq. O, simptomu müalicə edir və səhv ünvanları verilənlər bazanızda olduğu kimi saxlayır, növbəti ixrac, miqrasiya və ya lent isə onları özü ilə irəli aparacaq. Əvvəlcə məlumatı düzəldin, sonra istəyirsinizsə, bunu ehtiyat tor kimi istifadə edin.

Hələ də ilişib qalmısınız?

Hər addımdan sonra siteurlhome dəyərlərini yenidən yoxlayın — plaginlər və miqrasiya alətləri bəzən onları arxanızca yenidən yazır. Əgər konsol hələ də nüsxədə tapa bilmədiyiniz təhlükəsiz olmayan ünvanı adlandırırsa, səhifənin mənbə kodunu açın və onu orada axtarın: əgər o, yaradılan markup daxilində görünür, amma verilənlər bazasında yoxdursa, deməli o, php tərəfində qurulur və düzəldilməli olan şey onu yaradan mövzu və ya plagindir.

FAQ

Suallar

SSL sertifikatı quraşdırandan sonra saytım nə üçün hələ də mixed content xəbərdarlığı göstərir?

Sertifikat yalnız bağlantının necə şifrələndiyini dəyişir, səhifələrinizin nə tələb etdiyini yox. Köhnə http:// ünvanları verilənlər bazasında — yazı məzmununda, vidcet parametrlərində və mövzu tənzimləmələrində — qalır. Brauzer səhifəni https üzərindən yükləyir, şəklin və ya skriptin adi http ilə istənildiyini görür və başqa cür təhlükəsiz olan səhifədə mixed content barədə xəbər verir.

WordPress verilənlər bazasında qalan http:// ünvanlarını necə tapa bilərəm?

Səhifəni brauzerdə açın və hər təhlükəsiz olmayan sorğunu URL-i ilə adlandıran tərtibatçı konsolunu oxuyun. Sonra verilənlər bazasını ixrac edin və nüsxədə domeninizi http prefiksi ilə axtarın. Cədvəl üzrə uyğunluqları saymaq problemin yazı məzmununda, wp_options cədvəlində, yoxsa gözləmədiyiniz plagin cədvəllərində olduğunu göstərir.

Mixed content problemini adi sql axtar-əvəz et əməliyyatı ilə həll edə bilərəmmi?

Yalnız siteurl və home kimi sadə skalyar dəyərlər üçün. WordPress-in serializasiya edilmiş massiv kimi saxladığı hər şey — bu da əksər seçim və meta dəyərlərini əhatə edir — içindəki hər sətrin bayt uzunluğunu qeyd edir. Kobud əvəzləmə mətni dəyişir, amma köhnə uzunluğu olduğu kimi saxlayır, dəyər deserializasiya oluna bilmir və parametr səssizcə öz standart dəyərinə qayıdır.

WordPress-də https-i hansı .htaccess qaydası məcbur edir?

HTTPS dəyişəni üzərində şərtlə qorunan bir RewriteRule qaydası, üstəlik BEGIN WordPress markerlərindən yuxarıda yerləşdirilmiş ki, daimi keçidləri yadda saxlamaq onu silməsin. Proksi və ya CDN arxasında HTTPS dəyişəni təhlükəsiz sorğularda belə söndürülmüş kimi oxunur, ona görə də onun əvəzinə X-Forwarded-Proto başlığını yoxlayın, əks halda qayda sonsuz yönləndirəcək.

HTTPS-i məcbur etdikdən sonra saytım nə üçün yönləndirmə dövrəsinə düşdü?

Demək olar ki, əminliklə TLS bağlantınız proksi və ya CDN səviyyəsində sonlanır və oradan Apache-yə adi http ötürülür. Yenidənyazma qaydası təhlükəsiz olmayan sorğu görür, https ünvanına yönləndirir, proksi yenidən http ötürür və dövrə təkrarlanır. Şərti X-Forwarded-Proto başlığına keçirin və wp-config.php faylında HTTPS server dəyişənini təyin edin.

Mixed content bütün səhifəni sındırır, yoxsa yalnız asma kilidi?

Bu, resursdan asılıdır. Brauzerlər skript, üslub faylı və iframe kimi aktiv mixed content resurslarını birmənalı olaraq bloklayır, bu da heç bir görünən izahat olmadan dizaynı və ya funksionallığı sındıra bilər. Şəkil və video kimi passiv mixed content adətən yenə də yüklənir, amma asma kilid aşağı salınır və ziyarətçilər «təhlükəsiz deyil» göstəricisini görə bilər. Hər ikisini düzəltməyə dəyər.