VirtualHost level help
How to show files in a directory
If you want to list all files in a directory that doesn't use an index.php or index.html file, you can create an .htaccess file with the following contents:
Options +Indexes
This will tell Apache that you want to list all files in the directory.
How to redirect example.com to www.example.com
You can now manage domains and pointers www/non-www redirection in the DirectAdmin GUI User Level -> Domain Setup -> domain.com -> Force Redirect. This applies to both domains and pointers, but the redirection for pointers can be overridden by setting &www=no
in the domains/domain.com.pointers
file.
This feature is off by default due to possible redirect loops and related errors.
The following domain.conf settings are available to choose from:
- force_redirect=www
- force_redirect=non-www
- force_redirect=none
where both the domain.com/www.domain.com, and all pointers would be affected by it (unless overridden via the domains/domain.com.pointers
file).
SSL redirection and www/non-www redirection
Note that the "force ssl" checkbox is also related to this setting.
Using the current FORCE_SSL_REDIRECT
tokens in the virtual_host2*.conf
files, rules will be as follows:
Force www:
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Force non-www:
RewriteCond %{HTTP_HOST} ^www\.
RewriteRule ^ http://|DOMAIN|%{REQUEST_URI} [L,R=301]
none:
Follow the current "force ssl" rules.
Note: The RewriteRule would go to https instead of http, but only for VH:80, because the force_ssl
option only applies to VH:80.
The VH:443 doesn't need to force ssl, since it's already ssl.
Skins changes for the www/non-www redirection feature
The user/modify_domain.html
replaced the deprecated www_pointer
with:
<tr>
<td class=list>www redirect</td>
<td class=list align=left>
<input type="radio" name="force_redirect" value='none' |FORCE_REDIRECT_NONE_CHECKED|> No redirection<br>
<input type="radio" name="force_redirect" value='www' |FORCE_REDIRECT_WWW_CHECKED|> www.|DOMAIN|<br>
<input type="radio" name="force_redirect" value='non-www' |FORCE_REDIRECT_NON_WWW_CHECKED|> |DOMAIN|
</td>
<td class=list>Redirection for domain, pointers,<br>and sub-domains.</td>
</tr>
Template changes for the www/non-www redirection feature
In the following files:
virtual_host2_secure.conf
virtual_host2_secure_sub.conf
nginx_server_secure.conf
nginx_server_secure_sub.conf
we've added the |FORCE_SSL_REDIRECT|
token. Note that the 443 VirtualHosts will not fill the token with the force_ssl
redirect, but will fill it with the www/non-www redirects.
For 80 VirtualHosts, the FORCE_SSL_REDRECT
token is filled with both redirections for force_ssl/www/non-www redirects.
For any one given VirtualHost (eg: domain.com:80), there are 6 possible combinations using force_ssl
, and the 3x force_redirect
options.
12 if you include 80+443.
When considering pointer redirects and aliases, there are 24 more, totaling 36 combinations.
When considering subdomains, multiply that by 2 (subdomain or non-subdomain): 72 combinations.
Apache, nginx, openlitespeed, nginx_proxy, multiplies that by 4, so we have a grand total of 288 combinations of test cases.
We do have test scripts, to show us all possible combinations, but it's unlikely all combinations will actually be tested (we'll do as much as is reasonable).
Please try out this new feature and let us know if you run into any issues.
Subdomains and forced www redirection
Relating to the User Level feature that allows forcing domain.com » to www.domain.com (or vice versa), the new internal directadmin.conf option:
subdomain_force_redirect=0
excludes subdomains from this redirection because we rarely intend for the www redirection to affect subdomains. For example, the following redirection is rarely ever desired:
sub.domain.com » www.sub.domain.com
Note that subdomains in this context refers to subdomains that are created under a domain, as opposed to those subdomains created as "full domains".
If you do need subdomains to redirect to www, then enable the setting globally:
/usr/local/directadmin/directadmin set subdomain_force_redirect 1
service directadmin restart
The next rewrite of the User httpd.conf
(or other server User config) will be updated with the change. To update all User configs, type:
/usr/local/directadmin/custombuild/build rewrite_confs
Old Guide
The DirectAdmin panel provides a GUI for this feature, so now you can easily redirect to www with a few mouse clicks. The below guide is for reference only.
If you want to force clients to use www.domain.com, you can redirect them from domain.com to the www version with an .htaccess file.
In your public_html folder, create a file called .htaccess
and add the code:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
Other versions of the same thing do a negation check to see if the domain is not www.domain.com, but that doesn't work if you have subdomains, hence the need for the explicit check for the value we don't want.
How to redirect non-www or non-https to https
The DirectAdmin panel provides a GUI for this feature, so now you can easily redirect to www with mouse click.
You should find the checkbox in BOTH:
- User Level -> Domain Setup -> domain.com under the "private_html setup for domain.com" table, showing
[ ] Force SSL with https redirect
- AND at bottom of User Level -> domain.com -> SSL Certificates where, if checked, the port 80 VirtualHost/server{} entries for a domain/subdomains will automatically redirect to the same host and request, but with https.
The setting 'force_ssl=yes can be found in the '/usr/local/directadmin/data/users/username/domains/domain.com.conf
file, if the feature is enabled. If it's off, it will be absent from the file (will not show force_ssl=no
).
CMD_ADDITIONAL_DOMAINS?action=view&domain=domain.com&json=yes
will now include "force_ssl": "yes"
, if enabled. If off, it will be absent from the output.
force_ssl
Skin changes regarding In the file /usr/local/directadmin/data/skins/enhanced/user/modify_domain.html
, in the "private_html setup" table below the 2 radio <tr>
entries for the link, a new row exists:
<tr><td class=list2><input type="checkbox" name="force_ssl" value="yes" |SSLDISABLED| |FORCE_SSL_CHECKED|></td><td class=list2>|LANG_FORCE_SSL_REDIRECT|</td></tr>
And the /usr/local/directadmin/data/skins/enhanced/user/ssl.html
file contents are shown below:
<table class=mb15 cellpadding=3 cellspacing=1>
<form name=https action="/CMD_DOMAIN" method="post">
<input type=hidden name=action value="private_html">
<input type=hidden name=domain value="|DOMAIN|">
<tr><td><input type="checkbox" name="force_ssl" value="yes" |FORCE_SSL_CHECKED|></td>
<td>|LANG_FORCE_SSL_REDIRECT|</td>
<td><input type=submit value='|LANG_SAVE|'></td>
</tr>
</form>
</table>
where it uses the same action=private_html
form, but really has nothing to do with the symbolic link since both radio buttons are excluded from the form.
force_ssl
Template changes regarding Changed templates include:
/usr/local/directadmin/data/templates/ --
virtual_host2.conf
virtual_host2_sub.conf
nginx_server.conf
nginx_server_sub.conf
which now include the added token:
|FORCE_SSL_REDIRECT|
which, if set in the Domain Setup for that domain, will be filled with either:
SetEnvIf X-Forwarded-Proto \"https\" HTTPS=on
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP:X-Forwarded-Proto} !https [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
OR
if ($http_x_forwarded_proto != 'https') {
return 301 https://$host$request_uri;
}
See related section How to redirect example.com to www.example.com for more information regarding this implementation and how it relates to the www/non-www redirection feature.
OLD Guide
The below guide is for reference only.
If you want to force a given website or path to use https and www, redirected from http, use the outlined instructions below.
First rewrite any request to the wrong domain to use the correct one (which is www.
in this case), and then do check if non-https were used.
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
For a simple http to https redirect, use a Force SSL with https redirect checkbox in the DA User panel > Domain Management.
If your site is running through CloudFlare, your https requests to it may actually hit your server in plaintext (http), which is confusing.
For that case, you might need something like this for an http to https redirect:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
where the only usable header is X-Forwarded-Proto
, because the %{HTTPS} variable is "off" for requests from the CloudFlare network.
How to force redirecting to https for all domains
See this guide for using the force_ssl
option for domains, and see this option for implementing this globally for all domains. If you need to force SSL for webapps, see this option.
Old Guide
- Create the global file
/usr/local/directadmin/data/templates/custom/cust_httpd.CUSTOM.pre
and insert code:
|?SSL_REDIRECT_HOST=www.`DOMAIN`|
|*if SUB|
|?SSL_REDIRECT_HOST=`SUB`.`DOMAIN`|
|*endif|
|*if SSL_TEMPLATE="1"|
|?SSL_REDIRECT_HOST=|
|*endif|
This will set what we want to redirect to, and set the redirect to nothing if it's an SSL VirtualHost.
- Next, we want to actually use the variable, so create the file
/usr/local/directadmin/data/templates/custom/cust_httpd.CUSTOM.post
and add code:
|*if SSL_REDIRECT_HOST!=""|
Redirect / https://|SSL_REDIRECT_HOST|/
|*endif|
- If you want to disable this for any domain, go to Admin Level -> Custom Httpd Config -> domain.com and in the CUSTOM token textarea, add this text
|?SSL_REDIRECT_HOST=|
which makes the variable blank, so it's not used.
- Lastly, rewrite the configs to apply the changes:
cd /usr/local/directadmin/custombuild
./build rewrite_confs
How to enable HSTS
For added security, you can tell all clients to always use https, even if there is an http link from somewhere. HSTS will silently change the request to use https without needing to be asked, so at no point is http ever used (except on the first attempt, where the browser is given the header, then never asks again). To set up HSTS, add this to your public_html/.htaccess
file:
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Note: This means you cannot connect to http again, even if you wanted to, so this usually only applies to sites that only ever use https, and never want http.
How to forward a website to another url
There are several ways to accomplish this task.
- Use an .htaccess file in the public_html directory. Sample contents:
Redirect 301 / http://whereyouwant.com/to/go.html
OR
- Create an index.php file in public_html directory with the code:
<?php
header("Location: http://whereyouwant.com/to/go.html");
?>
Where http://whereyouwant.com/to/go.html is the location that you want the page to forward to. You can use local values, i.e., /page.html
, or full urls as in the above example (http://... etc.)
.htaccess: Option FollowSymLinks not allowed here
Related thread:
https://forum.directadmin.com/showthread.php?t=42332
For security reasons, FollowSymLinks is disabled by default.
To prevent this, either:
Remove
FollowSymLinks
from your .htaccess file. It can be replaced withSymLinksIfOwnerMatch
.Or use the patch method instead, which allows
FollowSymLinks
, but replaces itwithSymLinksIfOwnerMatch
internally, so clients don't need to adjust anything (we will likely use this as the default in the future).
cd /usr/local/directadmin/custombuild
./build set harden_symlinks_patch yes
./build set secure_htaccess no
./build apache
./build rewrite_confs
Hotlink protection. How to prevent people from stealing your files
Add hotlink protection, so that other websites can not load images hosted on your website.
Create an .htaccess file with the following code:
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?domain.com.*$ [NC]
RewriteCond %{HTTP_REFERER} !^http://(www.)?domain2.com.*$ [NC]
RewriteRule .(gif|jpg)$ - [F]
Where the logic reads
- If the referer is not blank
- and is not domain.com
- and is not domain2.com
- and is accessing a gif or jpg
- Then [F]orbid the request.
Where you can add more domains in a similar manner, as needed. Similar file types could also be added as well.
How to restrict IP access to an Apache directory
If you have a path with sensitive data that you don't want to be public, you can restrict the path to only be accessible by your own IP address using an .htaccess file.
Create the .htaccess file in the path you'd like to protect. Add this code, where you'd replace 12.34.56.78 with your own IP (Apache 2.4+):
<Limit GET POST>
Require all denied
Require ip 12.34.56.78
</Limit>
<Limit PUT DELETE>
Require all denied
</Limit>
Other variations of this are possible. Google should have many guides on it.
Search engine crawlers are increasing system load
Since a search engine like Google needs to parse your website to determine what to search for, this can often cause a high load on your system if the crawl is done in a short amount of time and if your site has a lot of data.
By creating a robots.txt file in your public_html folder, you can instruct these crawlers to slow down.
A sample robots.txt might look like this:
User-agent: *
Crawl-delay: 300
Which tells all crawlers to wait 300 seconds before each request.
Without it, a crawler might make multiple requests per second, thus increasing your system load.
How to set webalizer/awstats to be available by default
If you want webalizer or awstats pages to be available by default for new domains, you can do so by creating the /usr/local/directadmin/scripts/custom/domain_create_post.sh
file and adding the code below:
#!/bin/sh
ln -s ../stats /home/$username/domains/$domain/public_html/stats
exit 0;
Make it executable:
chmod 755 /usr/local/directadmin/scripts/custom/domain_create_post.sh
If you want it to be for awstats, then change the stats name to be awstats instead.
The /icons/ folder with my website is not working
If you're trying to use /icons
with your website, this is reserved for Apache. It's used for the icons/images
, such as the folder icons
with an Apache directory listing.
If possible, use a different path for your website.
If you cannot get around it, then edit /etc/httpd/conf/extra/httpd-autoindex.conf
to remove or rename the Alias:
Alias /icons/ "/var/www/icons/"
This will break the Apache icons, but most people won't even notice.
Adding security headers to get an A+ rating
When a visitor opens a site in their browser, the server responds with HTTP Response Headers in addition to the actual site's content. These headers communicate rules to the browser regarding what is allowed when interacting with the website, and therefore are a fundamental component of a website's overall security posture. They work in tandem with the browser to protect you against a variety of common attacks. These headers can be constructed to protect against XSS, code injection, clickjacking, etc.
They are not set by default and have to be configured. Often they are set in .htaccess
files on a per-domain basis. Online tools like https://securityheaders.com can be used to scan your site and determine which security headers do/don't exist. SecurityHeaders.com also provides you with a brief description on every header and its purpose.
You may apply security headers to all domains at once by modifying users' VirtualHosts with a custom template. For example:
Create the
/usr/local/directadmin/data/templates/custom/cust_httpd.CUSTOM.post
filePost the code:
<IfModule mod_headers.c>
Header always set X-Content-Type-Options "nosniff"
<FilesMatch "\.(php|html)$$">
Header always unset X-Powered-By
Header unset X-Powered-By
Header set X-Frame-Options "SAMEORIGIN"
Header set X-XSS-Protection "1"
Header set X-Download-Options "noopen"
Header set X-Permitted-Cross-Domain-Policies "master-only"
Header set X-DNS-Prefetch-Control "on"
Header set Referrer-Policy "no-referrer-when-downgrade"
Header set Strict-Transport-Security "max-age=31536000" env=HTTPS
Header set Content-Security-Policy "block-all-mixed-content"
Header Set Permissions-Policy 'geolocation=*, midi=(), sync-xhr=(self "https://|DOMAIN|" "https://www.|DOMAIN|"), microphone=(), camera=(), magnetometer=(), gyroscope=(), payment=(), fullscreen=(self "https://|DOMAIN|" "https://www.|DOMAIN|")'
</FilesMatch>
</IfModule>
- And rewrite configs:
cd /usr/local/directadmin/custombuild/
./build rewrite_confs
Note: Any header may be unset for a particular domain by modifying that domain's .htaccess accordingly. The following example would unset the X-Frame-Options header for a single domain existing on a server where this header had been enabled globally:
Header always unset X-Frame-Options