菜单

Apache SSL in htaccess examples

2011年10月7日 - htaccess

Apache SSL examples in htaccess files

Any htaccess rewrite examples should always begin with

Options +FollowSymLinks
RewriteEngine On
RewriteBase /

Fixing double-login problem and making sure authorization usernames/passwords are not sent in cleartext unencrypted.

Additional https/ssl information

SSLOptions +StrictRequire
SSLRequireSSL
SSLRequire %{HTTP_HOST} eq "google.com"
ErrorDocument 403 https://google.com

This code is really, really nice because it fixes multiple issues with almost every other SSL redirect technique in htaccess files. (I discovered this one on my own)

The problem with most techniques is REWRITING the URL.. so if you check the request to see if its being sent on port 443… guess what? in the interim it got sent! Most of the times the double login prompt error happens because users type in http://secureurl.com instead of https://secureurl.com. Most modern browsers automatically request the /favicon.ico file from the resource. In this case the resource is http instead of https like it should be.

Now with some of the other techniques below you can solve this problem, but you will still face a potential ssl security issue. What if a user types in https://secureurl.com:80 There are a lot of these types of weird ways to bypass security so I recommend using the SSLRequireSSL option always.

This will check to make sure that the connection IS using SSL, or it will fail. This works regardless of if your serving SSL on port 443, 80, 81, etc. This is the most secure setting for SSL logins.

This also fixes having to type in the username and password twice by requiring the HTTP_HOST to match the HTTP_HOST that your SSL certificate is set-up for, in the case above, the SSL is for https://google.com not https://www.google.com

If any of the required conditions are not met the server returns a 403 Forbidden Status Code (before mod_rewrite starts) and the ErrorDocument directive catches the 403 to send the visitor a Redirect to https://google.com

Rewrite non-https requests to https without mod_ssl!

Depending upon the HTTPS variable

The HTTPS variable is always present, even if mod_ssl isn’t loaded!

RewriteCond %{HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Based upon the SERVER_PORT

The SERVER_PORT variable is always present, and generally SSL runs on certain ports like 443.

RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]

Redirect everything served on port 80 to SSL

RewriteCond %{SERVER_PORT} ^80$
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]

Redirect particular URLs to a secure version in an SSL SEO method

RewriteRule ^/normal/secure(/.*) https://%{HTTP_HOST}$1 [R=301,L]

Check to see whether the HTTPS environment variable is set

RewriteCond %{HTTPS} !=on
RewriteRule ^(/secure/.*) https://%{HTTP_HOST}$1 [R=301,L]

Use the Redirect directive to cause a URL to be served as HTTPS

Article: Redirect

302 (temp) Redirect

Redirect / https://google.com/

SEO friendly 301 (permanent) redirect

Redirect 301 / https://google.com/

Changing to SSL or NON-SSL using relative URLs

This lets you use hyperlinks of the form

/document.html:SSL -- https://google.com/document.html /document.html:NOSSL -- http://google.com/document.html

RewriteRule ^/(.*):SSL$   https://%{SERVER_NAME}/$1 [R,L]
RewriteRule ^/(.*):NOSSL$ http://%{SERVER_NAME}/$1 [R,L]

Custom Log Formats

When mod_ssl is built into Apache or at least loaded (under DSO situation) additional functions exist for the Custom Log Format of mod_log_config. First there is an additional %{varname} extension format function which can be used to expand any variables provided by any module, especially those provided by mod_ssl which can you find in the above table.

For backward compatibility there is additionally a special %{name} cryptography format function provided. Information about this function is provided in the Compatibility chapter.

CustomLog logs/ssl_request_log   "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"

SSLEngine Directive

This directive toggles the usage of the SSL/TLS Protocol Engine. This is usually used inside a section to enable SSL/TLS for a particular virtual host. By default the SSL/TLS Protocol Engine is disabled for both the main server and all configured virtual hosts.

SSLEngine Example

SSLEngine on

SSLOptions Directive

This directive can be used to control various run-time options on a per-directory basis. Normally, if multiple SSLOptions could apply to a directory, then the most specific one is taken completely; the options are not merged. However if all the options on the SSLOptions directive are preceded by a plus (+) or minus (-) symbol, the options are merged. Any options preceded by a + are added to the options currently in force, and any options preceded by a – are removed from the options currently in force.

Available options

SSLOptions Example

SSLOptions +FakeBasicAuth -StrictRequire +StdEnvVars +CompatEnvVars -ExportCertData

SSLRequire Directive

This directive specifies a general access requirement which has to be fulfilled in order to allow access. It’s a very powerful directive because the requirement specification is an arbitrarily complex boolean expression containing any number of access checks.

This function takes one string argument and expands to the contents of the file. This is especially useful for matching this contents against a regular expression, etc. Notice that expression is first parsed into an internal machine representation and then evaluated in a second step. Actually, in Global and Per-Server Class context expression is parsed at startup time and at runtime only the machine representation is executed. For Per-Directory context this is different: here expression has to be parsed and immediately executed for every request.

