preface

In some production scenarios, our application server cannot directly connect to the Internet, cannot access the Internet interface, use yum, wget and other related commands to download dependencies. Usually need a server can connect to the external network as a proxy server, to provide external proxy function, so that our internal network can also access the external interface, download related dependencies, here we use Squid proxy server

The introduction of squids

Squid is a high-performance proxy cache server that supports FTP, Gopher, HTTPS, and HTTP protocols. Unlike typical proxy caching software, Squid uses a single, non-modular, I/ O-driven process to handle all client requests. Those who want to know more can visit its website.

System Architecture Diagram

Implementation steps

1. Configure the client

1.1. Installation squids

yum install squid -y
yum install httpd-tools -y
Copy the code

1.2. Generate a password file

Htpasswd -cd /etc/squid/passwords User name#Prompt for password
#It will then generate a passwords file in /etc/squid directory with the contents (user name: password ciphertext).
Copy the code

1.3. Test whether the password is set successfully

/usr/lib64/squid/basic_ncsa_auth /etc/squid/passwords
#Enter the user name and password
username  password
#If OK is displayed, the operation succeeds
ok
#CTRL + c to exit
Copy the code

1.4. Configure squid.conf file

#Configure user name and password authorization
vi /etc/squid/squid.conf
#Add at the end
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwords
auth_param basic realm proxy
acl authenticated proxy_auth REQUIRED
http_access allow authenticated

#Here is the port number, which can be changed as needed
#Http_port 3128 The http_port 3128 will listen on both ipv6 and ipv4 ports. The following configuration method is recommended.Http_port 0.0.0.0:3128Copy the code

1.5. Start

#Start (stop) 
systemctl start squid.service
#Configure automatic startup upon startup
systemctl enable squid.service
Copy the code

2. Configure the client

2.1. Yum agent

vim /etc/yum.conf
proxy=http://username:password@proxy_ip:port/
Copy the code

2.2. Global proxy

vi /etc/profile
#Add at the end, proxying HTTP and HTTPS respectively
export http_proxy="http://username:password@proxy_ip:port"
export https_proxy="http://username:password@proxy_ip:port"
Copy the code

3. Java program proxy

Because your project is deployed on an APP server, you can proxy your Java program if an external interface is invoked in your project

3.1. The jar package

#The agent of HTTPProxyPort = Proxy server port -Dhttp. ProxyHost = Proxy server IP address#Agent HTTPSJava-jar-dhttps. proxyPort= Proxy server port - dhttps. proxyHost= Proxy server IP addressCopy the code

3.2. Nginx

The project calls HTTPS interface, and has the certificate authentication, can not go through the Squid agent, the author has studied for a long time but did not find the Squid certificate way, if you have a good idea, you can repost the corresponding blog in the comment area, together to learn

3.2.1. Download and convert the communication certificate to PEM and KEY formats

#Run the openssl command to create a communication certificate and download the certificate xxx. PFX
openssl pkcs12 -in server.pfx -nodes -out server.pem
openssl rsa -in server.pem -out server.key
openssl x509 -in server.pem -out server.crt
Copy the code

3.2.2. Modify the code

Change the HTTP and HTTPS requests in the project to install the nginx proxy server interface. If the HTTPS request is required and the security certificate is required, then we will configure the relevant certificate in nginx

3.2.3. To install nginx, SSL must be enabled

#See another Nginx blog post
#Core script to enable SSL support: --with-http_ssl_module
./configure --prefix=/usr/local/nginx --with-http_ssl_module
Copy the code

3.2.4. Modifying the Nginx configuration file on the proxy Server

The idea is that the Java program accesses the Proxy server and uses nginx to configure the proxy to access the extranet interface. The following is to proxy an SSL extranet interface

