Kategoriler
WordPress

WordPress güvenlik ve performans [2021]

WordPress güvenlik, performans ve fazlası. Bu ipuçlarının hepsi şahsım tarafından test edilmiş ve onaylanmıştır.

Bir önceki yazımda WordPress login güvenliği başlığında güvenlik ipucu paylaşmıştım. Burada da yine birkaç farklı güvenlik ve performans ipucu paylaşacağım.

Bu işlerimler WordPress sitenizin hem güvenli hem de gereksiz yüklerden kurtulacağı için daha hızlı çalışmasını sağlayacaktır.

Öncelikli olarak WordPress sitenizin wp.login.php dosyası ve wp-admin dizinini şifrelemenizi öneririm, bu konudan önceki yazımızda bahsetmiştik.

Aşağıdaki .htaccess kuralı WordPress sitenize saldırıları ve gereksiz yük oluşturmayı kısmen engelleyecektir. siteniz.com kısmını kendi site adresinizle değiştiriniz.

<IfModule mod_rewrite.c>
RewriteEngine On
#Arama sorgularını sınırlar, siteniz harici sadece get.
RewriteCond %{REQUEST_METHOD} !^(GET) [NC]
RewriteCond %{HTTP_REFERER} !^https://(.*)?siteniz.com [NC]
RewriteCond %{QUERY_STRING} ^s=(.*)$ [NC]
RewriteRule .* - [F,L]
#Eğer sitenizde içerik kleyen sadece 1 kişi varsa kullanın.
RewriteCond %{QUERY_STRING} "^(.*)&?author=(.*)$" [NC]
RewriteRule ^(.*)$ https://siteniz.com/hakkinda/ [R=301,NC,QSD,L]
#Facebook'dan gelen kullanıcıları doğru adrese yönlendirir.
RewriteCond %{QUERY_STRING} "^(.*)&?fbclid=(.*)$" [NC]
RewriteRule ^(.*)$ /$1?%1 [R=301,L]
#AMP'den gelen kullanıcıları doğru adrese yönlendirir.
RewriteCond %{QUERY_STRING} "^(.*)&?_gl=(.*)$" [NC]
RewriteRule ^(.*)$ /$1?%1 [R=301,L]
#Eğer sitenize üyelik kapalı ise kullanın.
RewriteCond %{QUERY_STRING} ^registration=disabled$ [NC]
RewriteRule ^wp-login.php$ wp-login.php [R=301,NC,QSD,L]
#Şifre sıfırlama isteklerini kapatın.
RewriteCond %{QUERY_STRING} ^action=lostpassword$ [NC]
RewriteRule ^wp-login.php$ wp-login.php [R=301,NC,QSD,L]
#Kötü niyetli botların otomatik .aspx saldırıları bloklayın.
RewriteCond %{REQUEST_URI} ^(.*)?.aspx(.*)$
RewriteRule ^(.*)$ - [F]
#User Agent boş ise ve sitenizden gelmiyorsa bu dosyalara erişimi engelleyin.
RewriteCond %{REQUEST_METHOD} POST [OR]
RewriteCond %{HTTP_USER_AGENT} ^$
RewriteCond %{HTTP_REFERER} !^https://(.*)?siteniz.com [NC]
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-comments-post\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?admin-ajax.php\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
RewriteRule ^(.*)$ - [F]
</IfModule>

Aşağıdaki kurallar ise sitenizdeki bazı kullanılması gereksiz şeyleri yönlendirmek ve bir miktar güvenlik için kullanabilirsiniz:

#Ana sayfa ve kategoriler harici tekil sayfaların feed adreslerini yönlendirir.
RedirectMatch 301 ^/(?!kategori/)(.*)/feed/$ https://wolkanca.com.tr/$1/
#Yorumlarla işiniz yoksa kullanın. 
RedirectMatch 301 ^/comments/(.*) https://wolkanca.com.tr/
RedirectMatch 301 ^/wp-comments-post.php(.*)$ https://wolkanca.com.tr/
#Bunlar gereksiz şeyler.
RedirectMatch 301 ^/xmlrpc.php(.*)$ https://wolkanca.com.tr/
RedirectMatch 301 ^/wp-includes/wlwmanifest.xml(.*)$ https://wolkanca.com.tr/
#Sitenizde sizden başka yazar yok ise kullanın.
RedirectMatch 301 ^/author/(.*)$ https://wolkanca.com.tr/hakkimda/
#Sonunda tırnak işareti olan URL'leri yönlendir(sık karşılaşılır)
RedirectMatch 301 ^/(.*)/&quot$ https://wolkanca.com.tr/$1/
#Bunlar saldırı yapanların en çok kullandığı dizin sorguları.
RedirectMatch 301 ^/wp/(.*)$ https://wolkanca.com.tr/wordpress/
RedirectMatch 301 ^/old/(.*)$ https://wolkanca.com.tr/
RedirectMatch 301 ^/oldsite/(.*)$ https://wolkanca.com.tr/
RedirectMatch 301 ^/new/(.*)$ https://wolkanca.com.tr/
RedirectMatch 301 ^/backup/(.*)$ https://wolkanca.com.tr/

