Tuesday, August 30, 2016

Ephemeral DH public key size is less than the required minimum

This error appeared for me after upgrading from 8.3.01 to 9.1.0, and not on appliances that were delivered with the newer 9.0.0 image (and patched to 9.1.0).

After running a TCP dump I found that the ciphers used by the gateway for its outbound connection in the client-hello did not match the default list shown in the routing assertion.

I found that upon changing the cipher list for the routing assertion that the client-hello was then correct and the error ceased to appear.

Support was able to clarify the underlying meaning of the error:
"The error relates to the Diffie-Hellman (DH) keys of sizes less than 1024 bits are deprecated because of their insufficient strength that is being presented to the Gateway.  There was changing JAVA along the way that disabled supported key size. (https://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html )

Support stronger ephemeral DH keys in the SunJSSE provider: Make ephemeral DH key match the length of the certificate key during SSL/TLS handshaking in the SunJSSE provider. A new system property, jdk.tls.ephemeralDHKeySize, is defined to customize the ephemeral DH key sizes. The minimum acceptable DH key size is 1024 bits, except for exportable cipher suites or legacy mode (jdk.tls.ephemeralDHKeySize=legacy). See Customizing Size of Ephemeral DH Keys and REF 6956398."

Ultimately the reason that the solution of changing the list worked is because:

  1. The cipher list being used when 'default' is selected is not actually what is indicated
    • My preference is to go to the bottom of the list and move the two SSL ciphers to the bottom of the checked list, this reordering is sufficient to cause the gateway to use what it says.
  2. The list that is actually being used by default has DHE ciphers prioritized over ECDHE (unlike the list indicted within the routing assertion)
    • Because the gateway is the client it controls the negotiation and therefore setting ECDHE ciphers ahead of DHE by minimal alteration to the routing assertions' cipher list may be sufficient to resolve the issue; however, depending on the cipher list available on the backend server you may need to alter the list further.
  3. "Server endpoint is using OLDER versions of SSL libraries (JDK 7, openssl, etc.) than currently supported by CA API Gateway"
    • Which is also why it does not appear for all backend systems, only ones that are not current on their security suites.
Special thanks to CA support for their time and effort in rooting out the cause of this issue.

Saturday, July 30, 2016

The SourceIP Problem (aka The SSL Termination Dilemma)

For any server it is desirable to know the originating IP address of client traffic, even when the network firewall is relied upon for IP filtering.  It is still indispensable in identifying traffic patterns, usage trends, and threat analysis.

The most direct method, I think, is to allocate the server's IP on the same subnet as the load balancer.  This allows the load balancer to forward traffic to the server instead of terminating IP and routing it.  The catch is that the gateway (or server) needs to be smart enough to route the traffic that arrives via the load balancer back out through the load balancer and all other traffic, out bound connections and direct non load balanced traffic, through the network gateway.  There are a few ways to achieve this.

1)  Setup NAT (Network Address Translation) for every IP that the server needs to communicate with directly, and add a hosts file entry where applicable to resolve SSL hostname mismatch errors as necessary.

2)  Setup explicit route entries on the server for targets that it is expected to communicate with directly, in or out bound.  One restriction of this approach is that all IPs communicated with must either go through the load balancer or through the network gateway, not both.

3) Terminate IP traffic at the load balancer and inject x-forwarded-for headers.  The gateway will automatically interpret these headers as the source IP in policy, this approach will however prevent you from seeing the client certificate of the requesters because SSL is being terminated at the load balancer.  But as far as routing goes, the gateway only has to communicate with the network firewall and does not need to be subnet adjacent to the load balancer (not the method I advocate, but frequently used).

4)  Dynamically route the traffic out the load balancer based on the incoming IP and default all other traffic through the network gateway.  This is the best of both worlds because the gateway sees the source IP of all incoming traffic and SSL is not terminated ahead either, this means it can still see the client certificates as well.  Supposedly there is a way to do this using metric and TCP flags, but I find it easier to have two ethernet ports enabled with dynamic routing, which turned out to be much simpler than expected.  This is what I describe in detail below.

You'll need to setup two network interfaces for the gateway (this should work for any linux server really).  One will be used as the default for all traffic (the outbound routing and direct commutations for management/administration), and the other interface will be for all traffic through the load-balancer.

We will use the following addresses for these objects in this example:
192.168.0.1    network.gateway.firewall
192.168.0.11   loadbalancer.local.interface
192.168.0.100  apigateway.eth0.default
192.168.0.101  apigateway.eth1.loadbalanced

You should setup both of these interfaces through the ssgconfig shell script with the network gateway as the gateway for eth0 and the load balancer's local interface as the gateway for eth1, with eth0 and it's gateway as the default when prompted (and restart for changes to take effect).  Then using the following commands from the root shell setup the dynamic routing (these also require another restart to take effect).

echo '252     internal' >> /etc/iproute2/rt_tables
echo 'default via 192.168.0.11 dev eth0 table internal' >> /etc/sysconfig/network-scripts/route-eth0
echo 'from 192.168.0.101 dev eth0 table internal' > /etc/sysconfig/network-scripts/rule-eth1

These will have added a custom route table called 'internal', then setup eth0 on startup to set the 'internal' route table to hold an entry making the system's default gateway to be the load balancer instead of the network gateway when this table is used, and finally eth1 on startup to use a routing rule that says when traffic arrives through eth1 it should use the 'internal' routing table.

Your firewall can block all traffic to the gateway's eth1 since it should only communicate with the load balancer's local interface (which does not have to go through the firewall as it is on the local subnet).  Then eth0 can be made accessible to the other gateways in the cluster and wherever your administrators run policy manager from, as well as whatever other system monitoring is in place.  The gateway's eth0 end up being your source for outbound firewall rules regardless of destination.  The only traffic that will leave the gateway though eth1 will be synchronous responses to incoming traffic from the load balancer (an inbound established connection, not outbound connections).

