Project

General

Profile

Feature #2856

ssl.openssl.ssl-conf-cmd Not used if placed within $SERVER configuration part

Added by Hinterwaeldlers 9 months ago. Updated 9 months ago.

Status:
Invalid
Priority:
Normal
Assignee:
-
Category:
TLS
Target version:
-
Start date:
2018-01-12
Due date:
% Done:

0%

Estimated time:
Missing in 1.5.x:

Description

Hi,
after an upgrade to V1.4.48 to allow the usage of ssl.openssl.ssl-conf-cmd, I've noticed, that it is only taken into account, if placed into the global configuration space. As the other ssl configuration parts seem to be only used, if they are placed in the related $SERVER part this doesn't seem to be consistent.

In addition some configuration might want to use a solution, where a per $SERVER configuration is wanted to be done (even if I am not sure if this is relevant).
Anyhow this is confusing, where the configuration parts have to be placed.

Workig config file:

ssl.use-sslv2 = "disable" 
ssl.use-sslv3 = "disable" 
ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")

$SERVER["socket"] == "[::]:443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
}

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
}

Not working configurtion:

Workig config file:
ssl.use-sslv2 = "disable" 
ssl.use-sslv3 = "disable" 

$SERVER["socket"] == "[::]:443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}

lighttpd.conf (1.05 KB) lighttpd.conf Hinterwaeldlers, 2018-01-15 07:17
10-name.conf (321 Bytes) 10-name.conf Hinterwaeldlers, 2018-01-15 07:17
mimetypes.conf (2.31 KB) mimetypes.conf Hinterwaeldlers, 2018-01-15 07:17
port.conf (501 Bytes) port.conf Option part discussed above Hinterwaeldlers, 2018-01-15 07:17

History

#1

Updated by gstrauss 9 months ago

  • Tracker changed from Bug to Feature
  • Category set to TLS

The feature was introduced in c09acbeb and documents that "lighttpd processes this directive after all other ssl.* directives have been applied for the $SERVER["socket"] scope."

after an upgrade to V1.4.48 to allow the usage of ssl.openssl.ssl-conf-cmd, I've noticed, that it is only taken into account, if placed into the global configuration space. As the other ssl configuration parts seem to be only used, if they are placed in the related $SERVER part this doesn't seem to be consistent.

In addition some configuration might want to use a solution, where a per $SERVER configuration is wanted to be done (even if I am not sure if this is relevant). Anyhow this is confusing, where the configuration parts have to be placed.

lighttpd config historically does not merge configurations from larger scopes into smaller scopes. I have special-cased some newer directives to inherit from the global scope into the $SERVER["socket"] scope, but still not to merge. A lighttpd option in a smaller scope, e.g. $SERVER["socket"] scope, with a ssl.openssl.ssl-conf-cmd replaces ssl.openssl.ssl-conf-cmd in the global scope (if present).

Would you please be more specific about what you think is not working? Is the config you provided the one that you tested? The cut-n-paste in the Description above seems to be misleading, as you included "Workig config file:" [sic] twice.

#2

Updated by gstrauss 9 months ago

  • Status changed from New to Missing Feedback

"I am confused" questions should not be asked in the bug tracker. Questions should be asked in the forums:
https://redmine.lighttpd.net/projects/lighttpd/boards/2

SSL/TLS works on a socket. The configuration is per $SERVER["socket"]. The simplest answer is to put all ssl.* directive exactly in the $SERVER["socket"] socket, not in a higher scope or sub-scope. However, if ssl.engine = "enable" in global scope, then other ssl.* directives can be in global scope, too. ssl.use-sslv2 and ssl.use-sslv3 are historical config options and must be in exactly $SERVER["socket"] scope, or can be in global scope if ssl.engine = "enable".

ssl.openssl.ssl-conf-cmd can be in exactly $SERVER["socket"] scope, and can also be in global scope even if ssl.engine = "enable" is not set. That is only because I wrote this directive as a new directive and added that enhancement. I can not do that for historical config directives since it might break existing configs.

#3

Updated by gstrauss 9 months ago

