SSL服务器 - 客户端通信由nginx负载均衡

时间:2015-02-06 15:49:49

标签: java sockets ssl nginx server

我有问题,我想知道是否有人可以帮助我:)。

我在JAVA中开发了一个SSL通信客户端服务器,我正在尝试使用nginx对服务器进行负载均衡。 conf文件看起来:

 upstream backend {
            least_conn;
            server localhost:2010 max_fails=1 fail_timeout=20s;
            server localhost:2011 max_fails=2 fail_timeout=20s;
        }

        server {
            listen 443 ssl;
            ssl_certificate C:/nginx-1.7.9/ssl/ServerKeyStore.crt;
            ssl_certificate_key C:/nginx-1.7.9/ssl/ServerKeyStore.key;
            #ssl_session_cache shared:SSL:10m;
            ssl_session_timeout 10m;
            ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
            #proxy_connect_timeout 5s;
            #proxy_timeout 3s;
            location / {
            proxy_pass http://backend;
            }

        }

当我想使用使用nginx的客户端与我的服务器通信时,它告诉我:

handling exception: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

这是我的Client.JAVA:

package sslClient;

import java.io.*;
import javax.net.ssl.*;

public class EchoClient {

    public static final boolean DEBUG = true;
    public static final int HTTPS_PORT = 443;
    public static final String HTTPS_HOST = "localhost";
    public static final String TRUSTTORE_LOCATION = "C:/CA/ClientKeyStore.jks";
    public static final String PAN = "12345678910111213";


    public static String wrapHTML(String source) {
        return "Content-Type: text-plain\n" + "Content-Length: "
                + source.length() + "\nServer: hcetoken" + "\n\n" + source;
    }

    public static void main(String[] args) {

        System.setProperty("javax.net.ssl.trustStore", TRUSTTORE_LOCATION);

        if (DEBUG)
            System.setProperty("javax.net.debug", "ssl:record");

        SSLSocketFactory f = (SSLSocketFactory) SSLSocketFactory.getDefault();
        try {

            SSLSocket c = (SSLSocket) f.createSocket(HTTPS_HOST, HTTPS_PORT);

            c.startHandshake();


            BufferedWriter w = new BufferedWriter(new OutputStreamWriter(
                    c.getOutputStream()));
            BufferedReader r = new BufferedReader(new InputStreamReader(
                    c.getInputStream()));

            PrintWriter sortie = new PrintWriter(w);




            String msgHTML = wrapHTML(PAN);
            System.out.println("Ecriture du client");
            sortie.println(msgHTML);
            sortie.flush();

            // now read the socket
            String m = null;
            for(int i=0;i<10;++i)
            {System.out.println("\n");}
            System.out.println("Lecture du client");
            while ((m = r.readLine()) != null) {
                System.out.println("==================================================================");
                System.out.println(m);
                System.out.println("==================================================================");
            }
            System.out.println("Fin lecture du client");
            for(int i=0;i<10;++i)
            {System.out.println("\n");}

        } catch (IOException e) {
            System.err.println(e.toString());
        }

    }
}

这是我的Server.JAVA:

public class EchoServer {

    public static final boolean DEBUG = true;
    public static final int HTTPS_PORT = 2010;
    public static final String KEYSTORE_LOCATION = "C:/Keys/ServerKeyStore.jks";
    public static final String KEYSTORE_PASSWORD = "myPassword";




    // main program
    public static void main(String argv[]) throws Exception {

        // set system properties, alternatively you can also pass them as
        // arguments like -Djavax.net.ssl.keyStore="keystore"....
        System.setProperty("javax.net.ssl.keyStore", KEYSTORE_LOCATION);
        System.setProperty("javax.net.ssl.keyStorePassword", KEYSTORE_PASSWORD);

        if (DEBUG)
            System.setProperty("javax.net.debug", "ssl:record");

        EchoServer server = new EchoServer();
        server.startServer();
    }

    // Start server
    public void startServer() {
        try {
            ServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory
                    .getDefault();
            SSLServerSocket serversocket = (SSLServerSocket) ssf
                    .createServerSocket(HTTPS_PORT);

            while (true) {
                Socket client = serversocket.accept();
                ProcessRequest cc = new ProcessRequest(client);
            }
        } catch (Exception e) {
            System.out.println("Exception:" + e.getMessage());
        }
    }
}

class ProcessRequest extends Thread {

    Socket client;
    BufferedReader is;
    DataOutputStream out;
    InputStream iss;
    PrintWriter sortie;

    public static String wrapHTML(String source) {
        return "Content-Type: text-plain\n" + "Content-Length: "
                + source.length() + "\nServer: hcetoken" + "\n\n" + source;
    }



    public ProcessRequest(Socket s) { // constructor
        client = s;
        try {
            is = new BufferedReader(new InputStreamReader(
                    iss=client.getInputStream()));
            out = new DataOutputStream(client.getOutputStream());

            sortie = new PrintWriter(client.getOutputStream());

        } catch (IOException e) {
            System.out.println("Exception: " + e.getMessage());
        }
        this.start(); // Thread starts here...this start() will call run()
    }

    public void run() {
        try {
            // get a request and parse it.


            String request = ""; 



            for(int i=0;i<10;++i)
            {System.out.println("\n");}



            while(true)
            {
                request=is.readLine();
                System.out.println(">"+request +" "+request.length());
                    if(request.length()==0)break;

            }

            request=is.readLine();


            for(int i=0;i<10;++i)
            {System.out.println("\n");} 
            System.out.println("=========================================================");

            for(int i=0;i<10;++i)
            {System.out.println("\n");}

            System.out.println(request);
            System.out.println("=========================================================");


            for(int i=0;i<10;++i)
            {System.out.println("\n");}
            try {

                sortie.println(wrapHTML(CryptographiePAN.cryptoPAN(request)));

                sortie.flush();

            } catch (Exception e) {
                out.writeBytes("Content-Type: text/html\r\n");
                out.writeBytes("HTTP/1.0 400 " + e.getMessage() + "\r\n");
                out.flush();
            } finally {
                out.close();
            }
            client.close();
        } catch (Exception e) {
            System.out.println("Exception: " + e.getMessage());
        }
    }
}

如果你能帮助我,我将不胜感激!

1 个答案:

答案 0 :(得分:1)

您是Java客户端不受信任的服务器证书。 Java使用信任库来确定它接受的证书。您需要从CA获取可信证书或将证书添加到信任库。

如果您不想购买证书,则需要更新Java。 This answer似乎涵盖了忽略错误或添加证书所需的内容。

你的nginx配置的相关部分是:

        ssl_certificate C:/nginx-1.7.9/ssl/ServerKeyStore.crt;
        ssl_certificate_key C:/nginx-1.7.9/ssl/ServerKeyStore.key;

您似乎已经了解了这一点,因为您已经定义了自定义信任库:

    public static final String TRUSTTORE_LOCATION = "C:/CA/ClientKeyStore.jks";

所以它应该只是添加服务器证书的情况。