web-dev-qa-db-ja.com

AppEngineフレキシブル環境カスタムランタイムでSSLを強制する

Openjdk:8に基づくDockerfileを使用して、AppEngineのフレキシブルカスタムランタイムでメタベースのインスタンスを実行しています。現在、 http:// [metabase-project] .appspot.com / および https:// [metabase-project] .appspot.com / でのアクセスが許可されています。すべてのhttpトラフィックをhttpsにリダイレクトしてSSLを強制したいと思います。

Dockerfileは次のようになります。

FROM openjdk:8
ADD https://dl.google.com/cloudsql/cloud_sql_proxy.linux.AMD64 ./cloud_sql_proxy
ADD http://downloads.metabase.com/v0.21.1/metabase.jar ./metabase.jar
CMD ./cloud_sql_proxy -instances=$INSTANCE=tcp:$MB_DB_PORT -dir=/cloudsql & Java -jar ./metabase.jar

App.yamlは次のようになります。

service: metabase
runtime: custom
env: flex

通常のAppEngine app.yamlファイルに、次のものを追加します。

handlers:
- url: [something]
  secure: always

ただし、カスタムランタイムでは、このようなハンドラーにアクセスできません。すべてのトラフィックに対してリダイレクトを実行するようにFlexibleランタイムを構成する方法はありますか?

15
Morgan Conbere

App Engine Flexはハンドラーをまったくサポートしていません: https://cloud.google.com/appengine/docs/flexible/Java/upgrading#appyaml_changes

Https://リダイレクトが必要な場合は、アプリケーション内から実行する必要があります。ごめんなさい!

7
Justin Beckwith

アプリ(app.yamlのenv: flex)はSSL接続を終了するnginxリバースプロキシの背後で実行されているため、httpまたはhttpsのいずれかになるX-FORWARDED-PROTOヘッダーを確認する必要があります。 httpの場合は、リダイレクトを実行できます。

3
zengabor

これは私のために働いたものです。私の場合、Cloud Sites AppEngineフレキシブル環境で実行されているループバックベースのNodeJSアプリケーションを使用しています。

  1. 次のコードを使用して、ミドルウェア、たとえば_server/middleware/https-redirect.js_を作成します。

    _/**
    * Create a middleware to redirect http requests to https
    * @param {Object} options Options
    * @returns {Function} The express middleware handler
    */
    module.exports = function(options) {
      options = options || {};
      var httpsPort = options.httpsPort || 443;
      return function(req, res, next) {
        if (req.protocol != 'https' && process.env.NODE_ENV !== 'development') {
          var parts = req.get('Host').split(':');
          var Host = parts[0] || '127.0.0.1';
          return res.redirect('https://' + Host + ':' + httpsPort + req.url);
        }
        next();
      };
    };
    _

    (投稿のステップ8に基づく http://www.jonxie.com/blog/2014/11/12/setting-up-loopback-to-use- https-and-ssl-certificates / ただし、_req.protocol_の代わりに_req.secure_を使用するように変更され、開発モードで実行されていない場合にのみリダイレクトされます)

  2. ファイル_server/server.js_を変更して、以下を要求します。

    _var httpsRedirect = require('./middleware/https-redirect');
    _
  3. 次に、ブートラインの後:

    _var httpsPort = app.get('https-port');
    app.use(httpsRedirect({httpsPort: httpsPort}));
    app.set('trust proxy', true)
    _

app.set('trust proxy', true)を設定すると、req.protocolが_X-Forwarded-Proto_ヘッダーを読み取ることができます。

参照:

3
Ramses

答えるのが遅いが、これをするために私は多くの苦労をしなければならなかった。

私は次のコードに言及しているさまざまなリンクをたどりました、

app.use(function(req, res, next) {
  if(!req.secure) {
    return res.redirect(['https://', req.get('Host'), req.url].join(''));
  }
  next();
});

これは他のクラウドベンダーでも機能する可能性があります。

ただし、@ zengaborが正しく言及しているGCPでは、アプリはSSL接続を終了するnginxリバースプロキシの背後で実行されます。次のコードで実行できるX-FORWARDED-PROTOを確認する必要があります。

app.use(function(req, res, next) {
  if(req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
    return res.redirect(['https://', req.get('Host'), req.url].join(''));
  }
  next();
});

@zengaborのコードを読んだ後、答えを追加するだけで、それを実現する方法をもう一度検索する必要がありました。以上が、機能する既製のコードです。

2
Gokul Kulkarni

これが私が使用するNode.jsExpressコードです:

// set the env variable REQUIRE_HTTPS=1 to enable this middleware

.use(function(req, res, next) {
    // Redirect HTTP to HTTPS
    if (!process.env.REQUIRE_HTTPS) return next();
    if (req.headers["x-forwarded-proto"] === "https") return next();
    if (req.protocol === "https") return next();
    res.redirect(301, `https://${req.hostname}${req.url}`);
})

Expressアプリの最初のミドルウェアとして配置します。

このコードは、AppEngineを使用している場合と同様に、http/httpsに標準ポートを使用していることを前提としています。

0
sffc

次のコードを使用します

app.use (function (req, res, next) {
  var schema = (req.headers['x-forwarded-proto'] || '').toLowerCase();
  if (schema === 'https') {
    next();
  } else {
    res.redirect('https://' + req.headers.Host + req.url);
  }
});
0
Zahirul Haque