Ayrıca sitenize bir miktar hız kazandırmak için aşağıdaki kuralları kullanabilirsiniz:

#Disable ETags, bu önerilir.
<IfModule mod_headers.c>
    Header unset ETag
</IfModule>
FileETag None

#Bu mutlaka olmalı, klasörlerin içeriğini korumak için.
Options -Indexes

#Dosyaların karakter kodlamasını UTF-8 uyumlu yapar. 
AddDefaultCharset UTF-8
<filesMatch "\.(htm|html|xml|txt|css|js|json|pdf)$">
AddDefaultCharset UTF-8
DefaultLanguage tr
</filesMatch>

#Performans için önbellek ayarları.
<IfModule mod_expires.c>
  ExpiresActive On
  #Resimler
  ExpiresByType image/jpeg "access plus 1 year"
  ExpiresByType image/jpg "access plus 1 year"
  ExpiresByType image/gif "access plus 1 year"
  ExpiresByType image/png "access plus 1 year"
  ExpiresByType image/webp "access plus 1 year"
  ExpiresByType image/svg+xml "access plus 1 year"
  ExpiresByType image/x-icon "access plus 1 year"
  #Video - audio
  ExpiresByType video/webm "access plus 1 year"
  ExpiresByType video/mp4 "access plus 1 year"
  ExpiresByType video/mpeg "access plus 1 year"
  ExpiresByType audio/mp3 "access plus 1 year"
  ExpiresByType audio/mpeg "access plus 1 year"
  #Fonts
  ExpiresByType font/ttf "access plus 1 year"
  ExpiresByType font/otf "access plus 1 year"
  ExpiresByType font/woff "access plus 1 year"
  ExpiresByType font/woff2 "access plus 1 year"
  ExpiresByType font/eot "access plus 1 year"
  ExpiresByType application/font-woff "access plus 1 year"
  ExpiresByType application/font-woff2 "access plus 1 year"
  #CSS, JavaScript
  ExpiresByType text/css "access plus 1 year"
  ExpiresByType text/javascript "access plus 1 year"
  ExpiresByType application/javascript "access plus 1 year"
  #Diğer
  ExpiresByType application/pdf "access plus 1 year"
  ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
  ExpiresDefault "access 1 month"
</IfModule>

#Cache-Control Headers
<IfModule mod_expires.c>
  <IfModule mod_headers.c>
    <filesMatch "\.(css|js|ico|jpg|jpeg|png|gif|webp|mp3|mp4|webm|mpeg|ttf|otf|woff|woff2|eot|pdf|txt|json|xml)$">
      Header append Cache-Control "public"  
    </filesMatch>
    <filesMatch "\.(x?html?|php)$">
      Header append Cache-Control "private"
    </filesMatch>
  </IfModule>
</IfModule>

<IfModule mod_deflate.c>
  #HTML, CSS, JavaScript, Text, XML and fonts sıkıştırır.
  AddOutputFilterByType DEFLATE application/javascript
  AddOutputFilterByType DEFLATE application/rss+xml
  AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
  AddOutputFilterByType DEFLATE application/x-font
  AddOutputFilterByType DEFLATE application/x-font-opentype
  AddOutputFilterByType DEFLATE application/x-font-otf
  AddOutputFilterByType DEFLATE application/x-font-truetype
  AddOutputFilterByType DEFLATE application/x-font-ttf
  AddOutputFilterByType DEFLATE application/x-font-woff
  AddOutputFilterByType DEFLATE application/x-font-woff2
  AddOutputFilterByType DEFLATE application/x-font-eot
  AddOutputFilterByType DEFLATE application/x-javascript
  AddOutputFilterByType DEFLATE application/xhtml+xml
  AddOutputFilterByType DEFLATE application/xml
  AddOutputFilterByType DEFLATE font/opentype
  AddOutputFilterByType DEFLATE font/otf
  AddOutputFilterByType DEFLATE font/ttf
  AddOutputFilterByType DEFLATE font/woff
  AddOutputFilterByType DEFLATE font/woff2
  AddOutputFilterByType DEFLATE font/eot
  AddOutputFilterByType DEFLATE image/svg+xml
  AddOutputFilterByType DEFLATE image/x-icon
  AddOutputFilterByType DEFLATE text/css
  AddOutputFilterByType DEFLATE text/html
  AddOutputFilterByType DEFLATE text/javascript
  AddOutputFilterByType DEFLATE text/plain
  AddOutputFilterByType DEFLATE text/xml

  #Eski tarayıcılardaki hatayı çözer.
  BrowserMatch ^Mozilla/4 gzip-only-text/html
  BrowserMatch ^Mozilla/4\.0[678] no-gzip
  BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
  Header append Vary User-Agent