One more thing: when server is built with openssl supporting SNI extension, then ssl.pemfile and some other directives can be in $HTTP["host"] scope.

#4

Updated by Hinterwaeldlers 9 months ago

Yes those two parts are configuration variants I was using, at least some parts of it.

This cuts away all general parts:
- used mods
- document path
- file paths (pid, log, cache, ...)
- mimetype configuration
- fastcgi configuration
I will append those files at the end for completion, but think that they are not relevant for this case in here.

Sorry that I've left the working configuration file text within. As I don't see an edit button in here, I cannot change it : /

lighttpd config historically does not merge configurations from larger scopes into smaller scopes. I have special-cased some newer directives to inherit from the global scope into the $SERVER["socket"] scope, but still not to merge. A lighttpd option in a smaller scope, e.g. $SERVER["socket"] scope, with a ssl.openssl.ssl-conf-cmd replaces ssl.openssl.ssl-conf-cmd in the global scope (if present).

That's exactly my point:
Using ssl.openssl.ssl-conf-cmd within the $SERVER scope is completely omitted. So the following two configuration variants are equivalent:
Var 1

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}

Var 2
$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "/path/to/pem.file
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
}

In both variants, all available openssl protocols are still in use.
Used commands to test the different tls support:
openssl s_client -connect IP:PORT  -tls1
openssl s_client -connect IP:PORT  -tls1_1
openssl s_client -connect IP:PORT  -tls1_2

An all three worked, even the first should not work anymore within the first configuration variant, with ssl.openssl.ssl-conf-cmd.

Therefor I think this is more a bug than a miss-understood feature, as the configuration option is not working, if applied locally to a $SERVER scope.

Within the attached files, I've left out the server certificate file and hopefully renamed all file parts accordingly.
The part related to the ssl.use-sslv2 and ssl.use-sslv3 configuration parts, I've read and I'm aware that they might be not in use anymore. As I had no time yet, they are still within configuration as no incorrectness has been noticed so far. But think removing them in a second step is sufficient. Sorry if this makes it harder to read the configurations.

#5

Updated by gstrauss 9 months ago

An all three worked, even the first should not work anymore within the first configuration variant, with ssl.openssl.ssl-conf-cmd.

Please clarify what you mean by "worked". Were you subsequently able to submit an HTTP request using the openssl s_client connection? Or did it close immediately after the connection attempt? Perhaps you are misinterpreting the output of 'openssl s_client'?

Check you lighttpd error log. When attempting to use 'openssl s_client IP:PORT -tls1', which has been disabled with

ssl.openssl.ssl-conf-cmd = ("Protocol" => "-SSLv3,-TLSv1")

I get
SSL: 1 error:1417D102:SSL routines:tls_process_client_hello:unsupported protocol 

and the connection is closed.

#6

Updated by Hinterwaeldlers 9 months ago

By worked, I mean, that the ssl certificate exchange worked, which should not work.

Comparing the output of the command to access:

openssl s_client -connect IP:443 -tls1

Configuration 1:

ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")

$SERVER["socket"] == "[::]:443" {
  ssl.engine = "enable" 
  ssl.pemfile = "path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
}

$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
}

Output:

CONNECTED(00000003)
write:errno=0
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 102 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1516085768
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

So no connection has been established, which is correct

Configuration 2:

