APISIX: Cumplir con FIPS 140-2
Jinhua Luo
January 6, 2023
¿Qué es FIPS 140-2?
FIPS significa Estándares Federales de Procesamiento de Información, un conjunto de estándares de seguridad informática establecidos por el Instituto Nacional de Estándares y Tecnología (NIST) del Departamento de Comercio de los Estados Unidos.
El objetivo de FIPS es crear un nivel uniforme de seguridad para todas las agencias federales para proteger información sensible pero no clasificada - una gran porción de datos electrónicos que no se consideran secretos o de mayor clasificación.
Niveles de seguridad de FIPS 140-2
FIPS 140-2/3 son estándares frecuentemente utilizados en el contexto de la ciberseguridad. Ambos se relacionan con los requisitos estándar de seguridad para módulos criptográficos. FIPS 140-3 eventualmente reemplazará a FIPS 140-2, y esta transición está actualmente en curso.
- Nivel 1 – El nivel de seguridad más bajo que impone requisitos mínimos y requiere que todos los componentes sean 'de grado de producción'. FIPS 140-2 Nivel 1 se relaciona específicamente con módulos criptográficos de software y establece estipulaciones sobre los algoritmos criptográficos que pueden usarse y las autopruebas que deben realizarse para verificar su integridad.
- Nivel 2 – Requisitos adicionales para evidencia de manipulación física y autenticación basada en roles.
- Nivel 3 – Obligación adicional de fortalecer la seguridad contra atacantes, el uso de autenticación basada en identidad, así como separación física entre interfaces.
- Nivel 4 – El nivel más estricto que requiere medidas de seguridad física robustas contra ataques ambientales.
Por ejemplo, un módulo criptográfico validado en FIPS 140-2 Nivel 1 proporciona ese nivel básico de seguridad al cifrar los datos que pasan a través de él con el nivel de protección proporcionado por AES. Sin embargo, un módulo criptográfico validado en FIPS 140-2 Nivel 2 no solo proporciona cifrado electrónico AES, sino también seguridad física del dispositivo en sí.
Esto significa que un módulo criptográfico validado en FIPS 140-2 Nivel 2 no puede ser manipulado a menos que se rompan los sellos de la carcasa de la solución, en cuyo caso el llamado oficial criptográfico sabrá inmediatamente que la seguridad de la información ha sido comprometida y podrá tomar medidas de inmediato para remediar cualquier violación de datos.
¿Por qué es importante FIPS?
Los módulos criptográficos validados en FIPS 140-2 son requeridos por ley para todas las agencias federales de los Estados Unidos que manejan información sensible pero no clasificada. Y otros sectores industriales están haciendo de FIPS 140-2 Nivel 2 un elemento no negociable para su seguridad de backhaul, incluyendo finanzas, atención médica, servicios legales, operadores móviles e industrias de seguridad pública.
APISIX compatible con FIPS 140-2
¿Cómo ser compatible con FIPS 140-2?
Cuando se usa con una compilación validada de OpenSSL 3.0 en modo FIPS, APISIX cumple con los requisitos de FIPS 140-2 (Nivel 1) en cuanto a la desencriptación y encriptación del tráfico de red cifrado con SSL/TLS.
Influencias
El modo FIPS deshabilita los siguientes cifrados:
- TLS_ECDH_anon_WITH_RC4_128_SHA
- TLS_ECDHE_RSA_WITH_RC4_128_SHA
- TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
- TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
- TLS_RSA_WITH_IDEA_CBC_SHA
- TLS_RSA_WITH_RC4_128_MD5
- TLS_RSA_WITH_RC4_128_SHA
- TLS_RSA_WITH_SEED_CBC_SHA
Además, FIPS no admite claves RSA menores de 2048 bits.
Compilar OpenSSL
Compilar e instalar OpenSSL con FIPS habilitado
apt install -y build-essential
git clone https://github.com/openssl/openssl
cd openssl
./Configure --prefix=/usr/local/openssl-3.0 enable-fips
make install
bash -c "echo /usr/local/openssl-3.0/lib64 > /etc/ld.so.conf.d/openssl3.conf"
ldconfig
/usr/local/openssl-3.0/bin/openssl fipsinstall -out /usr/local/openssl-3.0/ssl/fipsmodule.cnf \
-module /usr/local/openssl-3.0/lib64/ossl-modules/fips.so
sed_expr='s@# .include fipsmodule.cnf@.include /usr/local/openssl-3.0/ssl/fipsmodule.cnf@g;'
sed_expr+=' s/# \(fips = fips_sect\)/\1\nbase = base_sect\n\n[base_sect]\nactivate=1\n/g'
sed -i "$sed_expr" /usr/local/openssl-3.0/ssl/openssl.cnf
bash -c "echo /usr/local/openssl-3.0/lib64 > /etc/ld.so.conf.d/openssl3.conf"
ldconfig
Verificar OpenSSL
Verifique el archivo de configuración (/usr/local/openssl-3.0/ssl/openssl.cnf
).
Asegúrese de que coincida con el siguiente fragmento:
config_diagnostics = 1
openssl_conf = openssl_init
.include /usr/local/ssl/fipsmodule.cnf
[openssl_init]
providers = provider_sect
[provider_sect]
fips = fips_sect
base = base_sect
[base_sect]
activate = 1
Determine si OpenSSL puede realizar hashes SHA1: Esta prueba verifica el funcionamiento correcto de OpenSSL. El algoritmo de hash SHA1 está permitido en todos los modos, por lo que un fallo en este comando indica que la implementación de OpenSSL no funciona correctamente:
# openssl sha1 /dev/null
SHA1(/dev/null)= da39a3ee5e6b4b0d3255bfef95601890afd80709
Determine si OpenSSL puede realizar hashes MD5: Esta prueba verifica que OpenSSL esté ejecutándose en modo FIPS. MD5 no es un algoritmo de hash permitido en modo FIPS, por lo que un intento de usarlo fallará:
# openssl md5 /dev/null
Error setting digest
80920FA8DA7F0000:error:0308010C:digital envelope routines:
inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:341:
Global default library context, Algorithm (MD5 : 100), Properties ()
Si OpenSSL no está ejecutándose en modo FIPS, la función de hash MD5 funciona normalmente:
# /usr/bin/openssl md5 /dev/null
MD5(/dev/null)= d41d8cd98f00b204e9800998ecf8427e
Compilar APISIX con FIPS
# instalar dependencias pcre y zlib
wget -O - https://openresty.org/package/pubkey.gpg | apt-key add -
echo "deb http://openresty.org/package/${arch_path}ubuntu $(lsb_release -sc) main" | \
tee /etc/apt/sources.list.d/openresty.list
apt-get update
apt-get install -y openresty-pcre-dev openresty-zlib-dev
# especificar opciones de compilación y enlace
export zlib_prefix=/usr/local/openresty/zlib
export pcre_prefix=/usr/local/openresty/pcre
export cc_opt="-DNGX_LUA_ABORT_AT_PANIC -I${zlib_prefix}/include -I${pcre_prefix}/include"
cc_opt+="-I/usr/local/openssl-3.0/include"
export ld_opt="-L${zlib_prefix}/lib -L${pcre_prefix}/lib -L/usr/local/openssl-3.0/lib64"
ld_opt+="-Wl,-rpath,${zlib_prefix}/lib:${pcre_prefix}/lib:/usr/local/openssl-3.0/lib64"
# compilar e instalar apisix-base
wget https://raw.githubusercontent.com/api7/apisix-build-tools/master/build-apisix-base.sh
bash build-apisix-base.sh latest
Configurar una ruta de prueba
curl http://127.0.0.1:9180/apisix/admin/routes/httpbin -H 'X-API-KEY: YOUR-KEY' -X PUT -i -d '
{
"uri": "/anything",
"hosts": ["*.httpbin.org"],
"methods": ["GET"],
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'
Probar la validación de clave privada
Prueba de caso normal, esperamos que sea exitosa.
Cree un script auxiliar en Python para subir el certificado:
cfg_ssl.py
import sys
import requests
if len(sys.argv) <= 3:
print("bad argument")
sys.exit(1)
with open(sys.argv[1]) as f:
cert = f.read()
with open(sys.argv[2]) as f:
key = f.read()
sni = sys.argv[3]
api_key = "edd1c9f034335f136f87ad84b625c8f1"
resp = requests.put("http://127.0.0.1:9180/apisix/admin/ssls/1", json={
"cert": cert,
"key": key,
"snis": [sni],
}, headers={
"X-API-KEY": api_key,
})
print(resp.status_code)
print(resp.text)
Cree una función en bash para facilitar la generación de claves:
genkey() {
keylen=${1:-4096}
/usr/bin/openssl genrsa -out apisix.key $keylen
/usr/bin/openssl req -key apisix.key -new -out apisix.csr -subj '/C=/ST=/L=/O=/OU=web/CN=*.httpbin.org'
/usr/bin/openssl x509 -req -in apisix.csr -signkey apisix.key -out apisix.crt -days 3650 -sha256
}
Prueba:
cd $(mktemp -d)
genkey 2048
python3 ssl.py apisix.crt apisix.key '*.httpbin.org'
curl --resolve 'www.httpbin.org:9443:127.0.0.1' https://www.httpbin.org:9443/uuid -vvv -k
Salida:
...
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: OU=web; CN=*.httpbin.org
* start date: Dec 22 05:52:58 2022 GMT
* expire date: Dec 19 05:52:58 2032 GMT
* issuer: OU=web; CN=*.httpbin.org
* SSL certificate verify result: self signed certificate (18), continuing anyway.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55e125a24e30)
> GET /uuid HTTP/2
> Host: www.httpbin.org:9443
> user-agent: curl/7.68.0
> accept: */*
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Connection state changed (MAX_CONCURRENT_STREAMS == 128)!
< HTTP/2 200
< content-type: application/json
< content-length: 53
< date: Thu, 22 Dec 2022 06:35:04 GMT
< access-control-allow-origin: *
< access-control-allow-credentials: true
< server: APISIX/3.0.0
<
{
"uuid": "1827f239-376f-47ec-9b54-d5addaa8c7f9"
}
Probar clave menor de 2048 bits
FIPS no admite claves RSA menores de 2048 bits. Entonces, probemos si falla con una clave pequeña.
genkey 1024
python3 cfg_ssl.py apisix.crt apisix.key '*.httpbin.org'
curl --resolve 'www.httpbin.org:9443:127.0.0.1' https://www.httpbin.org:9443/uuid -vvv -k
Salida:
...
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS alert, internal error (592):
* error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
* Closing connection 0
curl: (35) error:14094438:SSL routines:ssl3_read_bytes:tlsv1 alert internal error
Conclusión
Dadas las pruebas rigurosas que conlleva FIPS, se consideran un estándar de seguridad confiable. Además, son una línea base útil para cualquier entidad que necesite implementar estándares de seguridad dentro de su infraestructura.
Es fácil agregar soporte FIPS en APISIX. APISIX puede usarse para desencriptar y encriptar tráfico de red cifrado con SSL/TLS en implementaciones que requieren cumplimiento con FIPS 140-2 Nivel 1.
Para obtener más información sobre la puerta de enlace de API, visite nuestros blogs o contáctenos.