Jetty Hook для раннего отзыва соединения TCP/IP (избегая accept())
Я ищу зацепку, позволяющую мне сообщать / инструктировать ServerConnector (или любой другой объект в архитектуре Jetty, который был бы более подходящей точкой подключения) НЕ принимать входящее соединение TCP/IP через порты веб-сервера (например: 80 или 443) на основе IP-адреса удаленной стороны (потому что это вся информация, доступная там до вызова accept() и до, позже, после принятия, данные HTTP становятся доступными из полезной нагрузки кадра TCP/IP).
Идея состоит в том, чтобы я прикрепил к этому хуку мир программного обеспечения, который для каждого входящего соединения может сказать: Принять / Отменить. При отзыве входящее соединение будет игнорироваться, а сокет будет оставаться закрытым, избегая того, чтобы контейнер Jetty выполнял над ним больше работы / использования ресурсов.
Это также позволило бы защитить функции системы (например, специальное меню администратора) после определенных портов сервера, принимая только, например, локальные адреса (10.32....) и т. Д. Было бы еще приятнее, чтобы ТАКЖЕ иметь возможность получить доступ к MAC-адресу подключаемого устройства и разрешить доступ только в том случае, если MAC-адрес находится в списке авторизации (= пользователь имел физический доступ к локальной сети для подключения своего устройства, иначе его MAC-адрес никогда не будет тем, который виден в локальной сети, потому что нет обмена одноранговыми MAC-адресами, если не в той же локальной сети).
Таким образом, я намерен предотвратить использование враждебными соединениями ЦП, полосы пропускания и сокетов, просто чтобы они отправляли им "главные" страницы во время атак и заставляли их ждать тайм-ауты. В то же время это дополнительно позволило бы защитить доступ к закрытым функциям на основе "физического локального доступа". Программное обеспечение для перехвата может даже аннулировать соединения по частям IP-адреса, например, по китайскому диапазону IP-адресов и т. Д.
Я нашел типичный интерфейс сокетов TCP/IP в классах ServerConnector (open/close/accept/...), но я не нашел места, где я мог бы зарегистрироваться для перехвата pre-accept() или обратного вызова. Я также посмотрел на предков класса ServerConnector, но я действительно не видел ничего подобного. Я начал с org.eclipse.jetty.server Класс ServerConnector
Для ясности и для людей, которые более совместимы с кодом, это будет концептуально представлять в коде то, что я ищу.
...setup Jetty server, Factories, etc
ServerConnector http2=new ServerConnector(this.oServer,sslF,alpnF,h2F,https2F);
http2.setPort(8443);
http2.setPreAcceptHook(8843, oMyHook); <---INVENTED line
this.oServer.addConnector(http2);
Хук будет простым методом объекта MyHook, который возвращает истину или ложь.
boolean AcceptRevoke(IP, Port) <--return true=accept, false=revoke
Я приветствовал бы любой намек относительно того, в каком направлении смотреть (имя класса или около того) или подтверждение, что такая функция недоступна или не может быть, и поэтому никогда не будет доступна. Могут быть ограничения в дизайне контейнера, которые не позволят аннулировать предварительное принятие, как те, которые можно делать с библиотеками сокетов, о которых я не знаю и, следовательно, буду искать невозможность.
Большое спасибо.
Информация о продукте и версиях: Jetty 9.3.0 (v20150612) alpn-boot-8.1.3 (v20150130) JRE 8 (Oracle 1.8.0 Build 45 - b15)
2 ответа
У вас впереди много работы.
Для этого вам, по сути, придется предоставить свой Socket
уровень реализации для Java. В Jetty нет слоя, который вы можете зацепить, который позволял бы вам делать все, что вы упомянули. Виды вещей, которые вы хотите сделать, находятся на гораздо более низком уровне, что-то на уровнях JVM и / или OS.
Вам нужно будет справиться java.net.Socket
, java.net.ServerSocket
, а также java.nio.channels.ServerSocketChannel
,
Это означает, что вы будете писать свои собственные javax.net.ServerSocketFactory
, javax.net.SocketFactory
, java.net.SocketImpl
, а также java.net.SocketImplFactory
для штатных розеток.
А для SSL/TLS вам нужно написать / обработать / управлять своим собственным javax.net.ssl.SSLSocket
, javax.net.ssl.SSLServerSocket
, javax.net.ssl.SSLSocketFactory
, а также javax.net.ssl.SSLServerSocketFactory
,
И не забудьте захватить все дополнения кода Jetty-Alpn в стандартных библиотеках SSL OpenJDK, чтобы вы могли также использовать HTTP/2 для себя (учитывая, что вы, очевидно, используете его, основываясь на деталях вашего вопроса)
Перед тем, как проверить это на Jetty, протестируйте свою реализацию на простой установке ServerSocket и ServerSocketChannel.
После того, как вы подтвердите, что он делает то, что вы хотите, вам нужно будет подключить его к Jetty. Для обычного ServerSocket / ServerSocketChannel вам придется работать с общесистемной java.nio.channels.spi.SelectorProvider
Для SSLServerSocket / SSLServerSocketChannel вы подключите его через пользовательский / переопределенный org.eclipse.jetty.util.ssl.SslContextFactory
реализация самостоятельно.
Или же...
Вы можете использовать комбинацию логики пост-принятия (встроенной в Jetty) и управления соединениями на уровне ОС (например, iptables), что было бы намного проще.
Требование, которое вы заявили для подключения к точке перед принятием, возможно с Java-сервером, но это особый вид усилий, когда вы расширяете базовую работу Java-сетей и поведение Socket.
В качестве альтернативы вы можете просто переопределить метод конфигурации (Socket socket) ServerConnector. Если вы хотите отказаться от сокета, просто закройте соединение. Это может вызвать некоторые странные исключения, если так, сообщите о них в bugzilla, и мы исправим.
Альтернативно В качестве альтернативы откройте bugzilla и попросите нас сделать принятый метод (Socket socket) защищенным, а не приватным, и вы можете отклонить его там.
Обратите внимание, что с любым из них клиент увидит соединение как принятое, а затем сразу же закрыто.