Примитивная и эффективная защита Веб-сервисов

В данной статье я поведаю Вам, как совершенно бесплатно можно обеспечить объективную безопасность Веб-сайта или веб-сервиса.

Давным давно, когда я занимался разработкой сайтов возник вопрос редиректа устаревших ссылок и небольшой настройкой кеширования элементов интернет страницы и обеспечения защиты от xss атак.

Оставалась одна сложность в реализации требуемого — это виртуальный хостинг, параметрами которого, провайдер услуг (хостинг провайдер) не даст управлять на уровне подсистем, для полного контроля естественно требуется VPS хостинг или личный сервер с белым ip-адресом.

Но был найден выход — это файл .htaccess — конфигурационный файл, позволяющий управлять работой веб-сервера и настройками сайта с помощью различ

ных параметров (директив) без изменения основного конфигурационного файла веб-сервера. Очень давно на Apache использовался для небольших настроек тонкого клиента для 1С.

В итоге, после долгих проб и ошибок, невероятно длительного поиска в просторах могучего Интернета были собраны лучшие методики использования директив данного файла, которые позволили не только обеспечить защиту, но и настроить кеширование и редиректы и очень многое другое.

Бонусом многолетнего сбора лучших методик и собственных замечаний будет полная универсальность данного файла как на Apache так и на Nginx. Вам даже не придется ничего специально адаптировать, почи все строки имею коменты. (если у Вас сервис на HTTPS раскоментируйте строки редиректа с http на https)

Создайте файл .htaccess скопируйте в него данный текст, сохраните и положите в корень папки с сайтом:

.htasccess

//Close User Agents
SetEnvIf user-agent "Indy Library" stayout=1
SetEnvIf user-agent "libwww-perl" stayout=1
SetEnvIf user-agent "Wget" stayout=1
SetEnvIf user-agent "wpscan" stayout=1
deny from env=stayout

//SetHandler server-status //Информация о Сервере аля PHPInfo
//SetHandler server-info
php_flag expose_php Off
php_value expose_php Off
// Диапозон ITrack.ru
deny from 144.76.
// Диапозон 2ip.ru
deny from 188.40.74.
deny from 178.63.151.
// Диапазон buildwith.com
deny from 198.22.98.0/23
deny from 198.22.100.0/22
deny from 198.22.104.0/21
deny from 198.22.112.0/20
deny from 198.22.128.0/17
deny from 198.23.0.0/16
deny from 198.24.0.0/13
deny from 198.32.0.0/14
deny from 198.36.0.0/19
DirectorySlash off
// Extra Security Headers
<ifModule ModSecurity.c>
SecServerSignature ''
</ifModule>
<IfModule mod_headers.c>
Header set header_name "SECURIXY"
//Header unset X-Powered-By
Header set X-Powered-By "tm by ©clevergod"
Header set Server "Xyuerver"
Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" env=HTTPS
Header set X-Permitted-Cross-Domain-Policies "none"
Header append Vary User-Agent
Header set Connection keep-alive
// Don't allow any pages to be framed - Defends against CSRF
Header set X-Frame-Options DENY
// Turn on IE8-IE9 XSS prevention tools
//Header set X-XSS-Protection "1; mode=block"
// Only allow JavaScript from the same domain to be run // Don't allow inline JavaScript to run.
Header set X-Content-Security-Policy "allow 'self';"
// prevent mime based attacks
Header set X-Frame-Options SAMEORIGIN
Header set X-Content-Type-Options nosniff
</IfModule>
// Увеличиваем безопасность cookie, включив режим HTTP Only обратите внимание на версию PHP
//<IfModule php5_module>
// php_flag session.cookie_httponly on
// php_value session.cookie_httponly true
//</IfModule>
Header always edit Set-Cookie (.*) "$1; HttpOnly; Secure"
//Strip off double Secure or HttpOnly settings as if App and Apache sets above you can sometimes get both
Header always edit Set-Cookie (?i)^(.*);\s?Secure;?\s?(.*)?;?\s?Secure;?\s?(.*)$ "$1; $2; $3; Secure"
Header always edit Set-Cookie (?i)^(.*);\s?HttpOnly;?\s?(.*)?;?\s?HttpOnly;?\s?(.*)$ "$1; $2; $3; HttpOnly"
//Strip off double ;; settings
Header always edit* Set-Cookie (;\s?){2,} "; "

//Данный код позволяет защитить сайт от scripts enjection
//Блокируем все ссылки, содержащие <script>
RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC,OR]
//Блокируем все скрипты, которые пытаются изменить переменные PHP Globals:
RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR]
//Блокируем все скрипты, которые пытаются изменить переменную _REQUEST:
RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})
//Перенаправляем все подобные на страницу с ошибкой 403 — запрещено
RewriteRule ^(.*)$ index.php [F,L]