SSLRequire htaccess example

SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)-/ \
            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/

SSLRequireSSL Directive

This directive forbids access unless HTTP over SSL (i.e. HTTPS) is enabled for the current connection. This is very handy inside the SSL-enabled virtual host or directories for defending against configuration errors that expose stuff that should be protected. When this directive is present all requests are denied which are not using SSL. Example SSLRequireSSL

SSLUserName Directive

This directive sets the “user” field in the Apache request object. This is used by lower modules to identify the user with a character string. In particular, this may cause the environment variable REMOTE_USER to be set. The varname can be any of the SSL environment variables.

SSLUserName usage example

SSLUserName SSL_CLIENT_S_DN_CN

SSLVerifyClient Directive

This directive sets the Certificate verification level for the Client Authentication. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the client authentication process used in the standard SSL handshake when a connection is established. In per-directory context it forces a SSL renegotation with the reconfigured client verification level after the HTTP request was read but before the HTTP response is sent.

The following levels are available for level:

In practice only levels none and require are really interesting, because level optional doesn’t work with all browsers and level optional_no_ca is actually against the idea of authentication (but can be used to establish SSL test pages, etc.)

SSLVerifyClient example

SSLVerifyClient require

SSLVerifyDepth Directive

This directive sets how deeply mod_ssl should verify before deciding that the clients don’t have a valid certificate. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the client authentication process used in the standard SSL handshake when a connection is established. In per-directory context it forces a SSL renegotation with the reconfigured client verification depth after the HTTP request was read but before the HTTP response is sent. The depth actually is the maximum number of intermediate certificate issuers, i.e. the number of CA certificates which are max allowed to be followed while verifying the client certificate. A depth of 0 means that self-signed client certificates are accepted only, the default depth of 1 means the client certificate can be self-signed or has to be signed by a CA which is directly known to the server (i.e. the CA’s certificate is under SSLCACertificatePath), etc.

SSLVerifyDepth example

SSLVerifyDepth 10

SSLCipherSuite Directive

This complex directive uses a colon-separated cipher-spec string consisting of OpenSSL cipher specifications to configure the Cipher Suite the client is permitted to negotiate in the SSL handshake phase. Notice that this directive can be used both in per-server and per-directory context. In per-server context it applies to the standard SSL handshake when a connection is established. In per-directory context it forces a SSL renegotation with the reconfigured Cipher Suite after the HTTP request was read but before the HTTP response is sent.

Algorithms

An SSL cipher specification in cipher-spec is composed of 4 major attributes plus a few extra minor ones

An SSL cipher can also be an export cipher and is either a SSLv2 or SSLv3/TLSv1 cipher (here TLSv1 is equivalent to SSLv3). To specify which ciphers to use, one can either specify all the Ciphers, one at a time, or use aliases to specify the preference and order for the ciphers.

Key Exchange Algorithm
Authentication Algorithm
Cipher Encoding Algorithm
MAC Digest Algorithm
Aliases

Now where this becomes interesting is that these can be put together to specify the order and ciphers you wish to use. To speed this up there are also aliases (SSLv2, SSLv3, TLSv1, EXP, LOW, MEDIUM, HIGH) for certain groups of ciphers. These tags can be joined together with prefixes to form the cipher-spec.

Available prefixes are

A simpler way to look at all of this is to use the openssl ciphers -v command which provides a nice way to successively create the correct cipher-spec string. The default cipher-spec string is ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXPwhich means the following: first, remove from consideration any ciphers that do not authenticate, i.e. for SSL only the Anonymous Diffie-Hellman ciphers. Next, use ciphers using RC4 and RSA. Next include the high, medium and then the low security ciphers. Finally pull all SSLv2 and export ciphers to the end of the list.

$ openssl ciphers -v 'ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP'
NULL-SHA                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=SHA1
NULL-MD5                SSLv3 Kx=RSA      Au=RSA  Enc=None      Mac=MD5
EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
EXP-RC4-MD5             SSLv3 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export
EXP-RC2-CBC-MD5         SSLv2 Kx=RSA(512) Au=RSA  Enc=RC2(40)   Mac=MD5  export
EXP-RC4-MD5             SSLv2 Kx=RSA(512) Au=RSA  Enc=RC4(40)   Mac=MD5  export

SSLCipherSuite Example

SSLCipherSuite RSA:!EXP:!NULL:+HIGH:+MEDIUM:-LOW

