On Thu, 27 Aug 2015 14:36:06 -0400
"Cohen, Laurence" <[email protected]> wrote:
Hi Laurence,
> Hi,
>
> I'm trying to set up an nss.conf to use while we are doing maintenance
> which will point all ssl traffic to a file called maintenance.html
> which simply states that we are doing maintenance on the server. The
> rewrite.conf we have set up is working fine for port 80 traffic, but
> the nss.conf is not working.
>
> Here are the errors I'm getting. BTW, we are using a self signed cert
> because this is our test system. I figured this would cause an info
> or at most a warning message, but not an error message.
>
> [Thu Aug 27 13:38:00 2015] [info] Connection to child 0 established
> (server jamie-web1:443, client "Server IP")
> [Thu Aug 27 13:38:00 2015] [info] Connection to child 7 established
> (server jamie-web1:443, client "Server IP")
> [Thu Aug 27 13:38:00 2015] [info] SSL input filter read failed.
> [Thu Aug 27 13:38:00 2015] [error] SSL Library Error: -12195 Peer
> does not recognize and trust the CA that issued your certificate
> [Thu Aug 27 13:38:00 2015] [info] Connection to child 7 closed (server
> jamie-web1.novetta.com:443, client Server IP)
> [Thu Aug 27 13:38:00 2015] [info] SSL library error -8172 writing data
> [Thu Aug 27 13:38:00 2015] [info] SSL Library Error: -8172
> Certificate is signed by an untrusted issuer
> [Thu Aug 27 13:38:00 2015] [error] (20014)Internal error: proxy: pass
> request body failed to 10.3.238.21:443 (jamie-web1)
> [Thu Aug 27 13:38:00 2015] [error] proxy: pass request body failed to
> Server IP:443 (jamie-web1) from Server IP ()
> [Thu Aug 27 13:38:00 2015] [info] Connection to child 1 closed (server
> jamie-web1:443, client "Workstation IP")
>
I suppose that this problem is with CA certificate on remote server:
You have two possible solution:
1. add CA from remote server to your certificate database at PROXY
server
2. build mod_nss with a patch from this email
PS: I have already worked on a similar problem for our customer.
Have nice day
Standa
> This is the nss.conf I'm using.
>
> Listen 443
>
> AddType application/x-x509-ca-cert .crt
> AddType application/x-pkcs7-crl .crl
>
> NSSPassPhraseDialog file:/etc/httpd/.password.conf
> #NSSPassPhraseDialog builtin
>
> NSSPassPhraseHelper /usr/sbin/nss_pcache
>
> NSSSessionCacheSize 10000
> NSSSessionCacheTimeout 100
> NSSSession3CacheTimeout 86400
>
>
> NSSRandomSeed startup builtin
>
>
> <VirtualHost _default_:443>
>
> DocumentRoot "/var/www/docroot"
> NSSProxyCheckPeerCN Off
> NSSEngine on
> NSSProxyEngine on
> NSSEnforceValidCerts off
> NSSRenegotiation on
> NSSRequireSafeNegotiation on
>
> NSSCipherSuite
> +rsa_3des_sha,-rsa_des_sha,-rsa_rc4_40_md5,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_null_sha,+fips_3des_sha,-fips_des_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-rsa_des_56_sha,-rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha
>
> NSSProxyCipherSuite
> +rsa_3des_sha,-rsa_des_sha,-rsa_rc4_40_md5,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_null_sha,+fips_3des_sha,-fips_des_sha,-fortezza,-fortezza_rc4_128_sha,-fortezza_null,-rsa_des_56_sha,-rsa_rc4_56_sha,+rsa_aes_128_sha,+rsa_aes_256_sha
>
> NSSProtocol TLSv1
> NSSNickname Server-Cert
> NSSCertificateDatabase /etc/httpd/alias
> NSSFIPS on
> NSSOCSP off
>
> ProxyPreserveHost On
>
>
> <Location />
> #SSLRenegBufferSize 52430000
> NSSVerifyClient optional
> NSSOptions +ExportCertData +StdEnvVars
> ProxyPass https://jamie-web1/maintenance.html
> ProxyPassReverse https://jamie-web1/maintenance.html
> </Location>
>
> <Files ~ "\.(cgi|shtml|phtml|php3?)$">
> NSSOptions +StdEnvVars
> </Files>
> <Directory "/var/www/cgi-bin">
> NSSOptions +StdEnvVars
> </Directory>
>
>
> # initialize the SSL headers to a blank value to avoid http header
> forgeries RequestHeader set SSL_CLIENT_CERT ""
> RequestHeader set SSL_CIPHER ""
> RequestHeader set SSL_SESSION_ID ""
> RequestHeader set SSL_CIPHER_USEKEYSIZE ""
>
> RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
> RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s"
> RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s"
> RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s"
>
> CustomLog /var/log/httpd/ssl_request_log "%t %h %{SSL_CLIENT_CERT}x
> %{SSL_CLIENT_S_DN}x %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
>
>
> ErrorLog /etc/httpd/logs/error_log
> TransferLog /etc/httpd/logs/access_log
> LogLevel info
>
> </VirtualHost>
>
> If anyone can help I'd appreciate it.
>
> Thanks,
>
> Larry Cohen
Index: mod_nss-1.0.8/nss_engine_init.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_init.c
+++ mod_nss-1.0.8/nss_engine_init.c
@@ -23,7 +23,6 @@
#include "keyhi.h"
#include "cert.h"
-static SECStatus ownBadCertHandler(void *arg, PRFileDesc * socket);
static SECStatus ownHandshakeCallback(PRFileDesc * socket, void *arg);
static SECStatus NSSHandshakeCallback(PRFileDesc *socket, void *arg);
static CERTCertificate* FindServerCertFromNickname(const char* name, const CERTCertList* clist);
@@ -862,7 +861,7 @@ static void nss_init_ctx_callbacks(serve
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
nss_die();
}
- if (SSL_BadCertHook(mctx->model, (SSLBadCertHandler) ownBadCertHandler, NULL) != SECSuccess) {
+ if (SSL_BadCertHook(mctx->model, (SSLBadCertHandler) NSSBadCertHandler, NULL) != SECSuccess) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
"SSL_BadCertHook failed");
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
@@ -1287,7 +1286,7 @@ static void nss_init_certificate(server_
"SSL_SNISocketConfigHook failed");
nss_log_nss_error(APLOG_MARK, APLOG_ERR, s);
nss_die();
- }
+ }
}
@@ -1554,25 +1553,6 @@ apr_status_t nss_init_ChildKill(void *da
}
/*
- * This callback is used when the incoming cert is not valid.
- * It should return SECSuccess to accept the cert anyway, SECFailure
- * to reject. In this case we always reject.
- */
-SECStatus ownBadCertHandler(void *arg, PRFileDesc * socket)
-{
- PRErrorCode err = PR_GetError();
-
- switch (err) {
- default:
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "Bad remote server certificate: %d", err);
- nss_log_nss_error(APLOG_MARK, APLOG_ERR, NULL);
- return SECFailure;
- break;
- }
-}
-
-/*
* Called by SSL to inform application that the handshake is
* complete. This function is mostly used on the server side of an SSL
* connection, although it is provided for a client as well.
Index: mod_nss-1.0.8/mod_nss.c
===================================================================
--- mod_nss-1.0.8.orig/mod_nss.c
+++ mod_nss-1.0.8/mod_nss.c
@@ -16,6 +16,7 @@
#include "mod_nss.h"
#include <assert.h>
#include "sslerr.h"
+#include "secerr.h"
/*
* the table of configuration directives we provide
@@ -147,6 +148,8 @@ static const command_rec nss_config_cmds
"(`nickname')")
SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
"SSL Proxy: check the peers certificate CN")
+ SSL_CMD_SRV(ProxyCheckPeerCA, FLAG,
+ "SSL Proxy: check the peers certificate CA")
#ifdef IGNORE
/* Deprecated directives. */
@@ -258,12 +261,18 @@ static int ssl_engine_disable(conn_rec *
SECStatus NSSBadCertHandler(void *arg, PRFileDesc * socket)
{
conn_rec *c = (conn_rec *)arg;
+ SECStatus rv = SECFailure;
SSLSrvConfigRec *sc = mySrvConfig(c->base_server);
PRErrorCode err = PR_GetError();
- SECStatus rv = SECFailure;
- CERTCertificate *peerCert = SSL_PeerCertificate(socket);
+ CERTCertificate *peerCert = NULL;
+ peerCert = SSL_PeerCertificate(socket);
const char *hostname_note;
+ char *subject, *subject_cn, *issuer;
+ issuer = CERT_NameToAscii(&peerCert->issuer);
+ subject = CERT_NameToAscii(&peerCert->subject);
+ subject_cn = CERT_GetCommonName(&peerCert->subject);
+
switch (err) {
case SSL_ERROR_BAD_CERT_DOMAIN:
if (sc->proxy_ssl_check_peer_cn == TRUE) {
@@ -271,10 +280,8 @@ SECStatus NSSBadCertHandler(void *arg, P
apr_table_unset(c->notes, "proxy-request-hostname");
rv = CERT_VerifyCertName(peerCert, hostname_note);
if (rv != SECSuccess) {
- char *remote = CERT_GetCommonName(&peerCert->subject);
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "SSL Proxy: Possible man-in-the-middle attack. The remove server is %s, we expected %s", remote, hostname_note);
- PORT_Free(remote);
+ "SSL Proxy: Possible man-in-the-middle attack. The remove server is %s, we expected %s", subject_cn, hostname_note);
}
} else {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
@@ -284,12 +291,34 @@ SECStatus NSSBadCertHandler(void *arg, P
rv = SECSuccess;
}
break;
+ case SEC_ERROR_CA_CERT_INVALID:
+ if (sc->proxy_ssl_check_peer_ca == FALSE) {
+ rv = SECSuccess;
+ }else {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Issuer certificate is invalid: '%s'", issuer);
+ }
+ break;
+ case SEC_ERROR_UNTRUSTED_ISSUER:
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Certificate is signed by an untrusted issuer: '%s'", issuer);
+ break;
+ case SEC_ERROR_EXPIRED_CERTIFICATE:
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Remote Certificate has expired.");
+ break;
+ case SEC_ERROR_UNKNOWN_ISSUER:
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Peer's certificate issuer is not recognized: '%s'", issuer);
+ break;
default:
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
- "Bad remote server certificate: %d", err);
- nss_log_nss_error(APLOG_MARK, APLOG_ERR, NULL);
- break;
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+ "Bad remote server certificate: %d. Subject = '%s', Issuer = '%s'", err, subject, issuer);
+ nss_log_nss_error(APLOG_MARK, APLOG_ERR, NULL);
+ break;
}
+
+ PR_Free(subject);
+ PR_Free(subject_cn);
+ PR_Free(issuer);
+ CERT_DestroyCertificate(peerCert);
+
return rv;
}
@@ -400,11 +429,11 @@ static int nss_hook_pre_connection(conn_
* authentication is requested.
*/
if (!mctx->as_server) {
- if (SSL_BadCertHook(ssl, (SSLBadCertHandler) NSSBadCertHandler, c) != SECSuccess)
+ if (SSL_BadCertHook(ssl, (SSLBadCertHandler) NSSBadCertHandler, c) != SECSuccess)
{
- /* errors are reported in the certificate handler */
- return DECLINED;
- }
+ /* errors are reported in the certificate handler */
+ return DECLINED;
+ }
if (mctx->nickname) {
if (SSL_GetClientAuthDataHook(ssl, NSSGetClientAuthData,
(void*)mctx->nickname) != SECSuccess)
Index: mod_nss-1.0.8/nss_engine_config.c
===================================================================
--- mod_nss-1.0.8.orig/nss_engine_config.c
+++ mod_nss-1.0.8/nss_engine_config.c
@@ -142,6 +142,7 @@ static SSLSrvConfigRec *nss_config_serve
sc->proxy = NULL;
sc->server = NULL;
sc->proxy_ssl_check_peer_cn = TRUE;
+ sc->proxy_ssl_check_peer_ca = FALSE;
modnss_ctx_init_proxy(sc, p);
@@ -218,6 +219,7 @@ void *nss_config_server_merge(apr_pool_t
cfgMergeBool(sni);
cfgMergeBool(proxy_enabled);
cfgMergeBool(proxy_ssl_check_peer_cn);
+ cfgMergeBool(proxy_ssl_check_peer_ca);
modnss_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
@@ -565,6 +567,15 @@ const char *nss_cmd_NSSProxyCheckPeerCN(
return NULL;
}
+
+const char *nss_cmd_NSSProxyCheckPeerCA(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->proxy_ssl_check_peer_ca = flag ? TRUE : FALSE;
+
+ return NULL;
+}
const char *nss_cmd_NSSEnforceValidCerts(cmd_parms *cmd,
void *dcfg,
Index: mod_nss-1.0.8/mod_nss.h
===================================================================
--- mod_nss-1.0.8.orig/mod_nss.h
+++ mod_nss-1.0.8/mod_nss.h
@@ -315,6 +315,7 @@ struct SSLSrvConfigRec {
modnss_ctx_t *server;
modnss_ctx_t *proxy;
BOOL proxy_ssl_check_peer_cn;
+ BOOL proxy_ssl_check_peer_ca;
};
/*
@@ -435,6 +436,7 @@ const char *nss_cmd_NSSProxyProtocol(cmd
const char *nss_cmd_NSSProxyCipherSuite(cmd_parms *, void *, const char *);
const char *nss_cmd_NSSProxyNickname(cmd_parms *cmd, void *dcfg, const char *arg);
const char *nss_cmd_NSSProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
+const char *nss_cmd_NSSProxyCheckPeerCA(cmd_parms *cmd, void *dcfg, int flag);
const char *set_user(cmd_parms *cmd, void *dummy, const char *arg);
/* module initialization */
@@ -496,6 +498,9 @@ int nss_io_buffer_fill(request_
int nss_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix);
+/* check certificate globally */
+SECStatus NSSBadCertHandler(void *arg, PRFileDesc * socket);
+
/* Pass Phrase Handling */
SECStatus nss_Init_Tokens(server_rec *s);
Index: mod_nss-1.0.8/docs/mod_nss.html
===================================================================
--- mod_nss-1.0.8.orig/docs/mod_nss.html
+++ mod_nss-1.0.8/docs/mod_nss.html
@@ -1127,7 +1127,8 @@ requests client authentication.<br>
<br>
<code>NSSProxyNickname beta<br>
<br>
-</code><big><big>NSSProxyCheckPeerCN</big></big><br>
+</code>
+<big><big>NSSProxyCheckPeerCN</big></big><br>
<br>
Compare the CN value of the peer certificate with the hostname being
requested. If this is set to on, the default, then the request will
@@ -1137,7 +1138,19 @@ man-in-the-middle attack so leaving this
<br>
<span style="font-weight: bold;">Example</span><br>
<br>
-<span style="font-family: monospace;">NSSProcyCheckPeerCN</span><code>
+<span style="font-family: monospace;">NSSProxyCheckPeerCN</span><code>
+on<br>
+</code><br>
+<big><big>NSSProxyCheckPeerCA</big></big><br>
+<br>
+When a proxy is configured to forward requests to a remote SSL server, this
+directive can be used to check certificate authority verification of the
+remote server. When check fails then you will get
+SEC_ERROR_CA_CERT_INVALID. The default value for this variable is off.
+<br>
+<span style="font-weight: bold;">Example</span><br>
+<br>
+<span style="font-family: monospace;">NSSProxyCheckPeerCA</span><code>
on<br>
</code><br>
<h1><a name="Environment"></a>Environment Variables</h1>
_______________________________________________
Mod_nss-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/mod_nss-list