net: use a secure cipher list by default
Previously, the `net` module use the blanket "ALL" as the default cipher list. This list may contain security ciphers that are weak and/or outdated according to the current standard. This commit introduces a new module `ssl_config` that contains the latest OpenSSL configurations as recommended by Mozilla OpSec, and make the `net` module use the cipher list targeting `intermediate` compatibility level as the default.
This commit is contained in:
parent
6cb94b5da6
commit
1fb2a58674
5 changed files with 125 additions and 1 deletions
|
|
@ -99,6 +99,15 @@
|
||||||
- `osproc.execCmdEx` now takes an optional `input` for stdin, `workingDir` and `env`
|
- `osproc.execCmdEx` now takes an optional `input` for stdin, `workingDir` and `env`
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
|
- Add `ssl_config` module containing lists of secure ciphers as recommended by
|
||||||
|
[Mozilla OpSec](https://wiki.mozilla.org/Security/Server_Side_TLS)
|
||||||
|
|
||||||
|
- `net.newContext` now uses the list of ciphers targeting
|
||||||
|
["Intermediate compatibility"](https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28recommended.29)
|
||||||
|
per Mozilla's recommendation instead of `ALL`. This change should protect
|
||||||
|
users from the use of weak and insecure ciphers while still provides
|
||||||
|
adequate compatiblity with the majority of the Internet.
|
||||||
|
|
||||||
## Language changes
|
## Language changes
|
||||||
- In the newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:
|
- In the newruntime it is now allowed to assign discriminator field without restrictions as long as case object doesn't have custom destructor. Discriminator value doesn't have to be a constant either. If you have custom destructor for case object and you do want to freely assign discriminator fields, it is recommended to refactor object into 2 objects like this:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ import std/private/since
|
||||||
|
|
||||||
import nativesockets, os, strutils, times, sets, options, std/monotimes
|
import nativesockets, os, strutils, times, sets, options, std/monotimes
|
||||||
from ssl_certs import scanSSLCertificates
|
from ssl_certs import scanSSLCertificates
|
||||||
|
import ssl_config
|
||||||
export nativesockets.Port, nativesockets.`$`, nativesockets.`==`
|
export nativesockets.Port, nativesockets.`$`, nativesockets.`==`
|
||||||
export Domain, SockType, Protocol
|
export Domain, SockType, Protocol
|
||||||
|
|
||||||
|
|
@ -533,7 +534,7 @@ when defineSsl:
|
||||||
raiseSSLError("Verification of private key file failed.")
|
raiseSSLError("Verification of private key file failed.")
|
||||||
|
|
||||||
proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer,
|
proc newContext*(protVersion = protSSLv23, verifyMode = CVerifyPeer,
|
||||||
certFile = "", keyFile = "", cipherList = "ALL",
|
certFile = "", keyFile = "", cipherList = CiphersIntermediate,
|
||||||
caDir = "", caFile = ""): SSLContext =
|
caDir = "", caFile = ""): SSLContext =
|
||||||
## Creates an SSL context.
|
## Creates an SSL context.
|
||||||
##
|
##
|
||||||
|
|
|
||||||
51
lib/pure/ssl_config.nim
Normal file
51
lib/pure/ssl_config.nim
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
# This file was automatically generated by tools/ssl_config_parser on 2020-06-03T22:02:05Z. DO NOT EDIT.
|
||||||
|
|
||||||
|
## This module contains SSL configuration parameters obtained from
|
||||||
|
## `Mozilla OpSec <https://wiki.mozilla.org/Security/Server_Side_TLS>`_.
|
||||||
|
##
|
||||||
|
## The configuration file used to generate this module: https://ssl-config.mozilla.org/guidelines/5.4.json
|
||||||
|
|
||||||
|
const CiphersModern* = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
|
||||||
|
## An OpenSSL-compatible list of secure ciphers for ``modern`` compatibility
|
||||||
|
## per Mozilla's recommendations.
|
||||||
|
##
|
||||||
|
## Oldest clients supported by this list:
|
||||||
|
## * Firefox 63
|
||||||
|
## * Android 10.0
|
||||||
|
## * Chrome 70
|
||||||
|
## * Edge 75
|
||||||
|
## * Java 11
|
||||||
|
## * OpenSSL 1.1.1
|
||||||
|
## * Opera 57
|
||||||
|
## * Safari 12.1
|
||||||
|
|
||||||
|
const CiphersIntermediate* = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"
|
||||||
|
## An OpenSSL-compatible list of secure ciphers for ``intermediate`` compatibility
|
||||||
|
## per Mozilla's recommendations.
|
||||||
|
##
|
||||||
|
## Oldest clients supported by this list:
|
||||||
|
## * Firefox 27
|
||||||
|
## * Android 4.4.2
|
||||||
|
## * Chrome 31
|
||||||
|
## * Edge
|
||||||
|
## * IE 11 on Windows 7
|
||||||
|
## * Java 8u31
|
||||||
|
## * OpenSSL 1.0.1
|
||||||
|
## * Opera 20
|
||||||
|
## * Safari 9
|
||||||
|
|
||||||
|
const CiphersOld* = "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||||
|
## An OpenSSL-compatible list of secure ciphers for ``old`` compatibility
|
||||||
|
## per Mozilla's recommendations.
|
||||||
|
##
|
||||||
|
## Oldest clients supported by this list:
|
||||||
|
## * Firefox 1
|
||||||
|
## * Android 2.3
|
||||||
|
## * Chrome 1
|
||||||
|
## * Edge 12
|
||||||
|
## * IE8 on Windows XP
|
||||||
|
## * Java 6
|
||||||
|
## * OpenSSL 0.9.8
|
||||||
|
## * Opera 5
|
||||||
|
## * Safari 1
|
||||||
|
|
||||||
62
tools/ssl_config_parser.nim
Normal file
62
tools/ssl_config_parser.nim
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# SSL configuration generator
|
||||||
|
# (c) Copyright 2020 Leorize <leorize+oss@disroot.org>
|
||||||
|
#
|
||||||
|
# See the file "copying.txt", included in this
|
||||||
|
# distribution, for details about the copyright.
|
||||||
|
#
|
||||||
|
|
||||||
|
import httpclient, json, net, strformat, strutils, sequtils, times
|
||||||
|
|
||||||
|
const
|
||||||
|
ConfigSource = "https://ssl-config.mozilla.org/guidelines/latest.json"
|
||||||
|
OutputFile = "ssl_config.nim"
|
||||||
|
|
||||||
|
func appendToList(list, str: string): string =
|
||||||
|
if list.len == 0:
|
||||||
|
result = str
|
||||||
|
elif str.len == 0:
|
||||||
|
result = list
|
||||||
|
else:
|
||||||
|
result = list & ':' & str
|
||||||
|
|
||||||
|
proc main() =
|
||||||
|
let
|
||||||
|
client = newHttpClient(sslContext = newContext(verifyMode = CVerifyPeer))
|
||||||
|
resp = client.get(ConfigSource)
|
||||||
|
defer: client.close()
|
||||||
|
if not resp.code.is2xx:
|
||||||
|
quit "Couldn't fetch configuration, server returned: " & $resp.code
|
||||||
|
|
||||||
|
let configs = resp.bodyStream.parseJson("ssl-config.json")
|
||||||
|
|
||||||
|
let generationTime = now().utc()
|
||||||
|
let output = open(OutputFile, fmWrite)
|
||||||
|
echo "Generating ", OutputFile
|
||||||
|
output.writeLine(&"""
|
||||||
|
# This file was automatically generated by tools/ssl_config_parser on {generationTime}. DO NOT EDIT.
|
||||||
|
|
||||||
|
## This module contains SSL configuration parameters obtained from
|
||||||
|
## `Mozilla OpSec <https://wiki.mozilla.org/Security/Server_Side_TLS>`_.
|
||||||
|
##
|
||||||
|
## The configuration file used to generate this module: {configs["href"].getStr}
|
||||||
|
""")
|
||||||
|
|
||||||
|
for name, config in configs["configurations"]:
|
||||||
|
let
|
||||||
|
constantName = "Ciphers" & name[0].toUpperAscii & name[1..^1]
|
||||||
|
ciphers = config["ciphersuites"].foldl(a.appendToList b.getStr, "").appendToList(
|
||||||
|
config["ciphers"]["openssl"].foldl(a.appendToList b.getStr, "")
|
||||||
|
)
|
||||||
|
oldestClients = config["oldest_clients"].foldl(a & "\n ## * " & b.getStr, "")
|
||||||
|
|
||||||
|
output.writeLine(&"""
|
||||||
|
const {constantName}* = "{ciphers}"
|
||||||
|
## An OpenSSL-compatible list of secure ciphers for ``{name}`` compatibility
|
||||||
|
## per Mozilla's recommendations.
|
||||||
|
##
|
||||||
|
## Oldest clients supported by this list:{oldestClients}
|
||||||
|
""")
|
||||||
|
|
||||||
|
when isMainModule: main()
|
||||||
1
tools/ssl_config_parser.nims
Normal file
1
tools/ssl_config_parser.nims
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
--d:ssl
|
||||||
Loading…
Add table
Add a link
Reference in a new issue