merging kerberos pull req. by @arwarw via github
[ach-master.git] / src / practical_settings / webserver.tex
1 %%---------------------------------------------------------------------- 
2 \subsection{Apache}
3
4 Note that any cipher suite starting with EECDH can be omitted, if in doubt.
5 (Compared to the theory section, EECDH in Apache and ECDHE in OpenSSL are
6 synonyms~\footnote{https://www.mail-archive.com/openssl-dev@openssl.org/msg33405.html})
7
8 \subsubsection{Tested with Versions}
9 \begin{itemize*}
10   \item Apache 2.2.22 linked against OpenSSL 1.0.1e, Debian Wheezy
11   \item Apache 2.4.6 linked against OpenSSL 1.0.1e, Debian Jessie
12 \end{itemize*}
13
14 \subsubsection{Settings}
15 Enabled modules \emph{SSL} and \emph{Headers} are required.
16
17 \begin{lstlisting}
18 SSLCertificateFile server.crt
19 SSLCertificateKeyFile server.key
20 SSLProtocol All -SSLv2 -SSLv3 
21 SSLHonorCipherOrder On
22 SSLCompression off
23 # Add six earth month HSTS header for all users...
24 Header add Strict-Transport-Security "max-age=15768000"
25 # If you want to protect all subdomains, use the following header
26 # ALL subdomains HAVE TO support HTTPS if you use this!
27 # Strict-Transport-Security: max-age=15768000 ; includeSubDomains
28
29 SSLCipherSuite '%*\cipherStringB*)'
30 \end{lstlisting}
31
32 \subsubsection{Additional settings}
33 You might want to redirect everything to \emph{https://} if possible. In Apache
34 you can do this with the following setting inside of a VirtualHost environment:
35
36 \begin{lstlisting}
37 <VirtualHost *:80>
38   RewriteEngine On
39   RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [L,R=permanent]
40 </VirtualHost>
41 \end{lstlisting}
42
43 In case you want to catch those old clients that do not support the recommended
44 cipher string (eg. WinXP or Java 6) you might use their inability to understand
45 SNI to create a catchall page with a default SSL server:
46
47 \begin{lstlisting}
48 # Debian: add this to /etc/apache2/ports.conf
49 NameVirtualHost *:443
50 Listen 443
51
52 # this setting is needed to allow non SNI aware clients to connect too
53 SSLStrictSNIVHostCheck off
54
55 # This needs to be the first virtual host entry; on Debian systems put this
56 # in /etc/apache2/sites-enabled/000-default-ssl
57 <VirtualHost *:443>
58     DocumentRoot /var/www/bad-ssl
59     SSLEngine on
60     SSLProtocol All
61     SSLCipherSuite ALL:!ADH:!NULL:!EXPORT:+HIGH:+MEDIUM:+LOW:+SSLv3
62     SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
63     SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
64 </VirtualHost>
65 \end{lstlisting}
66
67 The catchall virtual server needs to be the first server in the config. On the
68 default page you should provide information about upgrading the browser to the
69 user. You also should not use snakeoil certificates (as in the snipplet above)
70 but the very same certificate as you use for the real service. In case you
71 provide several virtual servers via SNI, the certificate for the catchall page
72 needs to include all their names.
73
74 %\subsubsection{Justification for special settings (if needed)}
75
76 \subsubsection{References}
77 \begin{itemize*}
78   \item Apache2 Docs on SSL and TLS: \url{https://httpd.apache.org/docs/2.4/ssl/}
79 \end{itemize*}
80
81
82 \subsubsection{How to test}
83 See appendix \ref{cha:tools}
84
85
86 %%---------------------------------------------------------------------- 
87 \subsection{lighttpd}
88
89 \subsubsection{Tested with Versions}
90 \begin{itemize*}
91   \item lighttpd/1.4.31-4 with OpenSSL 1.0.1e on Debian Wheezy
92   \item lighttpd/1.4.33 with OpenSSL 0.9.8o on Debian Squeeze (note that TLSv1.2 does not work in openssl 0.9.8 thus not all ciphers actually work)
93   \item lighttpd/1.4.28-2 with OpenSSL 0.9.8o on Debian Squeeze (note that TLSv1.2 does not work in openssl 0.9.8 thus not all ciphers actually work)
94 \end{itemize*}
95
96
97 \subsubsection{Settings}
98 \begin{lstlisting}
99 $SERVER["socket"] == "0.0.0.0:443" {
100   ssl.engine  = "enable"
101   ssl.use-sslv2 = "disable"
102   ssl.use-sslv3 = "disable"
103   ssl.pemfile = "/etc/lighttpd/server.pem"
104   ssl.cipher-list = "%*\cipherStringB*)"
105   ssl.honor-cipher-order = "enable"
106   setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=15768000") # six months
107   # use this only if all subdomains support HTTPS!
108   # setenv.add-response-header  = ( "Strict-Transport-Security" => "max-age=15768000; includeSubDomains")
109 }
110 \end{lstlisting}
111
112 Starting with lighttpd version 1.4.29 Diffie-Hellman and Elliptic-Curve Diffie-Hellman key agreement protocols are supported.
113 By default, elliptic curve "prime256v1" (also "secp256r1") will be used, if no other is given.
114 To select special curves, it is possible to set them using the configuration options \verb|ssl.dh-file| and \verb|ssl.ec-curve|.
115 \begin{lstlisting}
116 ssl.dh-file = "/etc/lighttpd/ssl/dh2048.pem"
117 ssl.ec-curve = "secp521r1"
118 \end{lstlisting}
119 Please read section \ref{section:DH} for more information on Diffie Hellman key exchange and elliptic curves.
120
121 \subsubsection{Additional settings}
122 As for any other webserver, you might want to automatically redirect \emph{http://}
123 traffic toward \emph{https://}. It is also recommended to set the environment variable
124 \emph{HTTPS}, so the PHP applications run by the webserver can easily detect,
125 that HTTPS is in use.
126
127 \begin{lstlisting}
128 $HTTP["scheme"] == "http" {
129   # capture vhost name with regex condition -> %0 in redirect pattern
130   # must be the most inner block to the redirect rule
131   $HTTP["host"] =~ ".*" {
132     url.redirect = (".*" => "https://%0$0")
133   }
134   # Set the environment variable properly
135   setenv.add-environment = (
136     "HTTPS" => "on"
137   )
138 }
139 \end{lstlisting}
140
141
142 \subsubsection{Additional information} 
143 The config option \emph{honor-cipher-order} is available since 1.4.30, the
144 supported ciphers depend on the used OpenSSL-version (at runtime). ECDHE has to
145 be available in OpenSSL at compile-time, which should be default. SSL
146 compression should by deactivated by default at compile-time (if not, it's
147 active).
148
149 Support for other SSL-libraries like GnuTLS will be available in the upcoming
150 2.x branch, which is currently under development.
151
152
153 \subsubsection{References} 
154 \begin{itemize*}
155   \item HTTPS redirection: \url{http://redmine.lighttpd.net/projects/1/wiki/HowToRedirectHttpToHttps}
156   \item Lighttpd Docs SSL: \url{http://redmine.lighttpd.net/projects/lighttpd/wiki/Docs\_SSL}
157   \item Release 1.4.30 (How to mitigate BEAST attack) \url{http://redmine.lighttpd.net/projects/lighttpd/wiki/Release-1\_4\_30}
158   \item SSL Compression disabled by default: \url{http://redmine.lighttpd.net/issues/2445}
159 \end{itemize*}
160
161
162 \subsubsection{How to test} 
163 See appendix \ref{cha:tools}
164
165
166 %%---------------------------------------------------------------------- 
167 \subsection{nginx}
168
169 \subsubsection{Tested with Version} 
170 \begin{itemize*}
171   \item 1.4.4 with OpenSSL 1.0.1e on OS X Server 10.8.5
172   \item 1.2.1-2.2+wheezy2 with OpenSSL 1.0.1e on Debian Wheezy
173   \item 1.4.4 with OpenSSL 1.0.1e on Debian Wheezy
174   \item 1.2.1-2.2~bpo60+2 with OpenSSL 0.9.8o on Debian Squeeze (note that TLSv1.2 does not work in openssl 0.9.8 thus not all ciphers actually work)
175 \end{itemize*}
176
177
178 \subsubsection{Settings}
179 \begin{lstlisting}
180 ssl_prefer_server_ciphers on;
181 ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # not possible to do exclusive
182 ssl_ciphers '%*\cipherStringB*)';
183 add_header Strict-Transport-Security max-age=15768000; # six months
184 # use this only if all subdomains support HTTPS!
185 # add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
186 \end{lstlisting}
187
188 If you absolutely want to specify your own DH parameters, you can specify them via
189
190 \begin{lstlisting}
191 ssl_dhparam file;
192 \end{lstlisting}
193
194 However, we advise you to read section \ref{section:DH} and stay with the standard IKE/IETF parameters (as long as they are \textgreater 1024 bits).
195
196 \subsubsection{Additional settings}
197 If you decide to trust NIST's ECC curve recommendation, you can add the following line to nginx's configuration file to select special curves:
198
199 \begin{lstlisting}
200 ssl_ecdh_curve          secp384r1;
201 \end{lstlisting}
202
203 You might want to redirect everything to \emph{https://} if possible. In Nginx you can do this with the following setting:
204
205 \begin{lstlisting}
206 return 301 https://$host$request_uri;
207 \end{lstlisting}
208
209 In case you want to catch those old clients that do not support the recommended
210 cipher string (eg. WinXP or Java 6) you might use their inability to understand
211 SNI to create a catchall page with a default SSL server:
212
213 \begin{lstlisting}
214 server {
215     listen 443 default;
216     listen [::]:443 default ipv6only=on;
217     root /var/www/bad-ssl;
218     index index.html
219     ssl on;
220     ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
221     ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
222
223     ssl_session_timeout 5m;
224
225     ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
226     ssl_ciphers ALL:!ADH:!NULL:!EXPORT:+HIGH:+MEDIUM:+LOW:+SSLv3;
227 }
228 \end{lstlisting}
229
230 The real service then needs to be in its own server definition omitting the
231 \texttt{default} keyword in the \texttt{listen} directive. On the default page
232 you should provide information about upgrading the browser to the user. You
233 should not use snakeoil certificates (as in the snipplet above) but the very
234 same certificate as you use for the real service. In case you provide several
235 virtual servers via SNI, the certificate for the catchall page needs to include
236 all their names.
237
238 \subsubsection{References} 
239 \begin{itemize*}
240   \item \url{http://nginx.org/en/docs/http/ngx_http_ssl_module.html}
241   \item \url{http://wiki.nginx.org/HttpSslModule}
242 \end{itemize*}
243
244 \subsubsection{How to test}
245 See appendix \ref{cha:tools}
246
247
248 %%---------------------------------------------------------------------- 
249 \subsection{MS IIS}
250 \label{sec:ms-iis}
251 \todo{Daniel: add screenshots and registry keys}
252
253
254 \subsubsection{Tested with Version} \todo{Daniel: add tested version}
255
256
257 \subsubsection{Settings}
258 When trying to avoid RC4 and CBC (BEAST-Attack) and requiring perfect
259 forward secrecy, Microsoft Internet Information Server (IIS) supports
260 ECDSA, but does not support RSA for key exchange (consider ECC suite
261 B doubts\footnote{\url{http://safecurves.cr.yp.to/rigid.html}}).
262
263 Since \verb|ECDHE_RSA_*| is not supported, a SSL certificate based on
264 elliptic curves needs to be used.
265
266 The configuration of cipher suites MS IIS will use, can be configured in one
267 of the following ways:
268 \begin{enumerate}
269   \item Group Policy \footnote{\url{http://msdn.microsoft.com/en-us/library/windows/desktop/bb870930(v=vs.85).aspx}}
270   \item Registry
271   \item IIS Crypto~\footnote{\url{https://www.nartac.com/Products/IISCrypto/}}
272 \end{enumerate}
273
274
275 Table~\ref{tab:MS_IIS_Client_Support} shows the process of turning on
276 one algorithm after another and the effect on the supported clients
277 tested using https://www.ssllabs.com.
278
279 \verb|SSL 3.0|, \verb|SSL 2.0| and \verb|MD5| are turned off.
280 \verb|TLS 1.0| and \verb|TLS 2.0| are turned on.
281
282 \begin{table}[h]
283   \centering
284   \small
285   \begin{tabular}{ll}
286     \toprule
287     Cipher Suite & Client \\
288     \midrule
289     \verb|TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256| & only IE 10,11, OpenSSL 1.0.1e \\
290     \verb|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256| & Chrome 30, Opera 17, Safari 6+ \\
291     \verb|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA| & FF 10-24, IE 8+, Safari 5, Java 7\\
292     \bottomrule 
293   \end{tabular}
294   \caption{Client support}
295   \label{tab:MS_IIS_Client_Support}
296 \end{table}
297
298 Table~\ref{tab:MS_IIS_Client_Support} shows the algorithms from
299 strongest to weakest and why they need to be added in this order. For
300 example insisting on SHA-2 algorithms (only first two lines) would
301 eliminate all versions of Firefox, so the last line is needed to
302 support this browser, but should be placed at the bottom, so capable
303 browsers will choose the stronger SHA-2 algorithms.
304
305 \verb|TLS_RSA_WITH_RC4_128_SHA| or equivalent should also be added if
306 MS Terminal Server Connection is used (make sure to use this only in a
307 trusted environment). This suite will not be used for SSL, since we do
308 not use a RSA Key.
309
310 % \verb|TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256| ... only supported by: IE 10,11, OpenSSL 1.0.1e
311 % \verb|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256| ... Chrome 30, Opera 17, Safari 6+
312 % \verb|TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA| ... Firefox 10-24, IE 8+, Safari 5, Java 7
313
314 Clients not supported:
315 \begin{enumerate}
316   \item Java 6
317   \item WinXP
318   \item Bing
319 \end{enumerate}
320
321
322 \subsubsection{Additional settings}
323 %Here you can add additional settings
324
325
326 \subsubsection{Justification for special settings (if needed)}
327 % in case you have the need for further justifications why you chose this and that setting or if the settings do not fit into the standard Variant A or Variant B schema, please document this here
328
329
330 \subsubsection{References}
331 \todo{add references}
332
333 % add any further references or best practice documents here
334
335
336 \subsubsection{How to test}
337 See appendix \ref{cha:tools}
338
339 %%% Local Variables: 
340 %%% mode: latex
341 %%% TeX-master: "../applied-crypto-hardening"
342 %%% End: