---
# System prepended metadata

title: Node JS與Apache2設定Http與Https
tags: [SSL, Node JS, Linux, Apache, Ubuntu]

---

# Node JS與Apache2設定Http與Https

###### tags: `Linux` `Ubuntu` `SSL` `Node JS` `Apache`

## Node Js 配置 HTTPS
### 編輯index.js
```javascript=
const express = require('express');
const app = express();
const fs = require('fs');
const https = require('https');
const ipfilter = require('express-ipfilter').IpFilter;
const ips = ['::ffff:127.0.0.1'];
app.use(ipfilter(ips, { mode: 'allow' }));

const server = https.createServer({
        key: fs.readFileSync([path_of_private.key], 'utf8'),
        cert: fs.readFileSync([path_of_certificate.crt], 'utf8')
}, app);

server.listen(3001, function() {
    console.log('listening HTTPS on 3001 port');
});

app.listen(3000, function () {
        //reqLogger.info('NCDR_AI listening on port 3000!');
        console.log('listening HTTP on 3000 port');
});
```

## 整合 Node Js 與 Systemd
### 1.參考自訂服務教學，自己建立一個 Systemd 服務設定檔 
```shell=
sudo vim /etc/systemd/system/[ServiceName].service
```
```shell=
[Unit]
After=network.target
Description=[ServiceName]
[Service]
Type=simple
Environment=[environment_variable]
# 執行服務的使用者
User=[user_who_execute_this_service]
# 啟動服務指令
ExecStart=[path_of_nodejs_index.js]
# 不正常停止時重新啟動
Restart=on-failure
[Install]
WantedBy=multi-user.target
```
### 2.變更權限
```shell=
sudo chmod 644 /etc/systemd/system/[ServiceName].service
```
### 3.重新載入 Systemd 設定檔
```shell=
sudo systemctl daemon-reload
```
### 4.啟動自訂的 伺服器
```shell=
sudo systemctl start [ServiceName]
```
### 5.查看伺服器狀態
```shell=
sudo systemctl status [ServiceName]
```

## Apache2 Proxy HTTPS
### 1.將Apache2的 proxy & proxy_http模組啟用
```shell=
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod ssl
```
### 2.重新啟動 apache以完成設定
```shell=
sudo service apache2 restart
```
### 3.編輯 /etc/apache2/sites-enabled/000-default.conf轉發Node Js的port
```
<VirtualHost *:443>
	ServerName [web.domain.com]
	ServerAlias [domain.com] #其他網址也可以連到同一個目錄
	SSLEngine On
	SSLProxyEngine on
	SSLProxyVerify none
	SSLProxyCheckPeerCN off
	SSLProxyCheckPeerName off
	SSLProxyCheckPeerExpire off
	SSLCertificateFile          [path_of_certificate.crt]
	SSLCertificateKeyFile       [path_of_private.key]
	SSLCertificateChainFile     [path_of_ca_bundle.crt]
	ProxyPass / https://localhost:3001/
	ProxyPassReverse / https://localhost:3001/
	<Proxy *>
		Order deny,allow
		Deny from all
		Allow from [ip]
	</Proxy>
</VirtualHost>
<VirtualHost *:80>
	ServerName www.example.com
	ServerAlias example.com #其他網址也可以連到同一個目錄
	ProxyPass http://localhost:3000/
	ProxyPassReverse http://localhost:3000/
	<Proxy *>
		Order deny,allow
		Deny from all
		Allow from [ip]
	</Proxy>
</VirtualHost>
```
### 4.不顯示server的詳細資料
編輯/etc/apache2/apache2.conf 在最後面加上
```
ServerTokens ProductOnly
ServerSignature Off
```


## Nodejs cipher(待補充)
https://ciphersuite.info/
https://node-security.com/posts/express-https-server/
```javascript=
const https = require('https');
var options = {
    key: fs.readFileSync('./ssl/gistw/server.key'),
    cert: fs.readFileSync('./ssl/gistw/server.crt'),
	maxVersion: 'TLSv1.3',
	minVersion: 'TLSv1.2',
	ciphers: 'TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256',
};



https.createServer(options,function(req,res){}).listen(443)
```

## Apache2 Headers安全性
### 1. 啟用header 修改模組
```
sudo a2enmod headers
```
### 2. 編輯 /etc/apache2/sites-enabled/000-default.conf
```
<VirtualHost *:443>
    ServerName [web.domain.com]
    
    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
    Header always set X-Content-Type-Options "nosniff"
    Header always set Content-Security-Policy "default-src 'self';"
    Header always set X-Frame-Options "SAMEORIGIN"
    Header always set Referrer-Policy "strict-origin"
    Header always set Permissions-Policy "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()"
    <Proxy *>
		Order deny,allow
		Deny from all
		Allow from [ip]
	</Proxy>
</VirtualHost>
```