私はHTTPSをnodeのexpress.jsで動作させようとしていますが、それを理解することができません。
これは私のapp.js
コードです。
var express = require('express');
var fs = require('fs');
var privateKey = fs.readFileSync('sslcert/server.key');
var certificate = fs.readFileSync('sslcert/server.crt');
var credentials = {key: privateKey, cert: certificate};
var app = express.createServer(credentials);
app.get('/', function(req,res) {
res.send('hello');
});
app.listen(8000);
実行すると、HTTPリクエストにのみ応答するようです。
私は簡単なVanillaのnode.js
ベースのHTTPSアプリを書きました。
var fs = require("fs"),
http = require("https");
var privateKey = fs.readFileSync('sslcert/server.key').toString();
var certificate = fs.readFileSync('sslcert/server.crt').toString();
var credentials = {key: privateKey, cert: certificate};
var server = http.createServer(credentials,function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});
server.listen(8000);
そして私がこのアプリを実行すると、 はします HTTPSリクエストに応答します。 fsの結果に対するtoString()は重要ではないと思うことに注意してください。私は両方の組み合わせを使用しましたが、まだes es buenoは使用していません。
追加するための編集:
プロダクションシステムの場合、nodejsアプリケーションへのリクエストを代理するためにNginxまたはHAProxyを使用する方がおそらく賢明です。あなたはSSLリクエストを処理し、あなたのノードapp.jsにhttpを話すようにnginxを設定することができます。
追加する編集(2015年4月6日)
AWSを使用しているシステムでは、SSL終了を処理するためにEC2 Elastic Load Balancerを使用し、EC2ウェブサーバーへの通常のHTTPトラフィックを許可することをお勧めします。セキュリティをさらに強化するには、ECBインスタンスへのHTTPトラフィックの送信がELBだけに許可されるようにセキュリティグループを設定します。これにより、外部の暗号化されていないHTTPトラフィックがマシンに衝突するのを防ぎます。
Express.js(バージョン3以降)では、その構文を使用する必要があります。
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('sslcert/server.key', 'utf8');
var certificate = fs.readFileSync('sslcert/server.crt', 'utf8');
var credentials = {key: privateKey, cert: certificate};
var express = require('express');
var app = express();
// your express configuration here
var httpServer = http.createServer(app);
var httpsServer = https.createServer(credentials, app);
httpServer.listen(8080);
httpsServer.listen(8443);
このようにして、ネイティブのhttp/httpsサーバーにエクスプレスミドルウェアを提供します。
アプリを1024未満のポートで実行したい場合は、Sudo
コマンドを使用するか(推奨されません)、またはリバースプロキシ(nginx、haproxyなど)を使用する必要があります。
私は、ポート443以外のポートでSSLを機能させることで同様の問題に遭遇しました。バンドル証明書は複数の証明書を保持するファイルです。ノードはそれらの証明書を配列の別々の要素に分割することを要求します。
var express = require('express');
var https = require('https');
var fs = require('fs');
var options = {
ca: [fs.readFileSync(PATH_TO_BUNDLE_CERT_1), fs.readFileSync(PATH_TO_BUNDLE_CERT_2)],
cert: fs.readFileSync(PATH_TO_CERT),
key: fs.readFileSync(PATH_TO_KEY)
};
app = express()
app.get('/', function(req,res) {
res.send('hello');
});
var server = https.createServer(options, app);
server.listen(8001, function(){
console.log("server running at https://IP_ADDRESS:8001/")
});
App.jsでは、httpsを指定してそれに応じてサーバーを作成する必要があります。また、使用しようとしているポートが実際に着信トラフィックを許可していることを確認してください。
まず、 selfsigned.key と selfsigned.crt filesを作成する必要があります。 にアクセスして自己署名SSL証明書を作成します
端末に行き、次のコマンドを実行してください。
Sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./selfsigned.key -out selfsigned.crt
作成後、コードにkey&certファイルを追加して、そのオプションをサーバーに渡します。
const express = require('express');
const https = require('https');
const fs = require('fs');
const port = 3000;
var key = fs.readFileSync(__dirname + '/../certs/selfsigned.key');
var cert = fs.readFileSync(__dirname + '/../certs/selfsigned.crt');
var options = {
key: key,
cert: cert
};
app = express()
app.get('/', (req, res) => {
res.send('Now using https..');
});
var server = https.createServer(options, app);
server.listen(port, () => {
console.log("server starting on port : " + port)
});
Sailsjsにはすべてのものを設定する2つの方法があります、最初はconfigフォルダで設定することです(それぞれ設定に関するデータベース接続がconnections.js内にあるように)それぞれ別々のファイルを持ちます。そして2つ目は、環境ベースのファイル構造で設定することです。各環境ファイルはconfig/env
フォルダーに存在し、各ファイルには特定のenvの設定が含まれています。
最初にconfig/envフォルダを探し、次にconfig/* .jsを楽しみにします
これで、sslをconfig/local.js
に設定できます
var local = {
port: process.env.PORT || 1337,
environment: process.env.NODE_ENV || 'development'
};
if (process.env.NODE_ENV == 'production') {
local.ssl = {
secureProtocol: 'SSLv23_method',
secureOptions: require('constants').SSL_OP_NO_SSLv3,
ca: require('fs').readFileSync(__dirname + '/path/to/ca.crt','ascii'),
key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key','ascii'),
cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt','ascii')
};
local.port = 443; // This port should be different than your default port
}
module.exports = local;
あるいは、これを config/env/production.js に追加することもできます。 (このスニペットは、複数のCARoot証明書を処理する方法も示しています)
またはproduction.jsに
module.exports = {
port: 443,
ssl: {
secureProtocol: 'SSLv23_method',
secureOptions: require('constants').SSL_OP_NO_SSLv3,
ca: [
require('fs').readFileSync(__dirname + '/path/to/AddTrustExternalCARoot.crt', 'ascii'),
require('fs').readFileSync(__dirname + '/path/to/COMODORSAAddTrustCA.crt', 'ascii'),
require('fs').readFileSync(__dirname + '/path/to/COMODORSADomainValidationSecureServerCA.crt', 'ascii')
],
key: require('fs').readFileSync(__dirname + '/path/to/jsbot.key', 'ascii'),
cert: require('fs').readFileSync(__dirname + '/path/to/jsbot.crt', 'ascii')
}
};
ここで、wsはWeb Socket、wssはSecure Web Socketを表します。SSLを設定してからhttpとwsの両方の要求がセキュアになり、それぞれhttpsとwssに変換されます。
ブログ投稿、ソーシャルメディア投稿のようにアプリからのリクエストを受け取るソースは多数ありますが、サーバーはhttpsでのみ実行されるため、httpからのリクエストがあるとクライアントブラウザで「このサイトにアクセスできない」エラーが発生します。そして私達は私達のウェブサイトのトラフィックを失います。そのため、httpリクエストをhttpsにリダイレクトする必要があります。そうでなければ、socketは失敗します。
そのため、同じサーバーをポート80(http)で実行し、すべての要求をポート443(https)に転送する必要があります。サーバーを持ち上げる前に、最初にconfig/bootstrap.jsファイルをコンパイルします。ここでは、エクスプレスサーバーをポート80で起動できます。
config/bootstrap.js内(httpサーバーを作成し、すべての要求をhttpsにリダイレクトします)
module.exports.bootstrap = function(cb) {
var express = require("express"),
app = express();
app.get('*', function(req, res) {
if (req.isSocket)
return res.redirect('wss://' + req.headers.Host + req.url)
return res.redirect('https://' + req.headers.Host + req.url)
}).listen(80);
cb();
};
今、あなたは http://www.yourdomain.comにアクセスできます 、それは/にリダイレクトされます https://www.yourdomain.com
これが私にとってどのように機能するかです。使用されるリダイレクトは、通常のhttpもすべてリダイレクトします。
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const http = require('http');
const app = express();
var request = require('request');
//For https
const https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('certificates/private.key'),
cert: fs.readFileSync('certificates/certificate.crt'),
ca: fs.readFileSync('certificates/ca_bundle.crt')
};
// API file for interacting with MongoDB
const api = require('./server/routes/api');
// Parsers
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Angular DIST output folder
app.use(express.static(path.join(__dirname, 'dist')));
// API location
app.use('/api', api);
// Send all other requests to the Angular app
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
app.use(function(req,resp,next){
if (req.headers['x-forwarded-proto'] == 'http') {
return resp.redirect(301, 'https://' + req.headers.Host + '/');
} else {
return next();
}
});
http.createServer(app).listen(80)
https.createServer(options, app).listen(443);
Greenlock 証明書の発行と更新(Let's Encrypt経由)およびhttp => httpsリダイレクトをそのまま使用できます。
express-app.js
:
var express = require('express');
var app = express();
app.use('/', function (req, res) {
res.send({ msg: "Hello, Encrypted World!" })
});
// DO NOT DO app.listen()
// Instead export your app:
module.exports = app;
server.js
:
require('greenlock-express').create({
// Let's Encrypt v2 is ACME draft 11
version: 'draft-11'
, server: 'https://acme-v02.api.letsencrypt.org/directory'
// You MUST change these to valid email and domains
, email: '[email protected]'
, approveDomains: [ 'example.com', 'www.example.com' ]
, agreeTos: true
, configDir: "/path/to/project/acme/"
, app: require('./express-app.j')
, communityMember: true // Get notified of important updates
, telemetry: true // Contribute telemetry data to the project
}).listen(80, 443);
クイックスタートのデモを見る: https://youtu.be/e8vaR4CEZ5s
これは一般的なフォローアップの質問なので、先回りで答えるだけです。
LocalhostにSSL証明書を持つことはできません。ただし、 Telebit のようなものを使用すると、ローカルのアプリを実際のアプリとして実行できます。
また、READMEでサポートされているさまざまなプラグインとともに、プライベートドメインをGreenlockでDNS-01チャレンジを介して使用することもできます。
Localhostについての上のメモを読んでください - Let's Encryptでも標準以外のポートを使うことはできません。
ただし、ポートフォワード、スニルート、またはSNIルーティングとポートフォワーディング/リレーを行うTelebitのようなものを使用して、内部の非標準ポートを外部の標準ポートとして公開することができます。
DNS-01チャレンジを使用することもできます。その場合は、ポートをまったく公開する必要はなく、プライベートネットワーク上のドメインをこのように保護することもできます。
これは私の 作業コード / express 4.0 です。
express 4.0は3.0などとは非常に異なります。
4.0/httpsを追加しようとしている/ bin/wwwファイルがあります。
"npm start"は、Express 4.0サーバーを起動するための標準的な方法です。
readFileSync()関数は __dirname を使用する必要があります
while() use ./ はカレントディレクトリを参照します。
最初に/ binフォルダの下にprivate.keyとpublic.certファイルを置き、それはWWWファイルと同じフォルダ です。