You can use the following commands to review the rules that are in place.

ip rule show
ip route show
ip route show table internal

Friday, July 29, 2016

OS root account unlock and reset

As many of you know the Gateway is built on top of RedHat Enterprise Linux running on Oracle Fire hardware, so some these procures are specific to vendors and not so much the gateway itself.
This was performed on a hardware appliance, commands for VM vary slightly.

Oracle Integrated Lights-Out Manager root password reset

  1. Connect to the iLOM serial port and login using the 'default' account (see reference for default account password).
  2. You will be prompted to press the physical presence button (located on the back of the server next to the iLOM serial port).
  3. After login is completed you may then change the password for the iLOM 'root' user:
    • set /SP/users/root password
Ref:
http://docs.oracle.com/cd/E24707_01/html/E24528/z400203c1534691.html

RedHat Enterprise Linux root password reset

  1. Connect to the system console and start (or restart if running) the OS.
  2. When prompted press any key to enter the boot loader menu.
  3. Press 'p' to enter the GRUB password (see referenced article for default password).
  4. Press 'e' to edit the kernel boot command.
  5. Select the 'kernel ...' line and press 'e' to edit.
  6. Append to the end of the line:
    • init=/bin/bashAnd if connected to a hardware appliance via the iLOM serial port then also append to the end of the line:
    • console=ttyS0Press Enter to save the changes
    • If you run into issues with the above parameters then the two following parameters may be useful in troubleshooting:
      panic=0
      --system noinitrd
  7. Then press 'b' to boot the kernel with the modified command parameters.
  8. Mount the root file system with the following command:
    • mount -o remount,rw /
  9. Change the root password:
    • passwd
    • Note: your new password should adhere to the system password policy.
  10. Re-mount the root file system with the following command:
    • mount -o remount,ro /
  11. Save the changes and restart the appliance:

    • sync; reboot -f

  12. Note: the above password reset will not unlock the root account
    • but this command will:
      /sbin/pam_tally2 --reset --user root
Ref:
http://www.ca.com/us/support/ca-support-online/product-content/knowledgebase-articles/tec0000001436.aspx

admin password reset

(The most direct way is ssgconfig menu option 2, option 8.  However if that is not working then you may use the following approach.)
(This section copied directly from the referenced article.)
  1. Login into the command shell of a gateway database node.
  2. Elevate to the root account (option 3).
  3. Run the following command:
    • /opt/SecureSpan/Appliance/bin/resetAdmin.sh root [MySQL root account password]
  4. Enter the Admin account name when prompted. This is the Administrative user name that was created when the Gateway was initially configured.
  5. When the script is complete, the password for the Administrative user is reset back to password. You should now log into the Policy Manager and change the password to a more secure password.
Ref:
https://docops.ca.com/ca-api-gateway/9-0/en/troubleshoot/troubleshooting-password-issues#TroubleshootingPasswordIssues-ResettingtheAdministrativePassword

Friday, May 6, 2016

Update Java Key Store with Renewed Client Certificate and Existing Private Key

Convention:
Bold: positive confirmation that the command executed correctly
Italic: do not be alarmed, this may appear to be an error, however it is not
input_prompt: the appropriate information must be entered

Export the old private key from the keystore.
command:
keytool -importkeystore -srckeystore privatekeystore.jks -storepass KeystoreStorePassword -destkeystore old-private.p12 -deststoretype PKCS12 -deststorepass KeystoreStorePassword
output:
(if you have other public certs in the keystore you will be prompted for each)
Problem importing entry for alias trusted.cert.com: java.security.KeyStoreException: TrustedCertEntry not supported.
Entry for alias trusted.cert.com not imported.
Do you want to quit the import process? [no]:  no
Import command completed:  1 entries successfully imported, 1 entries failed or cancelled

Extract the raw RSA key from the old private p12.
command:
openssl pkcs12 -in old-private.p12 -clcerts -nodes -nocerts | openssl rsa > private.key
output:
Enter Import Password: KeystoreStorePassword
MAC verified OK
writing RSA key

Merge the raw RSA key with the renewed certificate to generate the new private key.
command:
openssl pkcs12 -export -des -out new-private.p12 -inkey private.key -in renewed.pem
output:
Enter Export Password: KeystoreStorePassword
Verifying - Enter Export Password: KeystoreStorePassword
unable to write 'random state'

Remove the old private key from the keystore.
command:
keytool -delete -alias private.cert.com -keystore privatekeystore.jks -storepass KeystoreStorePassword
output: (none)

Import the new private key into into the keystore.
command:
keytool -v -importkeystore -srckeystore new-store.p12 -srcstoretype PKCS12 -storepass KeystoreStorePassword -destkeystore privatekeystore.jks -deststoretype JKS -deststorepass KeystoreStorePassword
output:
Entry for alias 1 successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled
[Storing privatekeystore.jks]

Change the alias associated with the private certificate within the keystore.
command:
keytool -changealias -keystore privatekeystore.jks -alias 1 -destalias private.cert.com -storepass KeystoreStorePassword
output: (none)

Validate by listing the certificates in the keystore.
command:
keytool -list -keystore privatekeystore.jks -storepass KeystoreStorePassword
output:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

trusted.cert.com, April 08, 2018, trustedCertEntry,
Certificate fingerprint (MD5): 35:F2:23:68:46:96:A6:38:AA:B2:09:4D:21:F6:9A:47
private.cert.com, May 4, 2016, PrivateKeyEntry,
Certificate fingerprint (MD5): 75:B8:80:C6:99:B7:FC:2B:E4:40:E6:4C:A6:46:66:B9:F3:B2:FA:E2