$SERVER["socket"] == "[::]:443" {
  ssl.engine = "enable" 
  ssl.pemfile = "path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}
$SERVER["socket"] == ":443" {
  ssl.engine = "enable" 
  ssl.pemfile = "path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}

Output (removed the certificate and the master key, but this should not matter):


CONNECTED(00000003)
depth=0 O = EXAMPLE
verify error:num=18:self signed certificate
verify return:1
depth=0 O = EXAMPLE
verify return:1
---
Certificate chain
 0 s:/O=EXAMPLE
   i:/O=EXAMPLE
---
Server certificate
-----BEGIN CERTIFICATE-----
THE CERTIFICATE WAS REMOVED 
-----END CERTIFICATE-----
subject=/O=EXAMPLE
issuer=/O=EXAMPLE
---
No client certificate CA names sent
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1416 bytes and written 240 bytes
Verification error: self signed certificate
---
New, TLSv1.0, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: C8F6D7207AFADF15BD3F3DE34BACDD3AC315D1D95264ACB8322678811A785179
    Session-ID-ctx:
    Master-Key: MASTER_KEY_VALUE
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 7200 (seconds)
    TLS session ticket:
    0000 - 30 00 9f 3f 47 00 ae e8-55 23 1c ee 1c ae 1a c1   0..?G...U#......
    0010 - 7a bf 07 64 1a 16 84 5e-c4 37 cb ad 01 a1 04 fc   z..d...^.7......
    0020 - 0b 6c 6b 22 ec 44 b9 d6-f1 71 5f 19 1e 69 42 20   .lk".D...q_..iB
    0030 - 07 13 6b 3b 36 cf 94 c9-99 e8 18 68 e9 c5 c2 7d   ..k;6......h...}
    0040 - f8 85 bd 8e f0 76 a4 b8-34 c9 0e 03 f1 0a 5f 49   .....v..4....._I
    0050 - f5 44 88 15 95 62 d3 6e-83 1c 5f 0f 94 64 0e 06   .D...b.n.._..d..
    0060 - 2a 96 44 70 a1 25 14 05-00 37 24 91 d1 4f ed 42   *.Dp.%...7$..O.B
    0070 - f5 bd f0 df 54 e1 97 d2-ee 99 4d 83 9f c6 9a 06   ....T.....M.....
    0080 - 9b 78 2e a5 55 8c 2d d5-e0 70 03 85 be 06 3a 59   .x..U.-..p....:Y
    0090 - 66 67 a2 97 68 3f 16 1b-bd bc 2d 28 ce ee b3 65   fg..h?....-(...e
    00a0 - c8 b2 43 e8 49 48 41 ff-a4 06 79 7d 47 cc 47 0d   ..C.IHA...y}G.G.

    Start Time: 1516086736
    Timeout   : 7200 (sec)
    Verify return code: 18 (self signed certificate)
    Extended master secret: yes
---

So a connection has been established, which is not correct.

Note: I've not tried to access the server using a regular browser, to see what happens

#7

Updated by gstrauss 9 months ago

I am sorry. I am unable to reproduce this. I am not running my tests as root, but that should not matter. Here is my entire test config. Please replace "/path/to/server.pem" and see if you can reproduce the problem on your rig, using lighttpd -D -f /path/to/this/file.conf and then connecting to port 8443 using openssl s_client -connect :8443 -tls1

server.port = 8443
server.document-root = "/www" 

server.modules += ("mod_openssl")

$SERVER["socket"] == "[::]:8443" {
  ssl.engine = "enable" 
  ssl.pemfile    = "/path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}
$SERVER["socket"] == ":8443" {
  ssl.engine = "enable" 
  ssl.pemfile    = "/path/to/server.pem" 
  ssl.cipher-list = "EECDH+AESGCM:EDH+AESGCM:AES128+EECDH:AES128+EDH" 
  ssl.openssl.ssl-conf-cmd = ("Protocol" => "-TLSv1, -SSLv3")
}
#8

Updated by Hinterwaeldlers 9 months ago

I've tested the whole part again on my local computer based on the current git state and cannot reproduce it now, too.

The original test was done one an armv5tejl with the source compiled via the definitions of buildroot (https://git.busybox.net/buildroot/tree/package/lighttpd) and a bumped version to 1.4.48 (LIGHTTPD_VERSION = $(LIGHTTPD_VERSION_MAJOR).48). I will check the related modifications within there and hope to get an idea what happens.

#9

Updated by gstrauss 9 months ago

  • Status changed from Missing Feedback to Invalid
  • Target version deleted (1.4.x)

Thanks for the update. This does not appear to be an issue with the lighttpd source.

However, there are many different linux distributions and packages, which are not maintained by the lighttpd core team. There may be an issue with busybox package or Makefiles which might need more than trivial modification to go from lighttpd 1.4.45 to lighttpd 1.4.48. Please let us know what you find.

Also available in: Atom