mod_ssl Directives External Information

  1. SSLPassPhraseDialog
  2. SSLMutex
  3. SSLRandomSeed
  4. SSLSessionCache
  5. SSLSessionCacheTimeout
  6. SSLEngine
  7. SSLProtocol
  8. SSLCipherSuite
  9. SSLCertificateFile
  10. SSLCertificateKeyFile
  11. SSLCertificateChainFile
  12. SSLCACertificatePath
  13. SSLCACertificateFile
  14. SSLCARevocationPath
  15. SSLCARevocationFile
  16. SSLVerifyClient
  17. SSLVerifyDepth
  18. SSLLog
  19. SSLLogLevel
  20. SSLOptions
  21. SSLRequireSSL
  22. SSLRequire
  23. Additional Features
  24. Environment Variables
  25. Custom Log Formats

Some handy in-page links to help you navigate:

Variables

SSL Related Variables

Standard CGI/1.0 and Apache variables:

HTTP_USER_AGENT        PATH_INFO             AUTH_TYPE
HTTP_REFERER           QUERY_STRING          SERVER_SOFTWARE
HTTP_COOKIE            REMOTE_HOST           API_VERSION
HTTP_FORWARDED         REMOTE_IDENT          TIME_YEAR
HTTP_HOST              IS_SUBREQ             TIME_MON
HTTP_PROXY_CONNECTION  DOCUMENT_ROOT         TIME_DAY
HTTP_ACCEPT            SERVER_ADMIN          TIME_HOUR
HTTP:headername        SERVER_NAME           TIME_MIN
THE_REQUEST            SERVER_PORT           TIME_SEC
REQUEST_METHOD         SERVER_PROTOCOL       TIME_WDAY
REQUEST_SCHEME         REMOTE_ADDR           TIME
REQUEST_URI            REMOTE_USER           ENV:variablename REQUEST_FILENAME

SSL-related variables:

HTTPS                  SSL_CLIENT_M_VERSION   SSL_SERVER_M_VERSION
SSL_CLIENT_M_SERIAL    SSL_SERVER_M_SERIAL
SSL_PROTOCOL           SSL_CLIENT_V_START     SSL_SERVER_V_START
SSL_SESSION_ID         SSL_CLIENT_V_END       SSL_SERVER_V_END
SSL_CIPHER             SSL_CLIENT_S_DN        SSL_SERVER_S_DN
SSL_CIPHER_EXPORT      SSL_CLIENT_S_DN_C      SSL_SERVER_S_DN_C
SSL_CIPHER_ALGKEYSIZE  SSL_CLIENT_S_DN_ST     SSL_SERVER_S_DN_ST
SSL_CIPHER_USEKEYSIZE  SSL_CLIENT_S_DN_L      SSL_SERVER_S_DN_L
SSL_VERSION_LIBRARY    SSL_CLIENT_S_DN_O      SSL_SERVER_S_DN_O
SSL_VERSION_INTERFACE  SSL_CLIENT_S_DN_OU     SSL_SERVER_S_DN_OU
SSL_CLIENT_S_DN_CN     SSL_SERVER_S_DN_CN
SSL_CLIENT_S_DN_T      SSL_SERVER_S_DN_T
SSL_CLIENT_S_DN_I      SSL_SERVER_S_DN_I
SSL_CLIENT_S_DN_G      SSL_SERVER_S_DN_G
SSL_CLIENT_S_DN_S      SSL_SERVER_S_DN_S
SSL_CLIENT_S_DN_D      SSL_SERVER_S_DN_D
SSL_CLIENT_S_DN_UID    SSL_SERVER_S_DN_UID
SSL_CLIENT_S_DN_Email  SSL_SERVER_S_DN_Email
SSL_CLIENT_I_DN        SSL_SERVER_I_DN
SSL_CLIENT_I_DN_C      SSL_SERVER_I_DN_C
SSL_CLIENT_I_DN_ST     SSL_SERVER_I_DN_ST
SSL_CLIENT_I_DN_L      SSL_SERVER_I_DN_L
SSL_CLIENT_I_DN_O      SSL_SERVER_I_DN_O
SSL_CLIENT_I_DN_OU     SSL_SERVER_I_DN_OU
SSL_CLIENT_I_DN_CN     SSL_SERVER_I_DN_CN
SSL_CLIENT_I_DN_T      SSL_SERVER_I_DN_T
SSL_CLIENT_I_DN_I      SSL_SERVER_I_DN_I
SSL_CLIENT_I_DN_G      SSL_SERVER_I_DN_G
SSL_CLIENT_I_DN_S      SSL_SERVER_I_DN_S
SSL_CLIENT_I_DN_D      SSL_SERVER_I_DN_D
SSL_CLIENT_I_DN_UID    SSL_SERVER_I_DN_UID
SSL_CLIENT_I_DN_Email  SSL_SERVER_I_DN_Email
SSL_CLIENT_A_SIG       SSL_SERVER_A_SIG
SSL_CLIENT_A_KEY       SSL_SERVER_A_KEY
SSL_CLIENT_CERT        SSL_SERVER_CERT
SSL_CLIENT_CERT_CHAINn SSL_CLIENT_VERIFY

发表评论

电子邮件地址不会被公开。 必填项已用*标注