l30 securing wordpress
the non root user is the owner of all the sites and directories.
the web server is the group owner.
cd /var/www/example.com/public_html/
ls -l
change group owner :
sudo chown -R rootuser:www-data /var/www/example.com
ls -l
sudo chown -R www-data:www-data /var/www/example.com/public_html/wp-contents
ls -l
sudo find /var/www/example.com/public_html/ -type d -exec chmod 755 {} \;
ls -l
sudo find /var/www/example.com/public_html/ -type f -exec chmod 644 {} \;
ls -l
sudo chmod 664 .htaccess wp-config.php
ls -l
deny access to wp-config.php and xmlrpc.php
disable hotlinking of images
block author scans, deny access to certain file extensions
deny php execusion, uploads, plugins and themes
unless a plugin need it, in which case you comment the disable php in plugins
rule, in the wp-config.php file.
deny access to important wordpress files
filter suspicious query strings in the url
filter non-english characters
clear
nano .htaccess
under # END WordPress
paste :
#Deny Access to WP-config and xmlrpc
<FilesMatch "(wp-config|xmlrpc)\.php$">
Deny from all
</FilesMatch>
#Disable Hotlinking of Images - change site.com
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?site.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]
# BEGIN block author scans
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
#DENY ACCESS TO FILES
<FilesMatch "\.(?:txt|htm|html)$">
Order allow,deny
Deny from all
</FilesMatch>
# General WordPress Protection
RewriteRule ^wp-admin/install\.php$ - [F]
RewriteRule ^wp-admin/includes/ - [F]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F]
RewriteRule ^wp-includes/theme-compat/ - [F]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (^|.*/)\.(git|svn)/.* - [F]
# Disable PHP in Uploads
RewriteRule ^wp\-content/uploads/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Disable PHP in Plugins - check for issues with installed plugins
# RewriteRule ^wp\-content/plugins/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Disable PHP in Themes - check for issues with selected theme
# RewriteRule ^wp\-content/themes/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Filter Request Methods
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
RewriteRule ^.* - [F]
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
RewriteRule ^.* - [F]
# Filter Suspicious Query Strings in the URL
RewriteCond %{QUERY_STRING} \.\.\/ [OR]
RewriteCond %{QUERY_STRING} \.(bash|git|hg|log|svn|swp|cvs) [NC,OR]
RewriteCond %{QUERY_STRING} etc/passwd [NC,OR]
RewriteCond %{QUERY_STRING} boot\.ini [NC,OR]
RewriteCond %{QUERY_STRING} ftp: [NC,OR]
RewriteCond %{QUERY_STRING} https?: [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)script(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [NC,OR]
RewriteCond %{QUERY_STRING} base64_decode\( [NC,OR]
RewriteCond %{QUERY_STRING} %24&x [NC,OR]
RewriteCond %{QUERY_STRING} 127\.0 [NC,OR]
RewriteCond %{QUERY_STRING} (^|\W)(globals|encode|localhost|loopback)($|\W) [NC,OR]
RewriteCond %{QUERY_STRING} (^|\W)(concat|insert|union|declare)($|\W) [NC,OR]
RewriteCond %{QUERY_STRING} %[01][0-9A-F] [NC]
RewriteCond %{QUERY_STRING} !^loggedout=true
RewriteCond %{QUERY_STRING} !^action=jetpack-sso
RewriteCond %{QUERY_STRING} !^action=rp
RewriteCond %{HTTP_COOKIE} !wordpress_logged_in_
RewriteCond %{HTTP_REFERER} !^http://maps\.googleapis\.com
RewriteRule ^.* - [F]
# Filter Non-English Characters
RewriteCond %{QUERY_STRING} %[A-F][0-9A-F] [NC]
RewriteRule ^.* - [F]
l31 SSL certificate
sudo apt-get install software-properties-common
sudo apt-get-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-apache
continue? y
clear
install free ssl certificates :
sudo certbot --apache -d example.com -d
www.example.comemail prompt :
admin@example.comagree? a
share email? n
redirect trafic to https ? 2
go to ssllabs.com, test your server, it should rank A
l32 configure ssl cert to obtain A+ rating
cd etc/apache2/sites-available/
cd ../mods-available/
ls
sudo cp ssl.conf.bak
(/etc/apache2):
cd..
clear
sudo mkdir ssl/
ls
cd ssl/
sudo openssl dhparam -out dhparam.pem 2048
wait a few minutes
ls
you should see dhparam.pem
cd ../mods-available/
ls
sudo nano ssl.conf
edit SSLProtocol +TLSv1.2
ADD to the bottom of the ssl.conf file above </Ifmodule>:
#SSL Stapling, only in httpd 2.3.3 and later
SSLUseStapling on
SSLStaplingResponderTimeout 5
SSLStaplingReturnResponderErrors off
SSLStaplingCache shmcb:/var/run/ocsp(128000)
# DHE (Diffie-Hellman key exchange)
SSLOpenSSLConfCmd Curves secp384r1
SSLOpenSSLConfCmd DHParameters "/etc/apache2/ssl/dhparam.pem"
exit and save
sudo apachectl configtest
Syntax OK
Change to the /etc/letsencrypt/ directory and open the file: options-ssl-apache.conf file
cd /etc/letsencrypt/
sudo nano options-ssl-apache.conf
Change SSLProtocol to:
SSLProtocol -all +TLSv1.2
Modify your sites LE generated ssl virtual host file
sudo nano /etc/apache2/sites-available/example.com-le-ssl.conf
Add underneath SSL Certificate paths above </VirtualHost>:
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains;"
ctrl+x and save
sudo apachectl configtest
Syntax OK
sudo systemctl restart apache2
l33 certificates pt3
display certificates :
sudo certbot certificates
to delete a cert from D server :
sudo certbot delete
c to cancel
test renewl process :
sudo certbot renew --dry-run
########################################################
ensure all contents on the site uses https
by search and replace http to https for the wordpress DB:
cd /var/www/example.com/public_html/
ls
test the command 1st :
wp search-replace
http://example.com https://example.com --dry-run
run :
wp search-replace
http://example.com https://example.comclear php opcache
sudo systemctl restart php7.2-fpm
l34 page caching using w3 total cache
cd /var/example.com/public_html/
ls -l
ls -la
cd ..
ls -l
when you install plugins(security and caching) that need to write to the wp config file or
htaccess file, you should give the webserver write permissions in the html dir
afterwords change the dir back to 755
sudo chmod 775 public_html/
ls -l
the group has write permissions in that directory
https://example.com/wp-admin/index.phpplugins->Add New
search w3
install : w3 total cache, clck activate, settings(of w3)
page cache: enable
disk cache methode disk Enhanced
minify: enable
minify mode : manual
opcode cache opcode: zend opcache
browser cache enabled
save all settings->save all settings and purge caches
on the left side bar : page cache->
cache preload, check: automatically prime
preload the post cache
save all settings, select empty the page cache
l35 installing additional wordpress sites
get domain name,l24
cd /var/www
ls
sudo mkdir -p example2.com/public_html/.well-known/
ls -l
sudo chown -R non_root_user:www-data example2.com/
ls -l
cd example2.com/
ls -l
CREATE APACHE VIRTUAL HOST
cd public_html/
cd /etc/apache2/sites-available/
sudo cp example.com.conf example2.com.conf
sudo nano example.com.conf
delete all rewright rules at the buttom
replace example.com to example2.com
ctrl + x, save
sudo a2ensite example2.com.conf
sudo systemctl restart apache2
sudo mysql -u root
see l20 to create a DB
cd /var/www/example2.com/public_html/
wp core download
wp core config --dbname= --dbuser= --dbpass= --dbprefix=
wp core install --url= --title='' --admin_user= --admin_password= --admin_email=
touch .htaccess
ls -al
sudo chown nonrootuser:www-data .htaccess
go to example.com/wp-admin
to log in paste the admin user then pass
next configure permalinks and delete default posts and pages:
settings->permalinks->set to post name->save changes
posts->all posts->trash hello world (trash all pages)->no comments in commets tab
set admin nickname :
Users tab->all users->edit->type nickname at its field->display name
publicly as : set to the new nick name->update profile
dashboard->home
l36 installing additional wordpress sites pt2: securing wordpress
from /var/www/example2.com/public_html :
cd ../../
sudo chown -R nonrootuser:www-data example2.com/
cd example2.com/public_html/
ls -la
sudo chown -R www-data:www-data wp-content/
ls -l
sudo find /var/www/example2.com/public_html/ -type d -exec chmod 755 {}\;
sudo find /var/www/example2.com/public_html/ -type f -exec chmod 644 {}\;
sudo chmod 664 .htaccess wp-config.php
sudo nano wp-config.php
paste above the line : /*that's all, stop editing!
/** Allow Direct Updating Without FTP */
define('FS_METHOD', 'direct');
/** Disable Editing of Themes and Plugins Using the Built In Editor */
define('DISALLOW_FILE_EDIT', 'true');
/** Allow Automatic Core Updates */
define('WP_AUTO_UPDATE_CORE', 'true');
exit and save.
sudo nano .htaccess
under # END WordPress
paste :
#Deny Access to WP-config and xmlrpc
<FilesMatch "(wp-config|xmlrpc)\.php$">
Deny from all
</FilesMatch>
#Disable Hotlinking of Images - change site.com
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?site.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?google.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ – [NC,F,L]
# BEGIN block author scans
RewriteEngine On
RewriteBase /
RewriteCond %{QUERY_STRING} (author=\d+) [NC]
RewriteRule .* - [F]
#DENY ACCESS TO FILES
<FilesMatch "\.(?:txt|htm|html)$">
Order allow,deny
Deny from all
</FilesMatch>
# General WordPress Protection
RewriteRule ^wp-admin/install\.php$ - [F]
RewriteRule ^wp-admin/includes/ - [F]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F]
RewriteRule ^wp-includes/theme-compat/ - [F]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule (^|.*/)\.(git|svn)/.* - [F]
# Disable PHP in Uploads
RewriteRule ^wp\-content/uploads/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Disable PHP in Plugins - check for issues with installed plugins
# RewriteRule ^wp\-content/plugins/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Disable PHP in Themes - check for issues with selected theme
# RewriteRule ^wp\-content/themes/.*\.(?:php[1-7]?|pht|phtml?|phps)\.?$ - [NC,F]
# Filter Request Methods
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
RewriteRule ^.* - [F]
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK) [NC]
RewriteRule ^.* - [F]
# Filter Suspicious Query Strings in the URL
RewriteCond %{QUERY_STRING} \.\.\/ [OR]
RewriteCond %{QUERY_STRING} \.(bash|git|hg|log|svn|swp|cvs) [NC,OR]
RewriteCond %{QUERY_STRING} etc/passwd [NC,OR]
RewriteCond %{QUERY_STRING} boot\.ini [NC,OR]
RewriteCond %{QUERY_STRING} ftp: [NC,OR]
RewriteCond %{QUERY_STRING} https?: [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)script(>|%3E) [NC,OR]
RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|%3D) [NC,OR]
RewriteCond %{QUERY_STRING} base64_decode\( [NC,OR]
RewriteCond %{QUERY_STRING} %24&x [NC,OR]
RewriteCond %{QUERY_STRING} 127\.0 [NC,OR]
RewriteCond %{QUERY_STRING} (^|\W)(globals|encode|localhost|loopback)($|\W) [NC,OR]
RewriteCond %{QUERY_STRING} (^|\W)(concat|insert|union|declare)($|\W) [NC,OR]
RewriteCond %{QUERY_STRING} %[01][0-9A-F] [NC]
RewriteCond %{QUERY_STRING} !^loggedout=true
RewriteCond %{QUERY_STRING} !^action=jetpack-sso
RewriteCond %{QUERY_STRING} !^action=rp
RewriteCond %{HTTP_COOKIE} !wordpress_logged_in_
RewriteCond %{HTTP_REFERER} !^http://maps\.googleapis\.com
RewriteRule ^.* - [F]
# Filter Non-English Characters
RewriteCond %{QUERY_STRING} %[A-F][0-9A-F] [NC]
RewriteRule ^.* - [F]
************************************
*and change site.com to your domain*
************************************
gen SSL cert :
cd
sudo certbot --apache -d example2.com -d
www.example2.comredirect trafic to https ? 2
cd /etc/apache2/sites_available/
ls -l
sudo nano /etc/apache2/sites-available/example2.com-le-ssl.conf
Add underneath SSL Certificate paths above </VirtualHost>:
Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains;"
ctrl+x and save
sudo apachectl configtest
Syntax OK
sudo systemctl restart apache2
ssllabs.com your site should rank A+
cd /var/www/example2.com/pulic_html/
wp search-replace
http://example2.com https://example2.comclear php opcache
sudo systemctl restart php7.2-fpm
see l34
l37 essential plugins :
plugins->add new-> autoptimize, async
plugins: delete hello dolly, akismet
activate autoptimize, javascript options, check optimize javascript codes, select :
optimize css codes, optimize html code, save changes
pluggind-> installed plugins, activate the above plugins
async settings :
enable javascript : this depends on your site
install plugin : post SMTP, activate plugin.
and discus plugin to manage spam.
l78 filezilla
used to DL or UL files between the server and a local machine
on the extreme left, open site manager
new site, call it vps1, protocol: SFTP, host: server ip
port : leave blank or 22, logon type : key file
user: nonrootuser
key file : browse to : cmder (dir you made when you installer commander), .ssh
set to all files, select ct (the private server key), open
on prompt: yes, provide your private key pass phrase
on save as prompt : ct_fz (filename_fz), save, ok
go back to site manager, select vps1, connect
check always trust this host, type private key pass phrase to unlock, ok
l64 server updates
login to the server
ssh 1st
upon message : n packages can be updated :
***system restart required***
sudo apt-get update && sudo apt-get upgrade
sudo apt-get autoremove
sudo reboot
site updates : because of the permissions we set, updates are not possible from the wordpress
dashboard. when the dashboard notifies of needed updates, instead use the cmd line :
wp core version
wp core update
wp core update-db
sudo systemctl restart php7.2-fpm
wp core version
depending on your WP ver you could end up with "cannot create dir err" on wp core update
the web server is the owner and group owner of the upgrade dir with permission 755
while the user is the other user withour permissions.
so the non root user needs to be the owner, and the webserver the group owner :
cd /var/example2.com/public_html/
cd wp-content/
ls -l
sudo chown -R nonrootusername:www-data upgrade/
cd ..
wp core update
wp core version
cd wp-content/
ls -l
sudo chown -R www-data:www-data upgrade/
ls -l
sudo systemctl restart php7.2-fpm
wpcli updates :
cd
curl -O
https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phargive wpcli executable permissions :
chmod +x wp-cli.phar
sudo mv wp-cli.phar /usr/local/bin/wp