Облачная платформа Google: не удается запустить Java-сервер https
Следующая простая программа:
import com.sun.net.httpserver.HttpsServer;
import java.net.InetSocketAddress;
class SimpleServer {
public static void main(String[] pArgs) {
try {
HttpsServer s = HttpsServer.create(new InetSocketAddress(443), 0);
System.out.println(" " + s);
} catch (Exception pE) {
throw new RuntimeException("Could not create HTTPS server", pE);
}
}
}
не будет работать внутри виртуальной машины Debian, размещенной на облачной платформе Google (Google Compute Engine - IaaS):
Exception in thread "main" java.lang.RuntimeException: Could not create HTTPS server
at SimpleServer.main(SimpleServer.java:10)
Caused by: java.net.SocketException: Permission denied
at sun.nio.ch.Net.bind0(Native Method)
at sun.nio.ch.Net.bind(Net.java:433)
at sun.nio.ch.Net.bind(Net.java:425)
at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
at sun.net.httpserver.ServerImpl.<init>(ServerImpl.java:100)
at sun.net.httpserver.HttpsServerImpl.<init>(HttpsServerImpl.java:50)
at sun.net.httpserver.DefaultHttpServerProvider.createHttpsServer(DefaultHttpServerProvider.java:39)
at com.sun.net.httpserver.HttpsServer.create(HttpsServer.java:90)
at SimpleServer.main(SimpleServer.java:7)
Этот пример будет работать при запуске на рабочем столе Windows, а также, если мы изменим порт с 443 на что-то другое. Так как же заставить облако Google разрешить сервер на 443? Я попытался открыть брандмауэр, но это не сработало (не то, чтобы оно действительно должно было быть:-(, так как это отдельная проблема).
Java-версия (хотя я сомневаюсь, что это имеет значение):
openjdk version "1.8.0_141"
OpenJDK Runtime Environment (build 1.8.0_141-8u141-b15-1~deb9u1-b15)
OpenJDK 64-Bit Server VM (build 25.141-b15, mixed mode)
1 ответ
Это не проблема GCP, а функция безопасности Linux / Unix.
Порты ниже 1024 в Linux / Unix являются "привилегированными портами", для создания которых требуются повышенные привилегии.
Поскольку вы находитесь в GCP, у вас есть несколько вариантов.
Используйте высокий порт выше 1024 в качестве непривилегированного пользователя и:
- Подключитесь к этому высокому порту в вашем URL https://foo:8443
- Используйте сеть GCP или балансировщик нагрузки HTTP/HTTPS для переадресации порта 443 на высокий порт
- Использование таблиц IP для пересылки пакетов с 443 на высокий порт внутри экземпляра виртуальной машины
- Запустите сервис, используя suid, sudo или другой метод
- Предоставьте процессу _CAP_NET_BIND_SERVICE_ возможности (7).
Эти два последних варианта имеют сложные последствия для безопасности, и их следует избегать, если это вообще возможно.
Следующая ссылка будет охватывать некоторые из перечисленных выше вариантов, но первый вариант будет самым простым, хотя и намного безопаснее, чем два последних.
https://debian-administration.org/article/386/Running_network_services_as_a_non-root_user.