Nano Hash - криптовалюты, майнинг, программирование

Vert.x перенаправляет http на https

Мы переписали наши веб-сервисы с помощью Vert.x 4 и более чем довольны. Прежде чем запускать их в производство, мы хотим защитить их и пытаемся включить https. Это основная статья:

public class MainVerticle extends AbstractVerticle {

  @Override
  public void start() throws Exception {
    //Deploy the HTTP server
    vertx.deployVerticle(
      "com.albertomiola.equations.http.HttpServerVerticle",
      new DeploymentOptions().setInstances(3)
    );
  }

  // I use this only in IntelliJ Idea because when I hit "Run" the build starts
  public static void main(String[] args) {
    Launcher.executeCommand("run", MainVerticle.class.getName());
  }

}

И это самая важная часть кода страницы HTTP-сервера:

public class HttpServerVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    var options = new HttpServerOptions();
    options.setPort(443)
           .setSSl(true)
           .setPemTrustOptions(...)
           .setPemKeyCertOptions(...);

    var server = vertx.createHttpServer(options);
    var router = Router.router(vertx);

    //Start
    server
      .requestHandler(router)
      .listen(portNumber, ar -> {
        if (ar.succeeded()) {
          startPromise.complete();
        } else {
          startPromise.fail(ar.cause());
        }
      });
  }

}

Приведенный выше код работает нормально, потому что мой веб-сайт доступен по адресу https://website.it и https://www.website.it (с сертификатами letsencrypt).


Проблема в том, что когда я пытаюсь получить доступ к http://website.it или http://www.website.it не работает (это означает, что я не вижу дом, потому что сервер недоступен).

Как я могу перенаправить http://website.it на https//website.it?

Я много гуглил, и мне удалось найти:

  • этот пример vertx, который настраивает HTTPS, как я, но не упоминает перенаправление
  • этот ТАК вопрос, который, кажется, говорит мне, что делать, но я не могу понять, что делать, и я не уверен, должна ли эта настройка идти в объекте HttpServerOption

Может быть, моя конфигурация https неверна? Я использую Java 11 в IntelliJ IDEA (сборка Maven) и последней версии Vert.x 4. Спасибо

16.09.2019

  • почему вы не включаете https в nginx/LB, что рекомендуется? 17.09.2019
  • потому что я не нашел никакого ресурса об этом! не могли бы вы поделиться ссылкой? 17.09.2019
  • 2 секунды гугления https://bjornjohansen.no/redirect-to-https-with-nginx 17.09.2019
  • если вы используете что-то другое вместо nginx, например AWS LB, в Интернете должно быть достаточно информации 17.09.2019
  • Я думал, что vert.x обеспечивает встроенную поддержку этого перенаправления, но, похоже, это не так. Тогда я пойду на nginx, спасибо! 17.09.2019
  • хорошо, вы можете включить SSL vertx.io/docs/vertx-core/groovy/#ssl , но переключение http-https не предусмотрено. На самом деле общепринятой практикой является обработка таких вещей, как прокси, перезапись, переключение протоколов перед сервером приложений. 17.09.2019

Ответы:


1

Окончательные решения, которые я придумал, показаны ниже, и они эквивалентны. Идея в обоих случаях состоит в том, чтобы иметь http-сервер (который, конечно же, прослушивает порт 80), который перенаправляет каждый вызов на https-сервер.

Так что в моем случае я могу делать именно то, что хочу, потому что http://mydomain.it перенаправляется на https://mydomain.it, как и ожидалось. Например, когда я звоню

http://mydomain.it/api/polynomial/laguerre

Существует живой http-сервер, который получает запрос, но затем немедленно бросает мяч на

https://mydomain.it/api/polynomial/laguerre

Конечно, если вы напрямую вызываете https-версию, этот «промежуточный» шаг не происходит.


Использование Vert.x

Ответ Хьюго в сообщении выше дает правильное решение с использованием Vertx. У меня есть основная вертикаль, которая выглядит так:

public class MainVerticle extends AbstractVerticle {

  @Override
  public void start() throws Exception {

    //Deploy the HTTPS server
    vertx.deployVerticle(
      "com.albertomiola.equations.http.HttpsServerVerticle",
      new DeploymentOptions().setInstances(n)
    );

    //Deploy the HTTP server
    vertx.deployVerticle(
      "com.albertomiola.equations.http.HttpServerVerticle",
      new DeploymentOptions().setInstances(1)
    );
  }

}

Первая вертикаль — это «настоящий» веб-сайт, потому что он содержит всю логику, которая мне нужна в моем веб-сервисе (маршрутизаторы, обработчики, модели...), и выглядит он так:

public class HttpsServerVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    // Setup the HTTPS
    var httpOptions = new HttpServerOptions()
      .setCompressionSupported(true)
      .setPort(443)
      .setSsl(true)
      .setPemTrustOptions(...)
      .setPemKeyCertOptions(...);

    // Start the server and the routes
    var server = vertx.createHttpServer(httpOptions);
    var router = Router.router(vertx);

    //Start
    server
      .requestHandler(router)
      .listen(ar -> {
        if (ar.succeeded()) {
          startPromise.complete();
        } else {
          startPromise.fail(ar.cause());
        }
      });
  }

}

Вместо этого другая вершина представляет собой просто http-сервер, который постоянно перенаправляет (с кодом 301) на https-версию веб-сервера. Вот код:

public class HttpsServerVerticle extends AbstractVerticle {

  @Override
  public void start(Promise<Void> startPromise) throws Exception {
    var server = vertx.createHttpServer(httpOptions);
    var router = Router.router(vertx);

    //Start
    server
      .requestHandler(r -> {
          r.response()
           .setStatusCode(301)
           .putHeader("Location", r.absoluteURI().replace("http", "https"))
           .end();
      });
  }

}

Таким образом, активны 2 сервера, но на самом деле это похоже на то, если бы был только 1, потому что сервер http (порт 80) перенаправляет каждый вызов на сервер https (порт 443).


Использование Nginx

Другой подход, который я тестировал, требует nginx, но он делает то же самое, что и в приведенном выше примере. Он прослушивает http-запросы на порту 80, а затем перенаправляет их на https-версию.

  1. Установите Nginx на мой сервер Ubuntu (или что у вас есть)
  2. Зайдите в файл конфигурации, который в моем случае находится в /etc/nginx/nginx.conf
  3. Добавьте приведенный ниже код

    http {
        server {
                listen         80;
                server_name    mydomain.it;
                return         301 https://$server_name$request_uri;
        }
    
        //other code...
    }
    
    1. Restart with systemctl restart nginx

Теперь каждый вызов http-версии перенаправляется на https-версию. Спасибо пользователю injecteer, который предложил мне этот путь.

Я использую этот подход, потому что предпочитаю не иметь ни одной вершины только для http-версии. Также в этой статье с веб-сайта Vertx говорится, что этот подход действителен. :

Обычно HTTP-серверы в производственной среде выставляются через передний HTTP-сервер/прокси, такой как Nginx, и заставляют его использовать HTTPS для входящих подключений. Vert.x также может сам раскрывать HTTPS, чтобы обеспечить сквозное шифрование.

Так что да, настройте https с помощью Vertx (я бы рекомендовал сертификаты letsencrypt), но также перенаправляйте вызовы на https с помощью nginx.


Я ошибочно думал, что могу сделать что-то конкретное с Vertx для обработки этого перенаправления, но это невозможно. После предложений людей в этом ответе И некоторого хорошего поиска в Google я узнал, что этот подход распространен, и это то, что я должен делать!

17.09.2019

2

Я думаю, вам следует создать HTTP-сервер, прослушивающий порт 80 (вместе с вашим HTTPS-сервером), который перенаправляет все запросы на их эквивалент HTTPS, отвечая HTTP-кодом 301.

Это было бы что-то вроде:

var server = vertx.createHttpServer();

server.requestHandler(req -> {
  req.response()
    .setStatusCode(301)
    .putHeader("Location", "https://" + req.host() + req.path()) // I completely made this line up and didn't test, but you have the idea
    .end();
})

Надеюсь, это поможет!

Хьюго

ps: используя Nginx, как было предложено в комментариях, вы бы сделали то же самое, но в Nginx: https://serversforhackers.com/c/redirect-http-to-https-nginx

17.09.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..