</IfModule>

Ayrıca aşağıdaki kurallar ile sitenizin güvenliğini bir tık daha yükseltebilirsiniz, daha fazla bilgi için: SSL siteler için HSTS

#Security Headers
<IfModule mod_headers.c>
#Bunlar tavsiye edilir.
Header set X-XSS-Protection "1; mode=block"
Header set X-Content-Type-Options "nosniff"
#Strict-Transport-Security ile siteniz sadece HTTPS olarak çalışır, HTTP olarak hiçbir dosya tarayıcıda gösterilmez.
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
#Sitenizden yapılan tıklamalarda referans bağlantı olarak sadece sitenin ana sayfasını gösterir, ayrıntı vermez.
Header set Referrer-Policy "strict-origin-when-cross-origin"
Header set Permissions-Policy: "accelerometer=(), camera=(), geolocation=(), microphone=()"
<FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|css|js)$">
#Bu dosyalara siteniz dışında çalışmasına izin vermek için.
Header unset X-XSS-Protection
Header unset X-Content-Type-Options
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials true
</FilesMatch>
</IfModule>

Yukarıdakiler sitenin ana dizinindeki .htaccess doyası içindi, aşağıdakiler de temanızın function.php dosyasına ekleyerek kullanabileceğiniz bazı güvenlik, kullanılabilirlik ve performans düzeltmeleridir.

/*bazi seyler gereksiz*/
remove_action('xmlrpc_rsd_apis', 'rest_output_rsd');
remove_action('wp_head', 'rest_output_link_wp_head', 10);
remove_action('template_redirect', 'rest_output_link_header', 11);
add_filter('xmlrpc_enabled', '__return_false');
remove_action('wp_head', 'rsd_link'); 
remove_action('wp_head', 'wlwmanifest_link'); 
remove_action('wp_head', 'wp_shortlink_wp_head', 10);
remove_action('template_redirect', 'wp_shortlink_header', 11);
remove_action('wp_head', 'feed_links_extra', 3); 
remove_action('wp_head', 'feed_links', 2); 
remove_action('wp_head', 'wp_generator');
remove_action('wp_head', 'print_emoji_detection_script', 7); 
remove_action('admin_print_scripts', 'print_emoji_detection_script'); 
remove_filter('embed_head', 'print_emoji_detection_script');
remove_action('wp_print_styles', 'print_emoji_styles'); 
remove_action('admin_print_styles', 'print_emoji_styles'); 
remove_filter('the_content_feed', 'wp_staticize_emoji');
remove_filter('comment_text_rss', 'wp_staticize_emoji');	
remove_filter('wp_mail', 'wp_staticize_emoji_for_email');

//Remove X-Pingback from Header
add_action('wp', function(){
    header_remove('X-Pingback');
	header_remove('X-Powered-By');
}, 1000);

// the_guid to permalink 
function filter_the_guid() {  
    return get_the_permalink();
};
add_filter( 'the_guid', 'filter_the_guid', 10, 1 ); 

//Google CDN jQuery
add_action('init', 'jquery_cdn');
function jquery_cdn(){
   if (!is_admin()) { if (function_exists( 'is_amp_endpoint' ) && is_amp_endpoint()) : else : 
    wp_deregister_script('jquery');
    wp_register_script('jquery', 'https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js', false);
	  //wp_script_add_data( 'jquery', 'defer', true );
    wp_enqueue_script('jquery');
	endif;   }
}
//Embed scripti single değilse kaldır.
add_action('wp_footer', 'my_deregister_scripts');
function my_deregister_scripts(){ 
if(!is_single()) : 	wp_deregister_script( 'wp-embed' );	else: 	wp_script_add_data( 'wp-embed', 'async', true ); endif;
}
//Eğer temanız kullanmıyorsa bunu kullanın.
add_action('wp_enqueue_scripts', 'dm_remove_wp_block_library_css');
function dm_remove_wp_block_library_css(){
if ( !is_admin() ) : wp_dequeue_style( 'wp-block-library' ); endif; 
}

