Есть ли сервис 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);
}