// Защита Slow HTTP POST vulnerability
<IfModule mod_reqtimeout.c>
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
<IfModule reqtimeout_module>
// Usually, a server should have both header and body timeouts configured. If a common configuration is used for http and https virtual hosts, the timeouts should not be set too low:
RequestReadTimeout header=20-40,MinRate=500 body=20,MinRate=500
</IfModule>
<IfModule mod_qos.c>
// handle connections from up to 100000 different IPs
QS_ClientEntries 100000
// allow only 50 connections per IP
QS_SrvMaxConnPerIP 50
// limit maximum number of active TCP connections limited to 256
MaxClients 256
// disables keep-alive when 180 (70%) TCP connections are occupied
QS_SrvMaxConnClose 180
// minimum request/response speed (deny slow clients blocking the server, keeping connections open without requesting anything
QS_SrvMinDataRate 150 1200
</IfModule>

// Доступ к чтению каталогов
Options All -ExecCGI -Indexes -Includes +FollowSymLinks
// Опция "-Indexes" заблокирует возможность просматривать директории посетителями
// Нельзя позволять случайным пользователям просматривать служебные директории вашей CMS.
<IfModule mod_autoindex.c>
Options -Indexes
</IfModule>
Order Allow,Deny
Allow from All

// Доступ к чтению каталогов
<Files readme.html>
Order deny,allow
Deny from all
</Files>
<Files wp-config-sample.php>
Order deny,allow
Deny from all
</Files>
<Files license.txt>
Order deny,allow
Deny from all
</Files>
<FilesMatch "\.htaccess.*|\.htpasswd.*|xmlrpc\.php|wp\-cron\.php|wp_cron\.php">
order allow,deny
deny from all
</FilesMatch>

// Доступ к файлам каталогов, разрешаем Роботс
<FilesMatch "\.(tpl|ini|log|txt)">
Order deny,allow
Deny from all
</FilesMatch>
<Files robots.txt>
Allow from all
</Files>
// Запретить читать log
<Files error.log>
Order allow,deny
Deny from all
Satisfy All
</Files>

<files admin="">
order allow,deny
deny from all
</files>

<files .htaccess="">
order allow,deny
deny from all
</files>

// SEO URL Настройка
// Если не стандартная установка сайта в корне, то заменить RewriteBase / на что-то свое RewriteBase /shop/
<IfModule mod_rewrite.c>
RewriteEngine On
// Поблочим нерадивых сразу
RewriteCond %{HTTP_REFERER} webtotem.kz [NC,OR]
RewriteCond %{HTTP_REFERER} cybersec.kz [NC,OR]

//Редирект на HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
//Old Redirect// RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
Header always edit Set-Cookie "(?i)^((?:(?!;\s?HttpOnly).)+)$" "$1; HttpOnly"
Header always edit Set-Cookie "(?i)^((?:(?!;\s?secure).)+)$" "$1; secure"

RewriteBase /

RewriteRule ^yandexbuy/([^?]*)$ index.php?route=yandexbuy/$1 [L,QSA]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteRule ^system/download/(.*) index.php?route=error/not_found [L]

// Основной редирект
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
// NOT MOVE - НЕ ТРОГАТЬ И НЕ ПЕРЕМЕЩАТЬ ЭТО ПРАВИЛО
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

//Редирект 301
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\ HTTPs/
RewriteRule ^index\.html$ / [R=301,L]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTPs/
RewriteRule ^index\.php$ / [R=301,L]
RewriteCond %{QUERY_STRING} ^route=common/home$
RewriteCond %{REQUEST_METHOD} !^POST$
RewriteRule ^index\.php$ http://%{HTTP_HOST}? [R=301,L]
</IfModule>

////// Закоментить если web-сервер не принимает, как правило при nginx
//// Главный индекс файл
//DirectoryIndex index.php
//
//// Часовой пояс и кодировка
//<IfModule mod_setenvif.c>
// SetEnv TZ Asia/Almaty
//</IfModule>
//ServerSignature Off
////AddDefaultCharset UTF-8

// Принудительное указание типов файлов
AddType application/x-javascript .js
AddType text/css .css
AddType text/xml .xml
AddType application/octet-stream .doc .mov .avi .pdf .xls
// ForceType application/x-httpd-php