server { listen 9443; server_name localhost; Location / {# proxy_pass https://ip:port/; Proxy_ssl_certificate /app/server.pem; proxy_ssl_certificate_key /app/server.key; proxy_ssl_trusted_certificate /app/server.pem; proxy_ssl_verify off; proxy_ssl_verify_depth 2; proxy_ssl_session_reuse on; Proxy_ssl_protocols TLSv1 TLSv1.1 TLSv1.2; proxy_ssl_ciphers HIGH:! aNULL:! MD5; }}Copy the code

4. Frequently Asked Questions

4.1 the host file

The host file needs to be configured on squid

Vim /etc/squid/squid.conf Add hosts_file /etc/hosts at the endCopy the code

4.2 The HTTPS Interface is Faulty

Vim /etc/squid/squid.conf Change http_access deny all to http_access allow allCopy the code

4.3 Interface SSL Certificate Authentication

Reference github.com/jkandasa/re…

public class InstallCert {
    public static void main(String[] args) throws Exception {
        String host;
        int port;
        char[] passphrase;
        String[] h={"ws.zhongdengwang.org.cn"};// This is the url of the WebService to visit
        if ((h.length == 1) || (h.length == 2)) {
            String[] c = h[0].split(":");
            host = c[0];
            port = (c.length == 1)?443 : Integer.parseInt(c[1]);
            String p = (h.length == 1)?"changeit" : h[1];
            passphrase = p.toCharArray();
        } else {
            System.out.println("Usage: java InstallCert <host>[:port] [passphrase]");
            return;
        }

        File file = new File("jssecacerts");
        if (file.isFile() == false) {
            char SEP = File.separatorChar;
            File dir = new File(System.getProperty("java.home") + SEP
                    + "lib" + SEP + "security");
            file = new File(dir, "jssecacerts");
            if (file.isFile() == false) {
                file = new File(dir, "cacerts");
            }
        }
        System.out.println("Loading KeyStore " + file + "...");
        InputStream in = new FileInputStream(file);
        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
        ks.load(in, passphrase);
        in.close();

        SSLContext context = SSLContext.getInstance("TLS");
        TrustManagerFactory tmf =
                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(ks);
        X509TrustManager defaultTrustManager = (X509TrustManager)tmf.getTrustManagers()[0];
        SavingTrustManager tm = new SavingTrustManager(defaultTrustManager);
        context.init(null.new TrustManager[] {tm}, null);
        SSLSocketFactory factory = context.getSocketFactory();

        System.out.println("Opening connection to " + host + ":" + port + "...");
        SSLSocket socket = (SSLSocket)factory.createSocket(host, port);
        socket.setSoTimeout(10000);
        try {
            System.out.println("Starting SSL handshake...");
            socket.startHandshake();
            socket.close();
            System.out.println();
            System.out.println("No errors, certificate is already trusted");
        } catch (SSLException e) {
            System.out.println();
            e.printStackTrace(System.out);
        }

        X509Certificate[] chain = tm.chain;
        if (chain == null) {
            System.out.println("Could not obtain server certificate chain");
            return;
        }

        BufferedReader reader =
                new BufferedReader(new InputStreamReader(System.in));

        System.out.println();
        System.out.println("Server sent " + chain.length + " certificate(s):");
        System.out.println();
        MessageDigest sha1 = MessageDigest.getInstance("SHA1");
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        for (int i = 0; i < chain.length; i++) {
            X509Certificate cert = chain[i];
            System.out.println
                    ("" + (i + 1) + " Subject " + cert.getSubjectDN());
            System.out.println(" Issuer " + cert.getIssuerDN());
            sha1.update(cert.getEncoded());
            System.out.println(" sha1 " + toHexString(sha1.digest()));
            md5.update(cert.getEncoded());
            System.out.println(" md5 " + toHexString(md5.digest()));
            System.out.println();
        }

        System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]");
        String line = reader.readLine().trim();
        int k;
        try {
            k = (line.length() == 0)?0 : Integer.parseInt(line) - 1;
        } catch (NumberFormatException e) {
            System.out.println("KeyStore not changed");
            return;
        }

        X509Certificate cert = chain[k];
        String alias = host + "-" + (k + 1);
        ks.setCertificateEntry(alias, cert);

        OutputStream out = new FileOutputStream("jssecacerts");
        ks.store(out, passphrase);
        out.close();

        System.out.println();
        System.out.println(cert);
        System.out.println();
        System.out.println
                ("Added certificate to keystore 'jssecacerts' using alias '"
                        + alias + "'");
    }

    private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray();

    private static String toHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder(bytes.length * 3);
        for (int b : bytes) {
            b &= 0xff;
            sb.append(HEXDIGITS[b >> 4]);
            sb.append(HEXDIGITS[b & 15]);
            sb.append(' ');
        }
        return sb.toString();
    }

    private static class SavingTrustManager implements X509TrustManager {

        private final X509TrustManager tm;
        private X509Certificate[] chain;

        SavingTrustManager(X509TrustManager tm) {
            this.tm = tm;
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            throw new UnsupportedOperationException();
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            throw new UnsupportedOperationException();
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            this.chain = chain; tm.checkServerTrusted(chain, authType); }}}Copy the code

Copy the generated certificate to $JAVA_HOME/jre/lib/security