Protect Sonatype Server Products against Weak Diffie-Hellman Keys and Logjam

<TABLE OF CONTENTS>

What is the Logjam Attack?

The so-called LogJam is an attack vector against server products that expose weak SSL connections using Diffie-Hellman (DH) key exchange.

A detailed explanation of the attack is outlined at https://weakdh.org/ .

How to check for Logjam Vulnerabilities on the Command Line

Use nmap version 7 or greater

nmap --script ssl-enum-ciphers -p 443 www.example.com

Look for warnings and C or below-rated ciphers present in the output, as bolded in the example output below:

> nmap --script ssl-enum-ciphers -p 8443 192.168.2.73

Starting Nmap 7.60 ( https://nmap.org ) at 2018-02-02 14:29 AST
Nmap scan report for 192.168.2.73
Host is up (0.00025s latency).

PORT     STATE SERVICE
8443/tcp open  https-alt
| ssl-enum-ciphers: 
|   TLSv1.0: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256k1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256k1) - C
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.1: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256k1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256k1) - C
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|   TLSv1.2: 
|     ciphers: 
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (secp256k1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (secp256k1) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (secp256k1) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (dh 1024) - A
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (secp256k1) - C
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA (rsa 2048) - C
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (dh 1024) - D
|     compressors: 
|       NULL
|     cipher preference: server
|     warnings: 
|       64-bit block cipher 3DES vulnerable to SWEET32 attack
|       Key exchange (dh 1024) of lower strength than certificate key
|_  least strength: D

Nmap done: 1 IP address (1 host up) scanned in 0.71 seconds

Protecting On-premise Sonatype Server Products

The LogJam attack is only applicable to TLS connections.

If you only terminate TLS connections at a reverse proxy/load balancer in front of a Sonatype server product, then please consult with your IT department to protect against this attack. In this case, no adjustments to Sonatype Platform products are needed. A sampling of how to configure common server products is found elsewhere.

If you terminate TLS connections inside a Sonatype server product then please follow our recommendations below.

Use Modern, Secure Cipher Suites

Configure Nexus Repository 3

  1. Identify the Java specific names of cipher suites you want to exclude. These names are NOT the same as one might see using nmap.

    To make identification of cipher names easier, while Nexus Repository is running, go to Administration -> Loggers. Add a new logger named org.eclipse.jetty.util.ssl and set its log level to DEBUG. Then restart Nexus Repository.

    On startup inside the nexus.log, Jetty will print a log line which will list all the SSL cipher names it is using ( after filters are applied) and all the cipher names it knows about. 

  2. Edit <application-directory>/etc/jetty/jety-https.xml file.
  3. Follow the Eclipse Jetty documentation for Jetty 9.x to add exclusions to the shipped default SslContextFactory included in jetty-https.xml.

    For example here is a sample modification ( in bold ) that explicitly excludes cipher suites by a regular expression:

    <New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
      <Set name="KeyStorePath"><Property name="ssl.etc"/>/keystore.jks</Set>
      <Set name="KeyStorePassword">password</Set>
      <Set name="KeyManagerPassword">password</Set>
      <Set name="TrustStorePath"><Property name="ssl.etc"/>/keystore.jks</Set>
      <Set name="TrustStorePassword">password</Set>
      <Set name="EndpointIdentificationAlgorithm"></Set>
      <Set name="NeedClientAuth"><Property name="jetty.ssl.needClientAuth" default="false"/></Set>
      <Set name="WantClientAuth"><Property name="jetty.ssl.wantClientAuth" default="false"/></Set>
      <!-- <Set name="ExcludeCipherSuites">
        <Array type="String">
          <Item>SSL_RSA_WITH_DES_CBC_SHA</Item>
          <Item>SSL_DHE_RSA_WITH_DES_CBC_SHA</Item>
          <Item>SSL_DHE_DSS_WITH_DES_CBC_SHA</Item>
          <Item>SSL_RSA_EXPORT_WITH_RC4_40_MD5</Item>
          <Item>SSL_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
          <Item>SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA</Item>
          <Item>SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA</Item>
        </Array>
      </Set> -->
      <Call name="addExcludeCipherSuites">
        <Arg>
          <Array type="String">
            <Item>.*NULL.*</Item>
            <Item>.*RC4.*</Item>
            <Item>.*MD5.*</Item>
            <Item>.*DES.*</Item>
            <Item>.*DSS.*</Item>
          </Array>
        </Arg>
      </Call>
    </New>

  4. Restart repository manager

Use a Strong Diffie-Hellman Group

Note: As of Java™ SE Development Kit 8, Update 161 (JDK 8u161 - January 16, 2018 ) a change updates the JDK providers to use 2048 bits as the default key size for DSA instead of 1024 bits when applications have not explicitly initialized the java.security.KeyPairGenerator and java.security.AlgorithmParameterGenerator objects with a key size. This does not mean that using 1024 bits is disabled.

Sonatype Platform products are written in Java and run inside the JVM. The JVM has a system property that can set a fixed minimum ephemeral DH key size of the specified value, in bits, to be used for non-exportable cipher suites. The default Java value is 1024 bits ( in Oracle Java versions prior to 8u161 ) which is too low to protect against attack.

Setting the Java system property can be specified as an argument to the java executable:

java -Djdk.tls.ephemeralDHKeySize=2048 ...

Configure Nexus Repository 3

As of Nexus Repository 3.30.0, this protection is already included by default.

For older Nexus Repository 3 versions:

  1. Verify Nexus Repository 3 is terminating TLS connections directly.
  2. Edit <application-dir>/bin/nexus.vmoptions
  3. Add a new line containing:

    -Djdk.tls.ephemeralDHKeySize=2048

  4. Restart Nexus Repository 3

Configure Sonatype IQ Server

  1. Verify Sonatype IQ Server is terminating TLS connections directly.
  2. Locate the custom service script used to execute the java command which launches the server
  3. Add a java executable argument to the java command:

    -Djdk.tls.ephemeralDHKeySize=2048
  4. Restart Sonatype IQ Server

Configure Nexus Repository 2

As of Nexus Repository 2.15.0, this protection is already included by default.

  1. Verify Nexus Repository is terminating TLS connections directly.
  2. Edit <application-dir>/bin/jsw/conf/wrapper.conf
  3. Find the last uncommented ( no # at the beginning ) line which specifies wrapper.java.additional.n and where n is a number - make note of the highest number used.

    For example by default you might see:

    # Additional JVM parameters (tune if needed, but match the sequence of numbers!)
    wrapper.java.additional.1=-XX:MaxPermSize=192m
    wrapper.java.additional.2=-Djava.io.tmpdir=./tmp
    wrapper.java.additional.3=-Djava.net.preferIPv4Stack=true
    wrapper.java.additional.4=-Dcom.sun.jndi.ldap.connect.pool.protocol="plain ssl"
    wrapper.java.additional.4.stripquotes=TRUE
    #wrapper.java.additional.5=-Xdebug


    In that example, you would modify the file to be:

    # Additional JVM parameters (tune if needed, but match the sequence of numbers!)
    wrapper.java.additional.1=-XX:MaxPermSize=192m
    wrapper.java.additional.2=-Djava.io.tmpdir=./tmp
    wrapper.java.additional.3=-Djava.net.preferIPv4Stack=true
    wrapper.java.additional.4=-Dcom.sun.jndi.ldap.connect.pool.protocol="plain ssl"
    wrapper.java.additional.4.stripquotes=TRUE
    wrapper.java.additional.5=-Djdk.tls.ephemeralDHKeySize=2048
    #wrapper.java.additional.5=-Xdebug

  4. Restart Nexus Repository
Have more questions? Submit a request

0 Comments

Article is closed for comments.