// Архивирование архивов
AddType text/css .css .cssgz
AddType text/javascript .js .jsgz
AddEncoding x-gzip .cssgz .jsgz
// Архивирование использованием mod_gzip.c
<ifModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/plain text/xml application/xml application/xhtml+xml text/css text/javascript application/javascript application/x-javascript
</ifModule>
<IfModule mod_gzip.c>
mod_gzip_on Yes
mod_gzip_dechunk Yes
mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$
mod_gzip_item_include mime ^text\.*
mod_gzip_item_include mime ^application/x-javascript.*
mod_gzip_item_include mime ^application/x-font-woff.*
mod_gzip_item_exclude mime ^image\.*
mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
SetOutputFilter DEFLATE
</IfModule>

// КЕША
//php_value session.cookie_domain .clevergod.net
//php_value max_input_vars 4000
// Управлять параметрами php.ini
<ifModule mod_php.c>
php_value upload_max_filesize 32M
php_value post_max_size 10M
php_value default_charset utf-8
php_value max_execution_time 200
</ifModule>

//Шрифты
// Add correct content-type for fonts
AddType application/vnd.ms-fontobject .eot
AddType application/x-font-ttf .ttf
AddType application/x-font-opentype .otf
AddType application/x-font-woff .woff
AddType image/svg+xml .svg

// Compress compressible fonts
AddOutputFilterByType DEFLATE application/x-font-ttf application/x-font-opentype image/svg+xml

// Cache Fonts
ExpiresByType application/vnd.ms-fontobject "access plus 2592000 seconds"
ExpiresByType application/x-font-ttf "access plus 2592000 seconds"
ExpiresByType application/x-font-opentype "access plus 2592000 seconds"
ExpiresByType application/x-font-woff "access plus 2592000 seconds"
ExpiresByType image/svg+xml "access plus 2592000 seconds"

// Кеширование Страницы
<ifModule mod_headers.c>
// Turn on Expires and set default to 0
ExpiresActive On
ExpiresDefault A0

// Set up caching on media files for 5 weeks
<FilesMatch "\.(flv|ico|pdf|avi|mov|ppt|doc|mp3|wmv|wav)$">
ExpiresDefault A3024000
Header append Cache-Control "public"
</FilesMatch>

// Set up caching on media files for 5 weeks
<FilesMatch "\.(gif|jpg|jpeg|png|swf)$">
ExpiresDefault A3024000
Header append Cache-Control "public"
</FilesMatch>

// Set up 1 day caching on commonly updated files
<FilesMatch "\.(xml|txt|html|js|css)$">
ExpiresDefault A86400
Header append Cache-Control "proxy-revalidate"
</FilesMatch>

// Force no caching for dynamic files
<FilesMatch "\.(php|cgi|pl|htm)$">
ExpiresActive Off
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
</IfModule>

// Кеширование Браузером
FileETag MTime Size
Header append Cache-Control "public"
<ifmodule mod_expires.c>
<filesmatch ".(jpg|gif|png|css|js)$">
ExpiresActive on
ExpiresDefault "access plus 1 year"

ExpiresDefault A0
//по умолчанию кеш в 5 секунд
ExpiresDefault "access plus 5 seconds"
//кэшировать флэш и изображения на месяц
ExpiresByType image/x-icon "access plus 2592000 seconds"
ExpiresByType image/jpeg "access plus 2592000 seconds"
ExpiresByType image/jpg "access plus 2592000 seconds"
ExpiresByType image/png "access plus 2592000 seconds"
ExpiresByType image/gif "access plus 2592000 seconds"
ExpiresByType application/x-shockwave-flash "access plus 2592000 seconds"
//кэшировать css, javascript и текстовые файлы на одну неделю
ExpiresByType text/css "access plus 604800 seconds"
ExpiresByType text/javascript "access plus 604800 seconds"
ExpiresByType application/javascript "access plus 604800 seconds"
ExpiresByType application/x-javascript "access plus 604800 seconds"
//кэшировать html и htm файлы на один день
ExpiresByType text/html "access plus 43200 seconds"
//кэшировать xml файлы на десять минут
ExpiresByType application/xhtml+xml "access plus 600 seconds"
</filesmatch>
</ifmodule>

// Совместимость со старыми браузерами
<IfModule mod_setenvif.c>
BrowserMatch "MSIE" force-no-vary
BrowserMatch "Mozilla/4.[0-9]{2}" force-no-vary
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
</IfModule>

// Отключите отправку cookies файлам
SetEnvIf Mime text/javascript unset-cookie
SetEnvIf Mime text/x-javascript unset-cookie
SetEnvIf Mime text/css unset-cookie
SetEnvIf Mime image/.* unset-cookie