/*wp versiyonunu her yerden sil*/
function remove_wordpress_version(){
return '';
}
add_filter('the_generator', 'remove_wordpress_version');

/*js ve css dosyalarından query string sil*/
function remove_cssjs_ver( $src ){
if( strpos( $src, '?ver=' ) )
$src = remove_query_arg( 'ver', $src );
return $src;
}
add_filter('style_loader_src', 'remove_cssjs_ver', 10, 2);
add_filter('script_loader_src', 'remove_cssjs_ver', 10, 2);

/*kategori ve etikette bir tane varsa yonlendir*/
add_action('template_redirect', 'arsiv_sadecebirsonucise_post');
function arsiv_sadecebirsonucise_post(){
global $wp_query;
global $paged;
if( is_archive() ) : 
if( $wp_query->post_count == 1 ){ the_post(); $post_url = get_permalink(); wp_redirect( $post_url, 302, 'WOLKANCA' ); }
if( $wp_query->post_count == 0 ){ wp_redirect( '/', 301, 'WOLKANCA' ); exit; }
if( get_query_var( 'paged' ) && $wp_query->post_count == 0 ){ wp_redirect( '/', 301, 'WOLKANCA' ); exit; }
endif;
}

/*login sayfasini duzenle, logo img değiştirin*/
add_action('login_enqueue_scripts', 'my_login_logo_one');
function my_login_logo_one(){ 
echo '<style type="text/css">body.login div#login h1 a{background-image: url(https://wolkanca.com.tr/apple-icon-180x180.png);}p#nav, #login_error, #backtoblog, .privacy-policy-page-link{display:none;}html{filter: invert(1);}html a, html :before, html input{filter: invert(1);}form#loginform{border:none;background-color:transparent;box-shadow:none;}</style>';
} 
add_filter('login_headerurl', 'wpb_login_logo_url');
function wpb_login_logo_url(){
    return get_bloginfo('url');
}
add_filter('login_headertitle', 'wpb_login_logo_url_title');
function wpb_login_logo_url_title(){
    return get_bloginfo('name');
}

add_action('login_footer', 'login_footer_ekle');
function login_footer_ekle(){
    echo '<p style="text-align:center;margin:auto;">&copy; 2021 <a href="/">Volkan Yılmaz</a></p>';
}

/*TinyMCE noreferer eklemesin, yine de ekliyor :) */
add_filter('tiny_mce_before_init','tinymce_allow_unsafe_link_target');
function tinymce_allow_unsafe_link_target( $mceInit ){
$mceInit['allow_unsafe_link_target']=true;
return $mceInit;
}
add_filter('wp_targeted_link_rel', 'my_targeted_link_rel',999);
function my_targeted_link_rel($rel_values){
 return 'noopener';
}
//login sayfasında hataları gösterme.
add_filter('login_errors', 'no_wordpress_errors');
function no_wordpress_errors(){
  return 'Olmuyor!';
}
//Admin sayfasında footer değiştirir.
add_filter('admin_footer_text', 'remove_footer_admin');
function remove_footer_admin(){
    echo '<span id="footer-thankyou">Developed by <a href="/" target="_blank">Volkan Yılmaz</a></span>';
}

#WordPress adminde yeni yazı eklemede hoş geldin şeyini kaldırır.
add_action('admin_enqueue_scripts', 'dn_enqueue_scripts');
function dn_enqueue_scripts(){
    wp_add_inline_script(
        'wp-edit-post',
        'wp.data.select( "core/edit-post" ).isFeatureActive( "welcomeGuide" ) && wp.data.dispatch( "core/edit-post" ).toggleFeature( "welcomeGuide" );'
    );
}

Hepsi bu kadar, tümünü kendim düzenledim, test ettim, hatasız ve sorunsuzdur, afiyet olsun.

Ayrıca bakınız:

WordPress versiyonunu gizlemek

Bu arada bugün çok mutluyum çünkü 🐔 artık yok, odamın cephesinde kümes olduğu için 7/24 öten bir horoz ile yaşıyordum hiç hoş değil tavsiye etmem, horozu kesmedik(önceki horozu kesip yedik), bunu başka birine verip tavuk ile takas ettik.

Daha fazlası için Twitter’dan takipte kalın.

WOLKANCA

Volkan Yılmaz

Digital Marketing & WordPress & SEO volkan@volkanyilmaz.com.tr