├── .gitignore ├── .htaccess ├── README.md ├── nginx.conf └── web.config /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea/ -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | ## The Kyrion .htaccess 3 | ## 4 | ## PLEASE READ THE README.md FILE BEFORE TRYING TO USE THIS ON YOUR SITE. 5 | ############################################################################### 6 | 7 | ########## Begin - RewriteEngine enabled 8 | RewriteEngine On 9 | ########## End - RewriteEngine enabled 10 | 11 | ########## Begin - RewriteBase 12 | ## 13 | ## Uncomment the following line if your URLs are not directly related to 14 | ## physical paths. 15 | ## 16 | ## If Joomla is installed in a subdirectory, uncomment and replace with 17 | ## the full path to the subdirectory e.g. /foo/bar if your site's URL is 18 | ## http://www.example.com/foo/bar 19 | ## 20 | # RewriteBase / 21 | ########## End - RewriteBase 22 | 23 | ##### HTTP to HTTPS redirection 24 | ## 25 | ## If your site is using HTTPS uncomment the following block to 26 | ## automatically redirect all plian old HTTP requests to HTTPS. 27 | ## 28 | # RewriteCond %{HTTPS} !=on [OR] 29 | # RewriteCond %{HTTP:X-Forwarded-Proto} =http 30 | # RewriteRule .* https://www.example.com%{REQUEST_URI} [L,R=301] 31 | ## 32 | 33 | ########## Begin - File execution order, by Komra.de 34 | DirectoryIndex index.php index.html 35 | ########## End - File execution order 36 | 37 | ########## Begin - No directory listings 38 | IndexIgnore * 39 | Options -Indexes 40 | ########## End - No directory listings 41 | 42 | ########## Begin - ETag Optimization 43 | ## This rule will create an ETag for files based only on the modification 44 | ## timestamp and their size. This works wonders if you are using rsync'ed 45 | ## servers, where the inode number of identical files differs. 46 | ## Note: It may cause problems on your server and you may need to remove it 47 | FileETag MTime Size 48 | ########## End - ETag Optimization 49 | 50 | ########## Begin - Optimal default expiration time 51 | ## Note: this might cause problems and you might have to comment it out by 52 | ## placing a hash in front of this section's lines 53 | ## Note: Some people prefer using "now plus 1 month" instead of "now plus 1 year". 54 | ## Suit to taste. 55 | 56 | # Enable expiration control 57 | ExpiresActive On 58 | 59 | # CSS and JS expiration: 1 week after request 60 | ExpiresByType text/css "now plus 1 week" 61 | ExpiresByType application/javascript "now plus 1 week" 62 | ExpiresByType application/x-javascript "now plus 1 week" 63 | 64 | # Image files expiration: 1 month after request 65 | ExpiresByType image/bmp "now plus 1 month" 66 | ExpiresByType image/gif "now plus 1 month" 67 | ExpiresByType image/jpeg "now plus 1 month" 68 | ExpiresByType image/jp2 "now plus 1 month" 69 | ExpiresByType image/pipeg "now plus 1 month" 70 | ExpiresByType image/png "now plus 1 month" 71 | ExpiresByType image/svg+xml "now plus 1 month" 72 | ExpiresByType image/tiff "now plus 1 month" 73 | ExpiresByType image/vnd.microsoft.icon "now plus 1 month" 74 | ExpiresByType image/x-icon "now plus 1 month" 75 | ExpiresByType image/ico "now plus 1 month" 76 | ExpiresByType image/icon "now plus 1 month" 77 | ExpiresByType text/ico "now plus 1 month" 78 | ExpiresByType application/ico "now plus 1 month" 79 | ExpiresByType image/vnd.wap.wbmp "now plus 1 month" 80 | ExpiresByType application/vnd.wap.wbxml "now plus 1 month" 81 | ExpiresByType application/smil "now plus 1 month" 82 | 83 | # Font files expiration: 1 week after request 84 | ExpiresByType application/vnd.ms-fontobject "now plus 1 week" 85 | ExpiresByType application/x-font-ttf "now plus 1 week" 86 | ExpiresByType application/x-font-opentype "now plus 1 week" 87 | ExpiresByType application/x-font-woff "now plus 1 week" 88 | ExpiresByType font/woff2 "now plus 1 week" 89 | ExpiresByType image/svg+xml "now plus 1 week" 90 | 91 | # Audio files expiration: 1 month after request 92 | ExpiresByType audio/ogg "now plus 1 month" 93 | ExpiresByType application/ogg "now plus 1 month" 94 | ExpiresByType audio/basic "now plus 1 month" 95 | ExpiresByType audio/mid "now plus 1 month" 96 | ExpiresByType audio/midi "now plus 1 month" 97 | ExpiresByType audio/mpeg "now plus 1 month" 98 | ExpiresByType audio/mp3 "now plus 1 month" 99 | ExpiresByType audio/x-aiff "now plus 1 month" 100 | ExpiresByType audio/x-mpegurl "now plus 1 month" 101 | ExpiresByType audio/x-pn-realaudio "now plus 1 month" 102 | ExpiresByType audio/x-wav "now plus 1 month" 103 | 104 | # Movie files expiration: 1 month after request 105 | ExpiresByType application/x-shockwave-flash "now plus 1 month" 106 | ExpiresByType x-world/x-vrml "now plus 1 month" 107 | ExpiresByType video/x-msvideo "now plus 1 month" 108 | ExpiresByType video/mpeg "now plus 1 month" 109 | ExpiresByType video/mp4 "now plus 1 month" 110 | ExpiresByType video/quicktime "now plus 1 month" 111 | ExpiresByType video/x-la-asf "now plus 1 month" 112 | ExpiresByType video/x-ms-asf "now plus 1 month" 113 | 114 | ########## End - Optimal expiration time 115 | 116 | ########## Begin - Common hacking tools and bandwidth hoggers block 117 | ## 118 | ## Denies access to specific user agents. Any request with a user agent that 119 | ## partially matches an entry in this list will be blocked. 120 | ## 121 | SetEnvIf user-agent "WebBandit" stayout=1 122 | SetEnvIf user-agent "webbandit" stayout=1 123 | SetEnvIf user-agent "Acunetix" stayout=1 124 | SetEnvIf user-agent "binlar" stayout=1 125 | SetEnvIf user-agent "BlackWidow" stayout=1 126 | SetEnvIf user-agent "Bolt 0" stayout=1 127 | SetEnvIf user-agent "Bot mailto:craftbot@yahoo.com" stayout=1 128 | SetEnvIf user-agent "BOT for JCE" stayout=1 129 | SetEnvIf user-agent "casper" stayout=1 130 | SetEnvIf user-agent "checkprivacy" stayout=1 131 | SetEnvIf user-agent "ChinaClaw" stayout=1 132 | SetEnvIf user-agent "clshttp" stayout=1 133 | SetEnvIf user-agent "cmsworldmap" stayout=1 134 | SetEnvIf user-agent "comodo" stayout=1 135 | SetEnvIf user-agent "Custo" stayout=1 136 | SetEnvIf user-agent "Default Browser 0" stayout=1 137 | SetEnvIf user-agent "diavol" stayout=1 138 | SetEnvIf user-agent "DIIbot" stayout=1 139 | SetEnvIf user-agent "DISCo" stayout=1 140 | SetEnvIf user-agent "dotbot" stayout=1 141 | SetEnvIf user-agent "Download Demon" stayout=1 142 | SetEnvIf user-agent "eCatch" stayout=1 143 | SetEnvIf user-agent "EirGrabber" stayout=1 144 | SetEnvIf user-agent "EmailCollector" stayout=1 145 | SetEnvIf user-agent "EmailSiphon" stayout=1 146 | SetEnvIf user-agent "EmailWolf" stayout=1 147 | SetEnvIf user-agent "Express WebPictures" stayout=1 148 | SetEnvIf user-agent "extract" stayout=1 149 | SetEnvIf user-agent "ExtractorPro" stayout=1 150 | SetEnvIf user-agent "EyeNetIE" stayout=1 151 | SetEnvIf user-agent "feedfinder" stayout=1 152 | SetEnvIf user-agent "FHscan" stayout=1 153 | SetEnvIf user-agent "FlashGet" stayout=1 154 | SetEnvIf user-agent "flicky" stayout=1 155 | SetEnvIf user-agent "GetRight" stayout=1 156 | SetEnvIf user-agent "GetWeb!" stayout=1 157 | SetEnvIf user-agent "Go-Ahead-Got-It" stayout=1 158 | SetEnvIf user-agent "Go!Zilla" stayout=1 159 | SetEnvIf user-agent "grab" stayout=1 160 | SetEnvIf user-agent "GrabNet" stayout=1 161 | SetEnvIf user-agent "Grafula" stayout=1 162 | SetEnvIf user-agent "harvest" stayout=1 163 | SetEnvIf user-agent "HMView" stayout=1 164 | SetEnvIf user-agent "ia_archiver" stayout=1 165 | SetEnvIf user-agent "Image Stripper" stayout=1 166 | SetEnvIf user-agent "Image Sucker" stayout=1 167 | SetEnvIf user-agent "InterGET" stayout=1 168 | SetEnvIf user-agent "Internet Ninja" stayout=1 169 | SetEnvIf user-agent "InternetSeer.com" stayout=1 170 | SetEnvIf user-agent "jakarta" stayout=1 171 | SetEnvIf user-agent "Java" stayout=1 172 | SetEnvIf user-agent "JetCar" stayout=1 173 | SetEnvIf user-agent "JOC Web Spider" stayout=1 174 | SetEnvIf user-agent "kmccrew" stayout=1 175 | SetEnvIf user-agent "larbin" stayout=1 176 | SetEnvIf user-agent "LeechFTP" stayout=1 177 | SetEnvIf user-agent "libwww" stayout=1 178 | SetEnvIf user-agent "Mass Downloader" stayout=1 179 | SetEnvIf user-agent "Maxthon$" stayout=1 180 | SetEnvIf user-agent "microsoft.url" stayout=1 181 | SetEnvIf user-agent "MIDown tool" stayout=1 182 | SetEnvIf user-agent "miner" stayout=1 183 | SetEnvIf user-agent "Mister PiX" stayout=1 184 | SetEnvIf user-agent "NEWT" stayout=1 185 | SetEnvIf user-agent "MSFrontPage" stayout=1 186 | SetEnvIf user-agent "Navroad" stayout=1 187 | SetEnvIf user-agent "NearSite" stayout=1 188 | SetEnvIf user-agent "Net Vampire" stayout=1 189 | SetEnvIf user-agent "NetAnts" stayout=1 190 | SetEnvIf user-agent "NetSpider" stayout=1 191 | SetEnvIf user-agent "NetZIP" stayout=1 192 | SetEnvIf user-agent "nutch" stayout=1 193 | SetEnvIf user-agent "Octopus" stayout=1 194 | SetEnvIf user-agent "Offline Explorer" stayout=1 195 | SetEnvIf user-agent "Offline Navigator" stayout=1 196 | SetEnvIf user-agent "PageGrabber" stayout=1 197 | SetEnvIf user-agent "Papa Foto" stayout=1 198 | SetEnvIf user-agent "pavuk" stayout=1 199 | SetEnvIf user-agent "pcBrowser" stayout=1 200 | SetEnvIf user-agent "PeoplePal" stayout=1 201 | SetEnvIf user-agent "planetwork" stayout=1 202 | SetEnvIf user-agent "psbot" stayout=1 203 | SetEnvIf user-agent "purebot" stayout=1 204 | SetEnvIf user-agent "RealDownload" stayout=1 205 | SetEnvIf user-agent "ReGet" stayout=1 206 | SetEnvIf user-agent "Rippers 0" stayout=1 207 | SetEnvIf user-agent "SeaMonkey$" stayout=1 208 | SetEnvIf user-agent "sitecheck.internetseer.com" stayout=1 209 | SetEnvIf user-agent "SiteSnagger" stayout=1 210 | SetEnvIf user-agent "skygrid" stayout=1 211 | SetEnvIf user-agent "SmartDownload" stayout=1 212 | SetEnvIf user-agent "sucker" stayout=1 213 | SetEnvIf user-agent "SuperBot" stayout=1 214 | SetEnvIf user-agent "SuperHTTP" stayout=1 215 | SetEnvIf user-agent "Surfbot" stayout=1 216 | SetEnvIf user-agent "tAkeOut" stayout=1 217 | SetEnvIf user-agent "Teleport Pro" stayout=1 218 | SetEnvIf user-agent "Toata dragostea mea pentru diavola" stayout=1 219 | SetEnvIf user-agent "turnit" stayout=1 220 | SetEnvIf user-agent "vikspider" stayout=1 221 | SetEnvIf user-agent "VoidEYE" stayout=1 222 | SetEnvIf user-agent "Web Image Collector" stayout=1 223 | SetEnvIf user-agent "Web Sucker" stayout=1 224 | SetEnvIf user-agent "WebAuto" stayout=1 225 | SetEnvIf user-agent "WebCopier" stayout=1 226 | SetEnvIf user-agent "WebFetch" stayout=1 227 | SetEnvIf user-agent "WebGo IS" stayout=1 228 | SetEnvIf user-agent "WebLeacher" stayout=1 229 | SetEnvIf user-agent "WebReaper" stayout=1 230 | SetEnvIf user-agent "WebSauger" stayout=1 231 | SetEnvIf user-agent "Website eXtractor" stayout=1 232 | SetEnvIf user-agent "Website Quester" stayout=1 233 | SetEnvIf user-agent "WebStripper" stayout=1 234 | SetEnvIf user-agent "WebWhacker" stayout=1 235 | SetEnvIf user-agent "WebZIP" stayout=1 236 | SetEnvIf user-agent "Widow" stayout=1 237 | SetEnvIf user-agent "WWW-Mechanize" stayout=1 238 | SetEnvIf user-agent "WWWOFFLE" stayout=1 239 | SetEnvIf user-agent "Xaldon WebSpider" stayout=1 240 | SetEnvIf user-agent "Yandex" stayout=1 241 | SetEnvIf user-agent "Zeus" stayout=1 242 | SetEnvIf user-agent "zmeu" stayout=1 243 | SetEnvIf user-agent "CazoodleBot" stayout=1 244 | SetEnvIf user-agent "discobot" stayout=1 245 | SetEnvIf user-agent "ecxi" stayout=1 246 | SetEnvIf user-agent "GT::WWW" stayout=1 247 | SetEnvIf user-agent "heritrix" stayout=1 248 | SetEnvIf user-agent "HTTP::Lite" stayout=1 249 | SetEnvIf user-agent "HTTrack" stayout=1 250 | SetEnvIf user-agent "ia_archiver" stayout=1 251 | SetEnvIf user-agent "id-search" stayout=1 252 | SetEnvIf user-agent "id-search.org" stayout=1 253 | SetEnvIf user-agent "IDBot" stayout=1 254 | SetEnvIf user-agent "Indy Library" stayout=1 255 | SetEnvIf user-agent "IRLbot" stayout=1 256 | SetEnvIf user-agent "ISC Systems iRc Search 2.1" stayout=1 257 | SetEnvIf user-agent "LinksManager.com_bot" stayout=1 258 | SetEnvIf user-agent "linkwalker" stayout=1 259 | SetEnvIf user-agent "lwp-trivial" stayout=1 260 | SetEnvIf user-agent "MFC_Tear_Sample" stayout=1 261 | SetEnvIf user-agent "Microsoft URL Control" stayout=1 262 | SetEnvIf user-agent "Missigua Locator" stayout=1 263 | SetEnvIf user-agent "panscient.com" stayout=1 264 | SetEnvIf user-agent "PECL::HTTP" stayout=1 265 | SetEnvIf user-agent "PHPCrawl" stayout=1 266 | SetEnvIf user-agent "PleaseCrawl" stayout=1 267 | SetEnvIf user-agent "SBIder" stayout=1 268 | SetEnvIf user-agent "Snoopy" stayout=1 269 | SetEnvIf user-agent "Steeler" stayout=1 270 | SetEnvIf user-agent "URI::Fetch" stayout=1 271 | SetEnvIf user-agent "urllib" stayout=1 272 | SetEnvIf user-agent "Web Sucker" stayout=1 273 | SetEnvIf user-agent "webalta" stayout=1 274 | SetEnvIf user-agent "WebCollage" stayout=1 275 | SetEnvIf user-agent "Wells Search II" stayout=1 276 | SetEnvIf user-agent "WEP Search" stayout=1 277 | SetEnvIf user-agent "zermelo" stayout=1 278 | SetEnvIf user-agent "ZyBorg" stayout=1 279 | SetEnvIf user-agent "Indy Library" stayout=1 280 | SetEnvIf user-agent "libwww-perl" stayout=1 281 | SetEnvIf user-agent "Go!Zilla" stayout=1 282 | SetEnvIf user-agent "TurnitinBot" stayout=1 283 | 284 | 285 | deny from env=stayout 286 | 287 | 288 | 289 | Require all granted 290 | Require not env stayout 291 | 292 | 293 | ########## End - Common hacking tools and bandwidth hoggers block 294 | 295 | ########## Begin - Automatic compression of resources 296 | ## 297 | ## Automatically GZip's static resources of your site, speeding up their 298 | ## delivery over the network. 299 | ## 300 | 301 | AddOutputFilterByType DEFLATE text/plain text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript image/svg+xml 302 | 303 | 304 | 305 | mod_gzip_on Yes 306 | mod_gzip_dechunk Yes 307 | mod_gzip_keep_workfiles No 308 | mod_gzip_can_negotiate Yes 309 | mod_gzip_add_header_count Yes 310 | mod_gzip_send_vary Yes 311 | mod_gzip_min_http 1000 312 | mod_gzip_minimum_file_size 300 313 | mod_gzip_maximum_file_size 512000 314 | mod_gzip_maximum_inmem_size 60000 315 | mod_gzip_handle_methods GET 316 | mod_gzip_item_include file \.(html?|txt|css|js|php|pl|xml|rb|py|svg|scgz)$ 317 | mod_gzip_item_include mime ^text/plain$ 318 | mod_gzip_item_include mime ^text/xml$ 319 | mod_gzip_item_include mime ^text/css$ 320 | mod_gzip_item_include mime ^application/xml$ 321 | mod_gzip_item_include mime ^application/xhtml+xml$ 322 | mod_gzip_item_include mime ^application/rss+xml$ 323 | mod_gzip_item_include mime ^application/javascript$ 324 | mod_gzip_item_include mime ^application/x-javascript$ 325 | mod_gzip_item_include mime ^image/svg+xml$ 326 | mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* 327 | mod_gzip_item_include handler ^cgi-script$ 328 | mod_gzip_item_include handler ^server-status$ 329 | mod_gzip_item_include handler ^server-info$ 330 | mod_gzip_item_include handler ^application/x-httpd-php 331 | mod_gzip_item_exclude mime ^image/.* 332 | 333 | 334 | ## This fixes broken versions of Internet Explorer with mangled Accept headers 335 | 336 | 337 | SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding 338 | RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding 339 | 340 | 341 | ########## End - Automatic compression of resources 342 | 343 | ########## Begin - Redirect index.php to / 344 | ## Note: Change example.com to reflect your own domain 345 | RewriteCond %{THE_REQUEST} !^POST 346 | RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/ 347 | RewriteCond %{SERVER_PORT}>s ^(443>(s)|[0-9]+>s)$ 348 | RewriteRule ^index\.php$ http%2://www.example.com/$1 [R=301,L] 349 | # If the above line throws a 500 error, try this instead: 350 | # RewriteRule ^index\.php$ http%2://www.example.com/$1 [R,L] 351 | ########## End - Redirect index.php to / 352 | 353 | ########## Begin - Redirect non-www to www 354 | RewriteCond %{HTTP_HOST} !^www\. [NC] 355 | RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L] 356 | ## If the above throws an HTTP 500 error, swap [R=301,L] with [R,L] 357 | ########## End - Redirect non-www to www 358 | 359 | ########## Begin - Redirect www to non-www 360 | ## WARNING: Comment out the non-www to www rule if you choose to use this 361 | # RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] 362 | # RewriteRule ^(.*)$ http://%1/$1 [R=301,L] 363 | ## If the above throws an HTTP 500 error, swap [R=301,L] with [R,L] 364 | ########## End - Redirect non-www to www 365 | 366 | ########## Begin - Redirect (www.)olddomain.com to www.example.com 367 | ## Note: olddomain.com is your old domain name, you want to redirect FROM, 368 | ## whereas www.example.com is the new domain name you want to redirect TO. 369 | ## Change those names to reflect your current configuration. Remember, this 370 | ## part of the file is supposed to be placed in www.olddomain.com! 371 | ## Note: Replace [R=301,L] with [R,L] if you get error 500. 372 | ## Uncomment the following lines to enable: 373 | # RewriteCond %{HTTP_HOST} ^(www\.)?olddomain\.com [NC] 374 | # RewriteRule (.*) http://www.example.com/$1 [R=301,L] 375 | ########## End - Redirect olddomain.com to www.example.com 376 | 377 | ########## Begin - Force HTTPS for certain pages 378 | # Force the page foobar.html to run in HTTPS mode, no matter what Joomla! says. 379 | # This is a sample redirection for foobar.html. Do note that you have to change 380 | # www.example.com to reflect your own domain. Remember to escape the dots using 381 | # \. in the left hand side of each rule. You need BOTH LINES PER URL for the rule 382 | # to work. 383 | RewriteCond %{SERVER_PORT} !^443$ 384 | ## Alternatively, comment the above line and uncomment the following line: 385 | # RewriteCond %{HTTPS} ^off$ [NC] 386 | RewriteRule ^foobar\.html$ https://www.example.com/foobar.html [R=301,L] 387 | ## NOTE: If you get an HTTP 500 error, please swap [R=301,L] with [R,L] 388 | # Add more rules below this line 389 | ########## End - Force HTTPS for certain pages 390 | 391 | ##### Rewrite rules to block out some common exploits -- BEGIN 392 | RewriteCond %{QUERY_STRING} proc/self/environ [OR] 393 | RewriteCond %{QUERY_STRING} mosConfig_[a-zA-Z_]{1,21}(=|\%3D) [OR] 394 | RewriteCond %{QUERY_STRING} base64_(en|de)code\(.*\) [OR] 395 | RewriteCond %{QUERY_STRING} (<|%3C).*script.*(>|%3E) [NC,OR] 396 | RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR] 397 | RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) 398 | RewriteRule .* index.php [F] 399 | ##### Rewrite rules to block out some common exploits -- END 400 | 401 | ########## Begin - File injection protection 402 | RewriteCond %{REQUEST_METHOD} GET 403 | RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=http:// [OR] 404 | RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=(\.\.//?)+ [OR] 405 | RewriteCond %{QUERY_STRING} [a-zA-Z0-9_]=/([a-z0-9_.]//?)+ [NC] 406 | RewriteRule .* - [F] 407 | ########## End - File injection protection 408 | 409 | ########## Begin - Advanced server protection rules exceptions #### 410 | ## 411 | ## These are sample exceptions to the Advanced Server Protection 3.0 412 | ## rule set further down this file. 413 | ## 414 | ## Joomla! Update (core feature) 415 | RewriteRule ^administrator\/components\/com_joomlaupdate\/restore\.php$ - [L] 416 | ## Akeeba Backup Professional, integrated restoration 417 | RewriteRule ^administrator\/components\/com_akeeba\/restore\.php$ - [L] 418 | ## Akeeba Backup Core and Professional, restoring your site 419 | RewriteRule ^kickstart\.php$ - [L] 420 | RewriteRule ^installation/ - [L] 421 | # 422 | # >> Add more rules to single PHP files here 423 | # 424 | ## RFC 8615 .well-known, req'ed for Let's Encrypt 425 | RewriteCond %{REQUEST_FILENAME} !(\.php)$ 426 | RewriteCond %{REQUEST_FILENAME} -f 427 | RewriteRule ^\.well\-known/ - [L] 428 | # 429 | # >> Add more rules for allowing full access (except PHP files) on more directories here 430 | # 431 | ## Uncomment to allow full access to the cache directory (strongly not recommended!) 432 | #RewriteRule ^cache/ - [L] 433 | ## Uncomment to allow full access to the tmp directory (strongly not recommended!) 434 | #RewriteRule ^tmp/ - [L] 435 | # 436 | # >> Add more full access rules here 437 | # 438 | ########## End - Advanced server protection rules exceptions #### 439 | 440 | ########## Begin - Advanced server protection 441 | 442 | ## Disable PHP Easter Eggs 443 | RewriteCond %{QUERY_STRING} \=PHP[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12} [NC] 444 | RewriteRule .* - [F] 445 | 446 | #### Back-end protection 447 | ## Allow secret word access 448 | RewriteRule ^administrator/?$ - [L] 449 | ## Allow the index.php file 450 | RewriteRule ^administrator/index\.(php|html?)$ - [L] 451 | ## Allow specific static media types in vetted folders 452 | RewriteRule ^administrator/(components|modules|templates|images|plugins)/.*\.(jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|htm|ttf|woff|woff2|eot|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT|ico|ICO)$ - [L] 453 | ## Disallow everything else 454 | RewriteRule ^administrator/ - [F] 455 | 456 | #### Front-end protection 457 | ## Allow limited access for certain directories with client-accessible content 458 | RewriteRule ^(components|modules|templates|images|plugins|media|libraries|media/jui/fonts)/.*\.(jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|ico|htm|ttf|woff|woff2|eot|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT|ico|ICO)$ - [L] 459 | RewriteRule ^(components|modules|templates|images|plugins|media|libraries|media/jui/fonts)/ - [F] 460 | ## Disallow front-end access for certain Joomla! system directories (unless access to their files is allowed above) 461 | RewriteRule ^includes/js/ - [L] 462 | RewriteRule ^(cache|includes|language|logs|log|tmp)/ - [F] 463 | RewriteRule ^(configuration\.php|CONTRIBUTING\.md|htaccess\.txt|joomla\.xml|LICENSE\.txt|phpunit\.xml|README\.txt|web\.config\.txt) - [F] 464 | ## Explicitly allow access to the site's index.php main entry point file 465 | RewriteRule ^index.php(/.*){0,1}$ - [L] 466 | ## Explicitly allow access to the site's robots.txt file 467 | RewriteRule ^robots.txt$ - [L] 468 | 469 | ## Disallow access to all other PHP files throughout the site, unless they are explicitly allowed 470 | RewriteCond %{REQUEST_FILENAME} (\.php)$ 471 | RewriteCond %{REQUEST_FILENAME} -f 472 | RewriteRule (.*\.php)$ - [F] 473 | 474 | ## Disallow access to htaccess.txt, php.ini, .user.ini and configuration.php-dist 475 | RewriteRule ^(htaccess\.txt|configuration\.php-dist|php\.ini|\.user\.ini)$ - [F] 476 | 477 | # Disallow access to all other front-end folders 478 | RewriteCond %{REQUEST_FILENAME} -d 479 | RewriteCond %{REQUEST_URI} !^/ 480 | RewriteRule .* - [F] 481 | 482 | # Disallow access to all other front-end files 483 | RewriteCond %{REQUEST_FILENAME} -f 484 | RewriteRule !^index.php$ - [F] 485 | ########## End - Advanced server protection 486 | 487 | ## Reduce MIME type security risks 488 | 489 | Header set X-Content-Type-Options "nosniff" 490 | 491 | 492 | ## Remove Apache and PHP version signature 493 | 494 | Header unset X-Powered-By 495 | 496 | 497 | ServerSignature Off 498 | 499 | ## HSTS Header - See http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security 500 | ## 501 | ## Only use if you are using HTTPS for the entire site 502 | ## 503 | # 504 | # Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS 505 | # 506 | 507 | ## Protect against certain cross-origin requests. More information can be found here: 508 | ## https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP) 509 | 510 | Header always set Cross-Origin-Resource-Policy "same-origin" 511 | Header always set Timing-Allow-Origin "same-origin" 512 | 513 | ## Conversely, if you want to allow Cross-Origin Request Sharing (CORS) you need 514 | ## to remove the block above and uncomment the block below. 515 | ## Also see http://enable-cors.org/ 516 | # 517 | # Header always set Access-Control-Allow-Origin "*" 518 | # Header always set Timing-Allow-Origin "*" 519 | # 520 | 521 | ## Referrer-policy 522 | 523 | Header always set Referrer-Policy "strict-origin-when-cross-origin" 524 | 525 | 526 | ## Set the UTF-8 character set as the default 527 | # Serve all resources labeled as `text/html` or `text/plain` 528 | # with the media type `charset` parameter set to `UTF-8`. 529 | AddDefaultCharset utf-8 530 | 531 | # Serve the following file types with the media type `charset` 532 | # parameter set to `UTF-8`. 533 | # 534 | # https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset 535 | 536 | AddCharset utf-8 .atom \ 537 | .bbaw \ 538 | .css \ 539 | .geojson \ 540 | .js \ 541 | .json \ 542 | .jsonld \ 543 | .rdf \ 544 | .rss \ 545 | .topojson \ 546 | .vtt \ 547 | .webapp \ 548 | .xloc \ 549 | .xml 550 | 551 | 552 | ########## Begin - Joomla! core SEF Section 553 | 554 | ## PHP FastCGI fix for HTTP Authorization. Do not remove. 555 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 556 | 557 | ## -- SEF URLs for the API application 558 | ## 559 | ## This section applies ONLY to Joomla 4. 560 | ## 561 | ## If the requested path starts with /api, the file is not /api/index.php 562 | ## and the request has not already been internally rewritten to the 563 | ## api/index.php script 564 | RewriteCond %{REQUEST_URI} ^/api/ 565 | RewriteCond %{REQUEST_URI} !^/api/index\.php 566 | ## and the requested path and file doesn't directly match a physical file 567 | RewriteCond %{REQUEST_FILENAME} !-f 568 | ## and the requested path and file doesn't directly match a physical folder 569 | RewriteCond %{REQUEST_FILENAME} !-d 570 | ## internally rewrite the request the the /api/index.php script 571 | RewriteRule .* api/index.php [L] 572 | 573 | ## -- SEF URLs for the public frontend application 574 | ## 575 | ## This section applies to Joomla 3 AND 4 576 | ## 577 | ## If the requested path and file is not /index.php and the request 578 | ## has not already been internally rewritten to the index.php script 579 | RewriteCond %{REQUEST_URI} !^/index\.php 580 | ## and the requested path and file doesn't directly match a physical file 581 | RewriteCond %{REQUEST_FILENAME} !-f 582 | ## and the requested path and file doesn't directly match a physical folder 583 | RewriteCond %{REQUEST_FILENAME} !-d 584 | ## internally rewrite the request to the index.php script 585 | RewriteRule .* index.php [L] 586 | ########## End - Joomla! core SEF Section 587 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Kyrion .htaccess 2 | 3 | Security-enhancing .htaccess (Apache), web.config (IIS) and NginX configuration files for Joomla! 4 | 5 | ## Customization required 6 | 7 | The files in this repository are designed as a template for you to create the .htaccess, web.config or NginX configuration file for your Joomla 3.x and 4.x sites. Their goal is to increase the security and performance of your site. 8 | 9 | You cannot simply drop a file into your site and call it a day. Each site and server configuration is a unique environment. These files need customization. You need to go through the entire file and understand what it's doing - there are comments. At the very least you need to replace `example.com`, `www.example.com`, `example\.com` and `www\.example\.com` with your real domain name. 10 | 11 | Some sections may cause problems with legitimate requests. You are ultimately responsible for disabling them or writing exception rules for your requests. Most notably, the advanced server protection section may cause issues with core features and third party software. You must add exceptions for them manually. 12 | 13 | On the same note, some sections - depending on your server configuration - may cause your site to throw 500 Internal Server Error. The only way to figure out which one is causing it is trial and error. 14 | 15 | ## No support 16 | 17 | Please bear in mind that I do not offer any kind of support for these files. If it breaks you get to keep both pieces. 18 | 19 | ## Do you want an easier way to customize these files? 20 | 21 | Customizing the server configuration files can be done with a few clicks using [Admin Tools Professional](http://www.akeebabackup.com/software/admin-tools.html). You also get a lot more security enhancing features for your Joomla site. Moreover, it comes with support. 22 | 23 | Purchasing a subscription to any of our software helps me and the other three people working with me to make a living. This allows us to work on Free and Open Source Software, do research and come up with things like this repository here. 24 | 25 | ## About the name 26 | 27 | Both words in the repository's title have a story and are not quite what I intended. 28 | 29 | “Kyrion” is a Greek word that means something that is either authoritative or meant to be the main instance which can be copied and modified. Yes, I am perfectly aware that there is an English word for that concept: “master”. Unfortunately, people take great offense at the word as having a racist connotation. On the upside, you clone a repository and you get a free Greek lesson. You're welcome. 30 | 31 | As for the second part being “.htaccess” when this repo also has NginX and IIS configuration files, not just the Apache ones, the reasoning is much simpler. When I started working on it back in 2009 it was only a .htaccess file I was using on all of my sites. It wasn't until 2011-ish that I started working on the other two files. 32 | 33 | I intended to call it The Non-Racially Charged Adjective Denoting Intent To Be Further Copied And Customized Server Configuration File Repository For Joomla Sites Running On Servers Capable Of Understanding Apache, NginX or IIS Configuration Language but that was a mouthful and a half and GitHub wouldn't allow me to use that name. So I settled for “Kyrion .htaccess“ and called it a night. -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | ###################################################################### 3 | ## The Kyrion NginX Configuration 4 | ## 5 | ## PLEASE READ THE README.md FILE BEFORE TRYING TO USE THIS ON YOUR SITE. 6 | ############################################################################### 7 | 8 | ###################################################################### 9 | ## Basic server setup. Change to match YOUR system! 10 | ###################################################################### 11 | # -- Basic configuration 12 | # ---- Port to listen to. For SSL sites change this to 443. 13 | listen 80; 14 | # ---- Domain name(s) of this site, separated by commas 15 | server_name www.example.com example.com www.example.org example.org; 16 | # ---- Site root path 17 | root /home/web/domains/www.example.com/public_html; 18 | # ---- Path to the access log 19 | access_log /home/web/domains/www.example.com/logs/access.log; 20 | # ---- Path to the error log 21 | error_log /home/web/domains/www.example.com/logs/error.log; 22 | # ---- Custom error pages. Each error page is four lines. The first one 23 | # defines which page will be shown for each error code. The next 24 | # three lines make sure that the error page cannot be accessed 25 | # directly over the web. 26 | error_page 404 /errors/404.html; 27 | location /errors/404.html { 28 | internal; 29 | } 30 | 31 | error_page 500 /errors/500.html; 32 | location /errors/500.html { 33 | internal; 34 | } 35 | 36 | error_page 403 /errors/403.html; 37 | location /errors/403.html { 38 | internal; 39 | } 40 | 41 | ###################################################################### 42 | ## SSL Configuration 43 | ## 44 | ## Only use this block if you are setting up the SSL (HTTPS) server 45 | ## definition of your site. 46 | ###################################################################### 47 | ssl on; 48 | ssl_certificate /etc/ssl/localcerts/webserver.pem; 49 | ssl_certificate_key /etc/ssl/localcerts/webserver.key; 50 | 51 | ssl_session_timeout 5m; 52 | 53 | ssl_protocols SSLv3 TLSv1; 54 | ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; 55 | ssl_prefer_server_ciphers on; 56 | 57 | ###################################################################### 58 | ## The Kitchen Sink - An array of useful and performance-tuning options 59 | ###################################################################### 60 | # -- Timeout handling, see http://wiki.nginx.org/HttpCoreModule 61 | client_header_timeout 10; 62 | client_body_timeout 10; 63 | send_timeout 30; 64 | keepalive_timeout 40 20; 65 | 66 | # -- Socket settings, see http://wiki.nginx.org/HttpCoreModule 67 | connection_pool_size 8192; 68 | client_header_buffer_size 4k; 69 | large_client_header_buffers 8 8k; 70 | request_pool_size 8k; 71 | 72 | # -- Performance, see http://wiki.nginx.org/HttpCoreModule 73 | sendfile on; 74 | sendfile_max_chunk 1m; 75 | postpone_output 0; 76 | tcp_nopush on; 77 | tcp_nodelay off; 78 | 79 | # -- Output buffering, see http://wiki.nginx.org/HttpCoreModule 80 | output_buffers 8 32k; 81 | 82 | # -- Character encoding, see http://wiki.nginx.org/HttpCharsetModule 83 | charset utf-8; 84 | source_charset utf-8; 85 | 86 | # -- Security options, see http://wiki.nginx.org/HttpCoreModule 87 | server_name_in_redirect off; 88 | server_tokens off; 89 | ignore_invalid_headers on; 90 | # You may have to comment out the next line on multi-site installations 91 | disable_symlinks if_not_owner; 92 | 93 | # -- Maximum client body size set to 1 Gigabyte 94 | client_max_body_size 1G; 95 | 96 | ###################################################################### 97 | ## Redirect non-www to www 98 | ## 99 | ## If you enable this, disable the "Redirect www to non-www" below! 100 | ###################################################################### 101 | if ($host = 'example.com' ) { 102 | rewrite ^/(.*)$ http://www.example.com/$1 permanent; 103 | } 104 | 105 | ###################################################################### 106 | ## Redirect www to non-www 107 | ## 108 | ## If you enable this, disable the "Redirect non-www to www" above! 109 | ###################################################################### 110 | #if ($host = 'www.example.com' ) { 111 | # rewrite ^/(.*)$ http://example.com/$1 permanent; 112 | #} 113 | 114 | ###################################################################### 115 | ## Redirect example.org to example.com 116 | ## 117 | ## Your server_name must include both the old and new domain names! 118 | ###################################################################### 119 | if ($host ~ "(www\.)?example.org$" ) { 120 | rewrite ^/(.*)$ http://www.example.com/$1 permanent; 121 | } 122 | 123 | ###################################################################### 124 | ## CloudFlare support - see http://wiki.nginx.org/NginxHttpRealIpModule 125 | ## Comment out if you are not using the CloudFlare CDN 126 | ###################################################################### 127 | set_real_ip_from 204.93.240.0/24; 128 | set_real_ip_from 204.93.177.0/24; 129 | set_real_ip_from 199.27.128.0/21; 130 | set_real_ip_from 173.245.48.0/20; 131 | set_real_ip_from 103.22.200.0/22; 132 | set_real_ip_from 141.101.64.0/18; 133 | set_real_ip_from 108.162.192.0/18; 134 | set_real_ip_from 190.93.240.0/20; 135 | real_ip_header CF-Connecting-IP; 136 | 137 | ## HSTS Header - See http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security 138 | # add_header Strict-Transport-Security max-age=31536000; 139 | 140 | ## Referrer-policy 141 | add_header Referrer-Policy "no-referrer-when-downgrade"; 142 | 143 | ###################################################################### 144 | ## Directory indices 145 | ## Forces index.php to be read before the index.htm(l) files 146 | ###################################################################### 147 | index index.php index.html index.htm; 148 | 149 | ###################################################################### 150 | ## Status page - DISABLE THIS ON LIVE SITES! 151 | ###################################################################### 152 | location /nginx_status { 153 | stub_status on; 154 | access_log off; 155 | # Remember to change this to your PC's IP address 156 | allow 192.168.0.1; 157 | } 158 | 159 | ###################################################################### 160 | ## Google Apps redirection 161 | ## This also shows how to redirect a directory to an external server 162 | ###################################################################### 163 | location ~* /mail { 164 | rewrite ^ http://mail.google.com/a/example.com permanent; 165 | } 166 | 167 | ###################################################################### 168 | ## Block some common exploits 169 | ###################################################################### 170 | set $common_exploit 0; 171 | if ($query_string ~ "proc/self/environ") { 172 | set $common_exploit 1; 173 | } 174 | if ($query_string ~ "mosConfig_[a-zA-Z_]{1,21}(=|\%3D)") { 175 | set $common_exploit 1; 176 | } 177 | if ($query_string ~ "base64_(en|de)code\(.*\)") { 178 | set $common_exploit 1; 179 | } 180 | if ($query_string ~ "(<|%3C).*script.*(>|%3E)") { 181 | set $common_exploit 1; 182 | } 183 | if ($query_string ~ "GLOBALS(=|\[|\%[0-9A-Z]{0,2})") { 184 | set $common_exploit 1; 185 | } 186 | if ($query_string ~ "_REQUEST(=|\[|\%[0-9A-Z]{0,2})") { 187 | set $common_exploit 1; 188 | } 189 | if ($common_exploit = 1) { 190 | return 403; 191 | } 192 | 193 | ###################################################################### 194 | ## Protect against common file injection attacks 195 | ###################################################################### 196 | set $file_injection 0; 197 | if ($query_string ~ "[a-zA-Z0-9_]=http://") { 198 | set $file_injection 1; 199 | } 200 | if ($query_string ~ "[a-zA-Z0-9_]=(\.\.//?)+") { 201 | set $file_injection 1; 202 | } 203 | if ($query_string ~ "[a-zA-Z0-9_]=/([a-z0-9_.]//?)+") { 204 | set $file_injection 1; 205 | } 206 | if ($file_injection = 1) { 207 | return 403; 208 | break; 209 | } 210 | 211 | ## Enable SEF URLs 212 | # Joomla API application 213 | location /api/ { 214 | try_files $uri $uri/ /api/index.php?$args; 215 | } 216 | # Joomla public frontend application 217 | location / { 218 | try_files $uri $uri/ /index.php?$args; 219 | } 220 | # Parse index.php as a PHP executable file 221 | location ~* /index.php$ { 222 | fastcgi_pass $fastcgi_pass; 223 | break; 224 | } 225 | 226 | ###################################################################### 227 | ## Advanced server protection rules exceptions 228 | ## 229 | ## You will DEFINITELY need to add exceptions for a lot of extensions 230 | ## to work. Yeah, I have to write an illustrated guide at some point. 231 | ## However, if you can use Firebug or Google Chrome Web Developer 232 | ## window then you can find out the exceptions all by yourself. Use the 233 | ## following as a guide. 234 | ###################################################################### 235 | # Allow direct access to a specific PHP file 236 | location = /tmp/test.php { 237 | fastcgi_pass $fastcgi_pass; 238 | break; 239 | } 240 | 241 | # Allow direct access to a specific static (non-PHP) file 242 | location = /administrator/test.png { 243 | break; 244 | } 245 | 246 | # Recommended exceptions 247 | location = /administrator/components/com_akeeba/restore.php { 248 | fastcgi_pass $fastcgi_pass; 249 | break; 250 | } 251 | location = /administrator/components/com_admintools/restore.php { 252 | fastcgi_pass $fastcgi_pass; 253 | break; 254 | } 255 | location = /administrator/components/com_joomlaupdate/restore.php { 256 | fastcgi_pass $fastcgi_pass; 257 | break; 258 | } 259 | location ~* ^/\.well\-known/.*\.php$ 260 | { 261 | break; 262 | } 263 | location ~* ^/\.well\-known/.*$ 264 | { 265 | break; 266 | } 267 | # This needs customisation! 268 | location ~* ^/templates\/your_template_name_here/.*$ 269 | { 270 | break; 271 | } 272 | 273 | ###################################################################### 274 | ## Disable PHP Easter Eggs 275 | ###################################################################### 276 | if ($query_string ~ "\=PHP[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}") { 277 | return 403; 278 | break; 279 | } 280 | 281 | ###################################################################### 282 | ## Block access to configuration.php-dist and htaccess.txt 283 | ###################################################################### 284 | location = /configuration.php-dist { 285 | log_not_found off; 286 | access_log off; 287 | return 404; 288 | break; 289 | } 290 | 291 | location = /htaccess.txt { 292 | log_not_found off; 293 | access_log off; 294 | return 404; 295 | break; 296 | } 297 | 298 | location = /web.config { 299 | log_not_found off; 300 | access_log off; 301 | return 404; 302 | break; 303 | } 304 | 305 | location = /configuration.php { 306 | log_not_found off; 307 | access_log off; 308 | return 404; 309 | break; 310 | } 311 | 312 | location = /CONTRIBUTING.md { 313 | log_not_found off; 314 | access_log off; 315 | return 404; 316 | break; 317 | } 318 | 319 | location = /joomla.xml { 320 | log_not_found off; 321 | access_log off; 322 | return 404; 323 | break; 324 | } 325 | 326 | location = /LICENSE.txt { 327 | log_not_found off; 328 | access_log off; 329 | return 404; 330 | break; 331 | } 332 | 333 | location = /phpunit.xml { 334 | log_not_found off; 335 | access_log off; 336 | return 404; 337 | break; 338 | } 339 | 340 | location = /README.txt { 341 | log_not_found off; 342 | access_log off; 343 | return 404; 344 | break; 345 | } 346 | 347 | location = /web.config.txt { 348 | log_not_found off; 349 | access_log off; 350 | return 404; 351 | break; 352 | } 353 | 354 | ###################################################################### 355 | ## Advanced server protection 356 | ###################################################################### 357 | # Allow media files in select back-end directories 358 | location ~* ^/administrator/(components|modules|templates|images|plugins)/.*.(jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|htm|ttf|woff|woff2|eot|webp|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT|WEBP)$ { 359 | break; 360 | } 361 | 362 | # Allow access to the back-end index.php file 363 | location = /administrator/index.php { 364 | fastcgi_pass $fastcgi_pass; 365 | break; 366 | } 367 | location ~* ^/administrator$ { 368 | return 301 /administrator/index.php?$args; 369 | } 370 | location ~* ^/administrator/$ { 371 | return 301 /administrator/index.php?$args; 372 | } 373 | 374 | # Disable access to everything else. 375 | location ~* /administrator.*$ { 376 | # If it is a file, directory or symlink and I haven't deliberately 377 | # enabled access to it, forbid any access to it! 378 | if (-e $request_filename) { 379 | return 403; 380 | } 381 | # In any other case, just treat as a SEF URL 382 | try_files $uri $uri/ /administrator/index.php?$args; 383 | } 384 | 385 | # Allow media files in select front-end directories 386 | location ~* ^/(components|modules|templates|images|plugins|media|libraries|media/jui/fonts)/.*.(jpe|jpg|jpeg|jp2|jpe2|png|gif|bmp|css|js|swf|html|mpg|mp3|mpeg|mp4|avi|wav|ogg|ogv|xls|xlsx|doc|docx|ppt|pptx|zip|rar|pdf|xps|txt|7z|svg|odt|ods|odp|flv|mov|ico|htm|ttf|woff|woff2|eot|webp|JPG|JPEG|PNG|GIF|CSS|JS|TTF|WOFF|WOFF2|EOT|WEBP)$ { 387 | break; 388 | } 389 | 390 | ## Disallow front-end access for certain Joomla! system directories (unless access to their files is allowed above) 391 | location ~* ^/includes/js/ { 392 | return 403; 393 | } 394 | location ~* ^/(cache|includes|language|logs|log|tmp)/ { 395 | return 403; 396 | } 397 | # Allow access to / 398 | location ~* ^/$ { 399 | return 301 /index.php?$args; 400 | } 401 | 402 | # Disable access to everything else. 403 | location ~* ^/.*$ { 404 | # If it is a file, directory or symlink and I haven't deliberately 405 | # enabled access to it, forbid any access to it! 406 | if (-e $request_filename) { 407 | return 403; 408 | } 409 | # In any other case, just treat as a SEF URL 410 | try_files $uri $uri/ /index.php?$args; 411 | } 412 | ##### Advanced server protection -- END 413 | 414 | ###################################################################### 415 | ## PHP Setup 416 | ###################################################################### 417 | include fastcgi_params; 418 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 419 | set $fastcgi_pass "unix:/var/run/php5-fpm-web.sock"; 420 | location ~ index.php$ { 421 | fastcgi_pass $fastcgi_pass; 422 | } 423 | 424 | ###################################################################### 425 | ## Expiration control 426 | ## 427 | ## Optimises the expiration time 428 | ###################################################################### 429 | # CSS and JavaScript : 1 week 430 | location ~* \.(css|js)$ { 431 | access_log off; log_not_found off; 432 | expires 1w; 433 | } 434 | 435 | # Image files : 1 month 436 | location ~* \.(bmp|gif|jpg|jpeg|jp2|png|svg|tif|tiff|ico|wbmp|wbxml|smil|webp)$ { 437 | access_log off; log_not_found off; 438 | expires 1M; 439 | } 440 | 441 | # Font files : 1 week 442 | location ~* \.(woff|woff2|ttf|otf|eot)$ { 443 | access_log off; log_not_found off; 444 | expires 1M; 445 | } 446 | 447 | # Document files : 1 month 448 | location ~* \.(pdf|txt|xml)$ { 449 | access_log off; log_not_found off; 450 | expires 1M; 451 | } 452 | 453 | # Audio files : 1 month 454 | location ~* \.(mid|midi|mp3|m4a|m4r|aif|aiff|ra|wav|voc|ogg)$ { 455 | access_log off; log_not_found off; 456 | expires 1M; 457 | } 458 | 459 | # Video files : 1 month 460 | location ~* \.(swf|vrml|avi|mkv|mpg|mpeg|mp4|m4v|mov|asf)$ { 461 | access_log off; log_not_found off; 462 | expires 1M; 463 | } 464 | 465 | ###################################################################### 466 | ## User agent blocking 467 | ## 468 | ## Disables access to your site by user agent. Useful to block some 469 | ## bandwidth hoggers. 470 | ###################################################################### 471 | set $bad_ua 0; 472 | 473 | if ($http_user_agent ~ "WebBandit") { 474 | set $bad_ua 1; 475 | } 476 | if ($http_user_agent ~ "webbandit") { 477 | set $bad_ua 1; 478 | } 479 | if ($http_user_agent ~ "Acunetix") { 480 | set $bad_ua 1; 481 | } 482 | if ($http_user_agent ~ "binlar") { 483 | set $bad_ua 1; 484 | } 485 | if ($http_user_agent ~ "BlackWidow") { 486 | set $bad_ua 1; 487 | } 488 | if ($http_user_agent ~ "Bolt 0") { 489 | set $bad_ua 1; 490 | } 491 | if ($http_user_agent ~ "Bot mailto:craftbot@yahoo.com") { 492 | set $bad_ua 1; 493 | } 494 | if ($http_user_agent ~ "BOT for JCE") { 495 | set $bad_ua 1; 496 | } 497 | if ($http_user_agent ~ "casper") { 498 | set $bad_ua 1; 499 | } 500 | if ($http_user_agent ~ "checkprivacy") { 501 | set $bad_ua 1; 502 | } 503 | if ($http_user_agent ~ "ChinaClaw") { 504 | set $bad_ua 1; 505 | } 506 | if ($http_user_agent ~ "clshttp") { 507 | set $bad_ua 1; 508 | } 509 | if ($http_user_agent ~ "cmsworldmap") { 510 | set $bad_ua 1; 511 | } 512 | if ($http_user_agent ~ "comodo") { 513 | set $bad_ua 1; 514 | } 515 | if ($http_user_agent ~ "Custo") { 516 | set $bad_ua 1; 517 | } 518 | if ($http_user_agent ~ "Default Browser 0") { 519 | set $bad_ua 1; 520 | } 521 | if ($http_user_agent ~ "diavol") { 522 | set $bad_ua 1; 523 | } 524 | if ($http_user_agent ~ "DIIbot") { 525 | set $bad_ua 1; 526 | } 527 | if ($http_user_agent ~ "DISCo") { 528 | set $bad_ua 1; 529 | } 530 | if ($http_user_agent ~ "dotbot") { 531 | set $bad_ua 1; 532 | } 533 | if ($http_user_agent ~ "Download Demon") { 534 | set $bad_ua 1; 535 | } 536 | if ($http_user_agent ~ "eCatch") { 537 | set $bad_ua 1; 538 | } 539 | if ($http_user_agent ~ "EirGrabber") { 540 | set $bad_ua 1; 541 | } 542 | if ($http_user_agent ~ "EmailCollector") { 543 | set $bad_ua 1; 544 | } 545 | if ($http_user_agent ~ "EmailSiphon") { 546 | set $bad_ua 1; 547 | } 548 | if ($http_user_agent ~ "EmailWolf") { 549 | set $bad_ua 1; 550 | } 551 | if ($http_user_agent ~ "Express WebPictures") { 552 | set $bad_ua 1; 553 | } 554 | if ($http_user_agent ~ "extract") { 555 | set $bad_ua 1; 556 | } 557 | if ($http_user_agent ~ "ExtractorPro") { 558 | set $bad_ua 1; 559 | } 560 | if ($http_user_agent ~ "EyeNetIE") { 561 | set $bad_ua 1; 562 | } 563 | if ($http_user_agent ~ "feedfinder") { 564 | set $bad_ua 1; 565 | } 566 | if ($http_user_agent ~ "FHscan") { 567 | set $bad_ua 1; 568 | } 569 | if ($http_user_agent ~ "FlashGet") { 570 | set $bad_ua 1; 571 | } 572 | if ($http_user_agent ~ "flicky") { 573 | set $bad_ua 1; 574 | } 575 | if ($http_user_agent ~ "GetRight") { 576 | set $bad_ua 1; 577 | } 578 | if ($http_user_agent ~ "GetWeb!") { 579 | set $bad_ua 1; 580 | } 581 | if ($http_user_agent ~ "Go-Ahead-Got-It") { 582 | set $bad_ua 1; 583 | } 584 | if ($http_user_agent ~ "Go!Zilla") { 585 | set $bad_ua 1; 586 | } 587 | if ($http_user_agent ~ "grab") { 588 | set $bad_ua 1; 589 | } 590 | if ($http_user_agent ~ "GrabNet") { 591 | set $bad_ua 1; 592 | } 593 | if ($http_user_agent ~ "Grafula") { 594 | set $bad_ua 1; 595 | } 596 | if ($http_user_agent ~ "harvest") { 597 | set $bad_ua 1; 598 | } 599 | if ($http_user_agent ~ "HMView") { 600 | set $bad_ua 1; 601 | } 602 | if ($http_user_agent ~ "ia_archiver") { 603 | set $bad_ua 1; 604 | } 605 | if ($http_user_agent ~ "Image Stripper") { 606 | set $bad_ua 1; 607 | } 608 | if ($http_user_agent ~ "Image Sucker") { 609 | set $bad_ua 1; 610 | } 611 | if ($http_user_agent ~ "InterGET") { 612 | set $bad_ua 1; 613 | } 614 | if ($http_user_agent ~ "Internet Ninja") { 615 | set $bad_ua 1; 616 | } 617 | if ($http_user_agent ~ "InternetSeer.com") { 618 | set $bad_ua 1; 619 | } 620 | if ($http_user_agent ~ "jakarta") { 621 | set $bad_ua 1; 622 | } 623 | if ($http_user_agent ~ "Java") { 624 | set $bad_ua 1; 625 | } 626 | if ($http_user_agent ~ "JetCar") { 627 | set $bad_ua 1; 628 | } 629 | if ($http_user_agent ~ "JOC Web Spider") { 630 | set $bad_ua 1; 631 | } 632 | if ($http_user_agent ~ "kmccrew") { 633 | set $bad_ua 1; 634 | } 635 | if ($http_user_agent ~ "larbin") { 636 | set $bad_ua 1; 637 | } 638 | if ($http_user_agent ~ "LeechFTP") { 639 | set $bad_ua 1; 640 | } 641 | if ($http_user_agent ~ "libwww") { 642 | set $bad_ua 1; 643 | } 644 | if ($http_user_agent ~ "Mass Downloader") { 645 | set $bad_ua 1; 646 | } 647 | if ($http_user_agent ~ "Maxthon$") { 648 | set $bad_ua 1; 649 | } 650 | if ($http_user_agent ~ "microsoft.url") { 651 | set $bad_ua 1; 652 | } 653 | if ($http_user_agent ~ "MIDown tool") { 654 | set $bad_ua 1; 655 | } 656 | if ($http_user_agent ~ "miner") { 657 | set $bad_ua 1; 658 | } 659 | if ($http_user_agent ~ "Mister PiX") { 660 | set $bad_ua 1; 661 | } 662 | if ($http_user_agent ~ "NEWT") { 663 | set $bad_ua 1; 664 | } 665 | if ($http_user_agent ~ "MSFrontPage") { 666 | set $bad_ua 1; 667 | } 668 | if ($http_user_agent ~ "Navroad") { 669 | set $bad_ua 1; 670 | } 671 | if ($http_user_agent ~ "NearSite") { 672 | set $bad_ua 1; 673 | } 674 | if ($http_user_agent ~ "Net Vampire") { 675 | set $bad_ua 1; 676 | } 677 | if ($http_user_agent ~ "NetAnts") { 678 | set $bad_ua 1; 679 | } 680 | if ($http_user_agent ~ "NetSpider") { 681 | set $bad_ua 1; 682 | } 683 | if ($http_user_agent ~ "NetZIP") { 684 | set $bad_ua 1; 685 | } 686 | if ($http_user_agent ~ "nutch") { 687 | set $bad_ua 1; 688 | } 689 | if ($http_user_agent ~ "Octopus") { 690 | set $bad_ua 1; 691 | } 692 | if ($http_user_agent ~ "Offline Explorer") { 693 | set $bad_ua 1; 694 | } 695 | if ($http_user_agent ~ "Offline Navigator") { 696 | set $bad_ua 1; 697 | } 698 | if ($http_user_agent ~ "PageGrabber") { 699 | set $bad_ua 1; 700 | } 701 | if ($http_user_agent ~ "Papa Foto") { 702 | set $bad_ua 1; 703 | } 704 | if ($http_user_agent ~ "pavuk") { 705 | set $bad_ua 1; 706 | } 707 | if ($http_user_agent ~ "pcBrowser") { 708 | set $bad_ua 1; 709 | } 710 | if ($http_user_agent ~ "PeoplePal") { 711 | set $bad_ua 1; 712 | } 713 | if ($http_user_agent ~ "planetwork") { 714 | set $bad_ua 1; 715 | } 716 | if ($http_user_agent ~ "psbot") { 717 | set $bad_ua 1; 718 | } 719 | if ($http_user_agent ~ "purebot") { 720 | set $bad_ua 1; 721 | } 722 | if ($http_user_agent ~ "RealDownload") { 723 | set $bad_ua 1; 724 | } 725 | if ($http_user_agent ~ "ReGet") { 726 | set $bad_ua 1; 727 | } 728 | if ($http_user_agent ~ "Rippers 0") { 729 | set $bad_ua 1; 730 | } 731 | if ($http_user_agent ~ "SeaMonkey$") { 732 | set $bad_ua 1; 733 | } 734 | if ($http_user_agent ~ "sitecheck.internetseer.com") { 735 | set $bad_ua 1; 736 | } 737 | if ($http_user_agent ~ "SiteSnagger") { 738 | set $bad_ua 1; 739 | } 740 | if ($http_user_agent ~ "skygrid") { 741 | set $bad_ua 1; 742 | } 743 | if ($http_user_agent ~ "SmartDownload") { 744 | set $bad_ua 1; 745 | } 746 | if ($http_user_agent ~ "sucker") { 747 | set $bad_ua 1; 748 | } 749 | if ($http_user_agent ~ "SuperBot") { 750 | set $bad_ua 1; 751 | } 752 | if ($http_user_agent ~ "SuperHTTP") { 753 | set $bad_ua 1; 754 | } 755 | if ($http_user_agent ~ "Surfbot") { 756 | set $bad_ua 1; 757 | } 758 | if ($http_user_agent ~ "tAkeOut") { 759 | set $bad_ua 1; 760 | } 761 | if ($http_user_agent ~ "Teleport Pro") { 762 | set $bad_ua 1; 763 | } 764 | if ($http_user_agent ~ "Toata dragostea mea pentru diavola") { 765 | set $bad_ua 1; 766 | } 767 | if ($http_user_agent ~ "turnit") { 768 | set $bad_ua 1; 769 | } 770 | if ($http_user_agent ~ "vikspider") { 771 | set $bad_ua 1; 772 | } 773 | if ($http_user_agent ~ "VoidEYE") { 774 | set $bad_ua 1; 775 | } 776 | if ($http_user_agent ~ "Web Image Collector") { 777 | set $bad_ua 1; 778 | } 779 | if ($http_user_agent ~ "Web Sucker") { 780 | set $bad_ua 1; 781 | } 782 | if ($http_user_agent ~ "WebAuto") { 783 | set $bad_ua 1; 784 | } 785 | if ($http_user_agent ~ "WebCopier") { 786 | set $bad_ua 1; 787 | } 788 | if ($http_user_agent ~ "WebFetch") { 789 | set $bad_ua 1; 790 | } 791 | if ($http_user_agent ~ "WebGo IS") { 792 | set $bad_ua 1; 793 | } 794 | if ($http_user_agent ~ "WebLeacher") { 795 | set $bad_ua 1; 796 | } 797 | if ($http_user_agent ~ "WebReaper") { 798 | set $bad_ua 1; 799 | } 800 | if ($http_user_agent ~ "WebSauger") { 801 | set $bad_ua 1; 802 | } 803 | if ($http_user_agent ~ "Website eXtractor") { 804 | set $bad_ua 1; 805 | } 806 | if ($http_user_agent ~ "Website Quester") { 807 | set $bad_ua 1; 808 | } 809 | if ($http_user_agent ~ "WebStripper") { 810 | set $bad_ua 1; 811 | } 812 | if ($http_user_agent ~ "WebWhacker") { 813 | set $bad_ua 1; 814 | } 815 | if ($http_user_agent ~ "WebZIP") { 816 | set $bad_ua 1; 817 | } 818 | if ($http_user_agent ~ "Widow") { 819 | set $bad_ua 1; 820 | } 821 | if ($http_user_agent ~ "WWW-Mechanize") { 822 | set $bad_ua 1; 823 | } 824 | if ($http_user_agent ~ "WWWOFFLE") { 825 | set $bad_ua 1; 826 | } 827 | if ($http_user_agent ~ "Xaldon WebSpider") { 828 | set $bad_ua 1; 829 | } 830 | if ($http_user_agent ~ "Yandex") { 831 | set $bad_ua 1; 832 | } 833 | if ($http_user_agent ~ "Zeus") { 834 | set $bad_ua 1; 835 | } 836 | if ($http_user_agent ~ "zmeu") { 837 | set $bad_ua 1; 838 | } 839 | if ($http_user_agent ~ "CazoodleBot") { 840 | set $bad_ua 1; 841 | } 842 | if ($http_user_agent ~ "discobot") { 843 | set $bad_ua 1; 844 | } 845 | if ($http_user_agent ~ "ecxi") { 846 | set $bad_ua 1; 847 | } 848 | if ($http_user_agent ~ "GT::WWW") { 849 | set $bad_ua 1; 850 | } 851 | if ($http_user_agent ~ "heritrix") { 852 | set $bad_ua 1; 853 | } 854 | if ($http_user_agent ~ "HTTP::Lite") { 855 | set $bad_ua 1; 856 | } 857 | if ($http_user_agent ~ "HTTrack") { 858 | set $bad_ua 1; 859 | } 860 | if ($http_user_agent ~ "ia_archiver") { 861 | set $bad_ua 1; 862 | } 863 | if ($http_user_agent ~ "id-search") { 864 | set $bad_ua 1; 865 | } 866 | if ($http_user_agent ~ "id-search.org") { 867 | set $bad_ua 1; 868 | } 869 | if ($http_user_agent ~ "IDBot") { 870 | set $bad_ua 1; 871 | } 872 | if ($http_user_agent ~ "Indy Library") { 873 | set $bad_ua 1; 874 | } 875 | if ($http_user_agent ~ "IRLbot") { 876 | set $bad_ua 1; 877 | } 878 | if ($http_user_agent ~ "ISC Systems iRc Search 2.1") { 879 | set $bad_ua 1; 880 | } 881 | if ($http_user_agent ~ "LinksManager.com_bot") { 882 | set $bad_ua 1; 883 | } 884 | if ($http_user_agent ~ "linkwalker") { 885 | set $bad_ua 1; 886 | } 887 | if ($http_user_agent ~ "lwp-trivial") { 888 | set $bad_ua 1; 889 | } 890 | if ($http_user_agent ~ "MFC_Tear_Sample") { 891 | set $bad_ua 1; 892 | } 893 | if ($http_user_agent ~ "Microsoft URL Control") { 894 | set $bad_ua 1; 895 | } 896 | if ($http_user_agent ~ "Missigua Locator") { 897 | set $bad_ua 1; 898 | } 899 | if ($http_user_agent ~ "panscient.com") { 900 | set $bad_ua 1; 901 | } 902 | if ($http_user_agent ~ "PECL::HTTP") { 903 | set $bad_ua 1; 904 | } 905 | if ($http_user_agent ~ "PHPCrawl") { 906 | set $bad_ua 1; 907 | } 908 | if ($http_user_agent ~ "PleaseCrawl") { 909 | set $bad_ua 1; 910 | } 911 | if ($http_user_agent ~ "SBIder") { 912 | set $bad_ua 1; 913 | } 914 | if ($http_user_agent ~ "Snoopy") { 915 | set $bad_ua 1; 916 | } 917 | if ($http_user_agent ~ "Steeler") { 918 | set $bad_ua 1; 919 | } 920 | if ($http_user_agent ~ "URI::Fetch") { 921 | set $bad_ua 1; 922 | } 923 | if ($http_user_agent ~ "urllib") { 924 | set $bad_ua 1; 925 | } 926 | if ($http_user_agent ~ "Web Sucker") { 927 | set $bad_ua 1; 928 | } 929 | if ($http_user_agent ~ "webalta") { 930 | set $bad_ua 1; 931 | } 932 | if ($http_user_agent ~ "WebCollage") { 933 | set $bad_ua 1; 934 | } 935 | if ($http_user_agent ~ "Wells Search II") { 936 | set $bad_ua 1; 937 | } 938 | if ($http_user_agent ~ "WEP Search") { 939 | set $bad_ua 1; 940 | } 941 | if ($http_user_agent ~ "zermelo") { 942 | set $bad_ua 1; 943 | } 944 | if ($http_user_agent ~ "ZyBorg") { 945 | set $bad_ua 1; 946 | } 947 | if ($http_user_agent ~ "Indy Library") { 948 | set $bad_ua 1; 949 | } 950 | if ($http_user_agent ~ "libwww-perl") { 951 | set $bad_ua 1; 952 | } 953 | if ($http_user_agent ~ "Go!Zilla") { 954 | set $bad_ua 1; 955 | } 956 | if ($http_user_agent ~ "TurnitinBot") { 957 | set $bad_ua 1; 958 | } 959 | if ($http_user_agent ~ "sqlmap") { 960 | set $bad_ua 1; 961 | } 962 | if ($bad_ua = 1) { 963 | return 403; 964 | } 965 | 966 | # If you enable any of the above don't remove this. It's what blocks 967 | # the bad user agents! 968 | if ($bad_ua = 1) { 969 | return 403; 970 | } 971 | 972 | ###################################################################### 973 | ## Automatic compression of static resources 974 | ## Compress text, html, javascript, css, xml and other static resources 975 | ## May kill access to your site for old versions of Internet Explorer 976 | ###################################################################### 977 | # The following is the actual automatic compression setup 978 | gzip on; 979 | gzip_vary on; 980 | gzip_comp_level 6; 981 | gzip_proxied expired no-cache no-store private auth; 982 | gzip_min_length 1000; 983 | gzip_http_version 1.1; 984 | gzip_types text/plain text/css application/xhtml+xml application/xml+rss application/rss+xml application/x-javascript application/javascript text/javascript application/json text/xml application/xml image/svg+xml; 985 | gzip_buffers 16 8k; 986 | gzip_disable "MSIE [1-6]\.(?!.*SV1)"; 987 | 988 | } 989 | -------------------------------------------------------------------------------- /web.config: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | --------------------------------------------------------------------------------