Detailed Explanation and Simple Example of Nodejs Multi site Handover Htpps Protocol

  • 2021-07-22 08:59:55
  • OfStack

Detailed Explanation of Nodejs Multi-site Handover Htpps Protocol

It is purely a fashion. After tossing for two days, I finally switched all the services of the personal station from http protocol to https. Although the whole process is not too troublesome, I have to admit that personal knowledge of Internet security is relatively lacking;

Letsencrypt was initiated by Mozilla, Cisco, EFF and other organizations. It provides SSL certificates to the vast number of Internet websites free of charge. The purpose is to accelerate the transition of the Internet from Http to Https. I am very happy to meet it unexpectedly on weekends. This is definitely a great benefit for an Internet retail investor, so I decided to take the weekend to toss once: get the certificate first, and then change the program;

It is also relatively simple to obtain the free SSL certificate issued by letsencrypt. I'm also an windows server, At present, I can't toss Linux. So download the installation package for letsencrypt-win-simple, Running letsencrypt. exe begins: Step 1 Enter the mailbox, If it is not the first application, the first two steps will be skipped. Then there are five options for you to choose from. 1 Choose M, Enter M, Enter gets to the field where you need a certificate, Then enter the root directory of the site corresponding to this domain. Just enter one domain running online, The specified root directory needs to be directly accessible, Because he will access the domain you entered and a file in the root directory, I wonder how he is in my site to create those new directories and verification files, that is to say, he will create two new directories and a verification file he needs to access under the directory you specify, and accurately say he needs to know this garbled file in a garbled content to complete authentication; After authentication, the certificate file will be generated in the directory C:\ Users\ Administrator\ AppData\ Roaming\ letsencrypt-win-simple\ httpsacme-v01.api.ES40org; The next steps are relatively casual;

If you have a main domain and a site, then you can take the certificate to change the program;

If it is really finished like this, does it feel too fast, so that there is no experience; According to the above steps, a certificate can be generated once under one domain, so it is naturally ok to repeat these steps and generate multiple certificates under multiple domains. The problem lies in the necessity, and perhaps tossing is to pay for your naive and weak knowledge;

Ok, I'm naive; I generated a certificate for the main domain and two level 2 domains, and then changed the program!

My site is built with Nodejs, and there are three small sites strung together by http-proxy agents inside. I didn't use Nginx completely to understand 1 point Nodejs with amateur playfulness; Next, the master station listens on port 443, and the level 2 station is distributed by http-proxy agent;


 
var https=require('https');
var http=require('http');
var fs=require('fs');

var server = http.createServer(app);
var httpsServer=https.createServer({
 key: fs.readFileSync('./privatekey.pem'),
 cert: fs.readFileSync('./certificate.pem')
},app);

httpsServer.listen(443);
server.listen(80);

What the proxy middleware looks like:


app.use(function(req,res,next){
  var proxy = httpProxy.createProxyServer({
    headers:{
      'x-forward-ip':req.ip.match(/([\w\.]+)/g)[1]    }
  });
  proxy.on('error', function (err, req, res) {
    res.writeHead(500, {
      'Content-Type': 'text/plain'
    });
    res.end('Something went wrong.');
  });
  
  switch (req.headers.host){
    case 'm.famanoder.cn':
    proxy.web(req, res, { target: 'https://localhost:2333' });
    break;
    case 'cdn.famanoder.cn': 
    proxy.web(req, res, { target: 'https://localhost:3222' });
    break;
    default: 
      next();
  }
});

In this way, there is no problem in accessing the main domain with https. The problem is that the visiting browser of the second-level site will always prompt that the certificate of the website is not trusted. There is no way, so we have to visit the second-level site like this: https://cdn.famanoder.com: 4000/. Yes, it is of course no problem to visit with a port. In this way, there is no proxy, but it always feels inconvenient and awkward, so we can only think again.

It was another coincidence. When I got up and got off work, I saw an article, except the title, which was all in English, but my intuition told me that the content had something I wanted; I looked at it once, and it suddenly became clear: start the letsencrypt plus-san parameter on the command line to apply for a certificate, which can bind multiple attached domains for one domain, that is to say, multiple domains can share the same set of certificates, so the proxy problem will naturally be solved; After entering the main domain, enter multiple domains separated by commas, and then he will go to each domain for verification in turn, and finally generate a common set of certificates; So I decided to add dinner tonight!

Letsencrypt is authenticated by accessing addresses in this format:

http://cdn.famanoder.com/.well-known/acme-challenge/RHha4Dx3YaUzi7tu_C6p9mPk-TNpuLVN5hMQro2N1_Q

He will access this garbled file in each domain in turn, and it is estimated that there is another garbled content he wants in this file. Open it and have a look; The Express used by the master station and the native Nodejs used by the cdn site, the access results of the two sites are directly downloaded files, and the MIME header may be changed, because now multiple domains want to access files under the same directory. Simply fill in the real root directory when filling in the root directory, but fill in a directory to which multiple root directories belong together, such as D:\. Modify the routing file as follows:


 
// www(Express)
app.get('/.well-known/acme-challenge/:ids',function(req,res,next){
  require('fs').readFile('D:/.well-known/acme-challenge/'+req.params.ids,function(err,data){
    err&&console.log(err);
    res.end(data);
  });
});
// www(Koa2)
router.get('/.well-known/acme-challenge/:ids',async (cx,next)=>{
  await next();
  let data=await fs.readFileSync('D:'+cx.request.url);
  cx.response.body=data;
});

// cdn
if (req.url.indexOf('acme-challenge')!=-1) {
  var pathname=url.parse(req.url).pathname;
  fs.readFile('D:'+pathname,function(err,data){
    err&&console.log(err);
    res.writeHead(200,{
     'content-type':'text/html'
    });
    res.end(data);
    return false;
  });
}
return false;

In this way, multiple domains have passed the verification in turn, and the same set of certificates are generated, which are valid for 3 months. If the system is normal within the validity period, it will be automatically renewed after 3 months; Then you can continue to take the http-proxy proxy, and the https access of level 2 sites does not need to bring ports; The next step is to replace all http with https, or directly remove the protocol.//www. famanoder. com format can also be used, and the browser will automatically recognize and adopt the corresponding protocol;

Since the authentication domain of Letsencrypt must be accessible online, local development should be configured separately. For example, it is also possible to generate a set of certificates with openssl that comes with Git for development and debugging, but the browser will prompt that the certificates are not credited;

In a word, it is not complicated to say it is complicated, and it is not so simple to say it is simple. Things are just such things, and tossing is to pay for naive and weak knowledge!

Thank you for reading, hope to help everyone, thank you for your support to this site!


Related articles: