Назад | Перейти на главную страницу

Сервис AWS для перевода портов

Есть ли сервис Amazon Web Services, который будет переводить порты, такие как порт 8001, на порт 80?

Мне нравится размещать несколько веб-сайтов за одним статическим IP-адресом, и я использую переадресацию портов для маршрутизации различных портов на различные веб-серверы за моим брандмауэром, который выполняет переадресацию портов.

Было бы неплохо, если бы я мог реализовать такую ​​таблицу где-нибудь внутри сервиса AWS:

Клиентские запросы mydomain.com:80 -> AWS Route 53 переводится как 123.123.123.123:8001 -> Перенаправляет порт моего брандмауэра 8001 к веб-серверу внутри локальной сети.

Если AWS не предлагает эту услугу, то есть ли другое готовое решение? Я мог бы написать собственное приложение для этого и запустить его на экземпляре EC2, но я предпочитаю использовать существующий инструмент, если он доступен.

Конечно, AWS ALB может это сделать. Кроме того, теперь он поддерживает маршрутизация на основе хоста, поэтому вы можете указать несколько имен на ALB и настроить его для маршрутизации каждого из них отдельно.

Примечание: ALB может загружать только запросы балансировки нагрузки на внутренние серверы, которые в пределах AWS. Это не универсальная служба балансировки нагрузки, которую можно использовать где угодно. Как правило, вы развертываете внутренние серверы в частной подсети VPC, а затем развертываете перед ними ALB для приема клиентских запросов.

Клиент запрашивает mydomain.com:80 -> AWS Route 53 преобразуется в 123.123.123.123:8001 -> Порт моего брандмауэра перенаправляет 8001 на веб-сервер внутри локальной сети.

Я думаю, вы не понимаете роли DNS. DNS ничего не знает о портах. Для публикации веб-сайта DNS только сопоставляет имя с одним или несколькими IP-адресами. Период. Невозможно настроить перенаправление DNS на порт или что-то подобное.

Я написал свой собственный переводчик портов на NodeJS и отправляю здесь код на случай, если кто-то еще захочет его использовать. Он выполняет зашифрованные соединения с сертификатами https, а также с обычным текстовым портом 80. Я запускаю его на экземпляре EC2 t2.micro за 10 долларов в месяц, и он отлично работает.

Единственная загвоздка - это то, что браузер должен поддерживать SNICallback, чтобы прокси-сервер мог динамически использовать правильный сертификат для запрошенного домена.

Это крошечное приложение ниже использует библиотека http-прокси для NodeJS.

var proxyTable = {
    'mydomain.com': 'http://localhost:8001',
    'demo1.mydomain.com': 'https://localhost:8002', // https after proxy
    'demo2.mydomain.com': 'https://localhost:8005', // https after proxy
    'demo3.mydomain.com': 'https://localhost:8006', // https after proxy
    'demo4.mydomain.com': 'https://localhost:8007', // https after proxy
    'demo5.mydomain.com': 'https://localhost:8008', // https after proxy
}

http.createServer(function(req, res) {
    var hostname = req.headers.host.replace(/^www\./, ''); // remove www. subdomain prefix
    if (proxyTable[hostname]) {
        if (-1 != httpsDomains.indexOf(hostname)) { // redirect to https for httpsDomains
            redirectToHttps(req, res); // res.redirect() not available here
        } else {
            proxy.web(req, res, {target: proxyTable[hostname]});
        }
    } else {
        displayError(res, hostname)
    }
}).listen(80);

// Use SNICallback to dynamically use various SSL certificates depending upon hostname.
// To add a new SSL domain, add to secureContext AND proxyTable
const efboKey = fs.readFileSync(global.appRootPath + '/../mydomain.com.key', 'utf8');
const efboCert = fs.readFileSync(global.appRootPath + '/../mydomain.com.crt', 'utf8');
const efboCaBundleArray = makeCertificateAuthorityArray(global.appRootPath + '/../mydomain.com.ca-bundle', 'utf8');
const efboHttpsComponents = {
        key: efboKey,
        cert: efboCert,
        ca: efboCaBundleArray,
    };
var secureContext = {
    'mydomain.com': tls.createSecureContext(efboHttpsComponents),
    'demo1.mydomain.com': tls.createSecureContext(efboHttpsComponents),
    'demo2.mydomain.com': tls.createSecureContext(efboHttpsComponents),
    'demo3.mydomain.com': tls.createSecureContext(efboHttpsComponents),
    'demo4.mydomain.com': tls.createSecureContext(efboHttpsComponents),
    'demo5.mydomain.com': tls.createSecureContext(efboHttpsComponents),
}
try {
    var options = {
        SNICallback: function (hostname, cb) {
            if (secureContext[hostname]) {
                if (cb) {
                    cb(null, secureContext[hostname]);
                } else {
                    return secureContext[hostname]; // compatibility for older versions of node
                }
            } else {
                throw new Error('No keys/certificates for hostname requested');
            }
        },
        // must list a key and cert because required by tls.createServer()
        key: efboKey,
        cert: efboCert,
        ca: efboCaBundleArray,
    }
    https.createServer(options, function (req, res) {
        var hostname = req.headers.host.replace(/^www\./, ''); // remove www. subdomain prefix
        proxy.web(req, res, {target: proxyTable[hostname], secure: false}); // proxy https to http
    }).listen(443);
} catch (err){
    console.error(err.message);
    console.error(err.stack);
}