//// Bad Rquest
//ErrorDocument 400 /400.html
//// Authorization Required
ErrorDocument 401 https://clevergod.net/img/htaccess-logo2.png
//// Forbidden
ErrorDocument 403 https://clevergod.net/img/htaccess-logo2.png
//// Not found
ErrorDocument 404 https://clevergod.net/404.shtml
//// Method Not Allowed
ErrorDocument 405 https://clevergod.net/img/htaccess-logo2.png
//// Request Timed Out
//ErrorDocument 408 /408.html
//// Request URI Too Long
//ErrorDocument 414 /414.html
//// Internal Server Error
//ErrorDocument 500 /500.html
//// Not Implemented
//ErrorDocument 501 /501.html
//// Bad Gateway
//ErrorDocument 502 http://clevergod.net/img/htaccess-logo2.png
//// Service Unavailable
//ErrorDocument 503 /503.html
//// Gateway Timeout
//ErrorDocument 504 /504.html
//Redirect 301 /index.html /index.php
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 6G FIREWALL/BLACKLIST
// @ https://perishablepress.com/6g/

// 6G:[QUERY STRINGS]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} (eval\() [NC,OR]
RewriteCond %{QUERY_STRING} (127\.0\.0\.1) [NC,OR]
RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR]
RewriteCond %{QUERY_STRING} (javascript:)(.*)(;) [NC,OR]
RewriteCond %{QUERY_STRING} (base64_encode)(.*)(\() [NC,OR]
RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)(.*)script(.*)(>|%3) [NC,OR]
RewriteCond %{QUERY_STRING} (\\|\.\.\.|\.\./|~|`|<|>|\|) [NC,OR]
RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR]
RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumb)?)\.php [NC,OR]
RewriteCond %{QUERY_STRING} (\'|\")(.*)(drop|insert|md5|select|union) [NC]
RewriteRule .* - [F]
</IfModule>

// 6G:[REQUEST METHOD]
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} ^(connect|debug|move|put|trace|track) [NC]
RewriteRule .* - [F]
</IfModule>

// 6G:[REFERRERS]
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_REFERER} ([a-z0-9]{2000,}) [NC,OR]
RewriteCond %{HTTP_REFERER} (semalt.com|todaperfeita) [NC]
RewriteRule .* - [F]
</IfModule>

// 6G:[REQUEST STRINGS]
<IfModule mod_alias.c>
RedirectMatch 403 (?i)([a-z0-9]{2000,})
RedirectMatch 403 (?i)(https?|ftp|php):/
RedirectMatch 403 (?i)(base64_encode)(.*)(\()
RedirectMatch 403 (?i)(=\\\'|=\\%27|/\\\'/?)\.
RedirectMatch 403 (?i)/(\$(\&)?|\*|\"|\.|,|&|&amp;?)/?$
RedirectMatch 403 (?i)(\{0\}|\(/\(|\.\.\.|\+\+\+|\\\"\\\")
RedirectMatch 403 (?i)(~|`|<|>|:|;|,|%|\\|\s|\{|\}|\[|\]|\|)
RedirectMatch 403 (?i)/(=|\$&|_mm|cgi-|etc/passwd|muieblack)
RedirectMatch 403 (?i)(&pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)
RedirectMatch 403 (?i)\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rdf)$
RedirectMatch 403 (?i)/(^$|(wp-)?config|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php
</IfModule>

// 6G:[USER AGENTS]
<IfModule mod_setenvif.c>
SetEnvIfNoCase User-Agent ([a-z0-9]{2000,}) bad_bot
SetEnvIfNoCase User-Agent (archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune) bad_bot

// Apache < 2.3
<IfModule !mod_authz_core.c>
Order Allow,Deny
Allow from all
Deny from env=bad_bot
</IfModule>

// Apache >= 2.3
<IfModule mod_authz_core.c>
<RequireAll>
Require all Granted
Require not env bad_bot
</RequireAll>
</IfModule>
</IfModule>

// 6G:[BAD IPS]
<Limit GET HEAD OPTIONS POST PUT>
Order Allow,Deny
Allow from All
// uncomment/edit/repeat next line to block IPs
// Deny from 123.456.789
</Limit>

AddOutputFilterByType DEFLATE text/html text/plain text/xml text/css text/javascript application/x-javascript
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
<FilesMatch "\.(js|css|jpg|png|jpeg|gif|xml|json|txt|pdf|mov|avi|otf|woff|ico|swf)$">
RequestHeader unset Cookie
Header unset Cookie
Header unset Set-Cookie
ErrorDocument 404 'Not Found'
</FilesMatch>


Хотел посоветовать форум настоящих системных администраторв  https://sys-adm.in/