Как сделать так, чтобы сокет принимал соединения только с локального хоста (на Java)?

У меня есть java-приложение (не работающее ни в одном контейнере приложений), которое прослушивает ServerSocket для соединений. Я хотел бы, чтобы он принимал только соединения, которые исходят от локального хоста. В настоящее время после того, как соединение принято, он проверяет одноранговый IP-адрес и отклоняет его, если это не петлевой адрес, но я знаю, что одноранговые IP-адреса могут быть подделаны. Итак, если возможно, я бы предпочел привязаться к сокету, который прослушивает только петлевой интерфейс; Это возможно?

Я пробовал несколько разных вещей (например, указывать «127.0.0.1» в качестве локального адреса при вызове bind()) безуспешно. Заранее спасибо.


Спасибо за вашу помощь. Мне стыдно признаться, что все это было моей ошибкой. Наше приложение прослушивает два разных порта, и я привязывал один к петлевому интерфейсу, но тестировал другой. Когда я на самом деле пытаюсь подключиться к правильному порту через telnet, все работает нормально (т. е. привязка к «127.0.0.1» делает именно то, что и должно).

Что касается подмены петлевого адреса, вы, ребята, правы. Я не должен был преподносить это как главную заботу. На самом деле желаемое поведение состоит в том, чтобы принимать только локальные соединения, и привязка только к локальному интерфейсу является более прямым способом достижения этого, чем принятие всех соединений и последующее закрытие нелокальных.


person Community    schedule 19.09.2008    source источник
comment
Откуда вы взяли информацию, что 127.0.0.1 можно подделать? Я настроен скептически.   -  person Stu Thompson    schedule 19.09.2008


Ответы (5)


IP-адреса одноранговых узлов не могут быть подделаны таким образом, вам нечего опасаться использования метода проверки однорангового узла и принятия решения о разрыве соединения во время установления.

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

person Jerub    schedule 19.09.2008

Если адрес пира подделан, то больше ничего сделать нельзя.

Однако подделать 127.0.0.1 непросто. У вас должен быть достаточно тупой стек TCP/IP, чтобы принять такой пакет. У спуфера не было бы возможности получать пакеты обратно. В хорошем стеке TCP/IP он не должен угадывать порядковые номера, чтобы не успевать за ожидаемым диалогом.

person Tom Hawtin - tackline    schedule 19.09.2008

Вы могли бы, как вы уже, кажется, делаете, принять () соединение в любом случае, а затем использовать getInetAddress (), чтобы убедиться, что адрес является авторизованным. Если нет, просто закройте() сокет сразу. 127.0.0.1 не адрес, который можно подделать.

В качестве альтернативы вы можете установить свой собственный менеджер безопасности, у которого будет вызываться метод checkAccept() с адресом и портом удаленного сайта. Это немного сложнее - я никогда не пробовал, так как первое решение всегда было адекватным для меня.

person paxdiablo    schedule 19.09.2008
comment
Оригинальный плакат уже сказал, что он это делает, но не хочет, потому что удаленную сторону можно «подделать» или что-то в этом роде. - person Jerub; 19.09.2008
comment
Джеруб: ОП не понимает спуфинга. Пакс: Подойдет любой старый менеджер безопасности, вам просто нужно установить политику, дающую коду правильные разрешения (разрешение java.net.SocketPermission 127.0.0.1 прослушивать, принимать или что-то в этом роде — нужно перехватывать SecurityException из accept). - person Tom Hawtin - tackline; 19.09.2008

Когда вы привязываете свой ServerSocket, указание localhost должно заставить стек TCP/IP отклонить соединение. Даже если это не работает в вашей системе, локальный хост не может быть подделан (хорошо, может быть, если кто-то взломал ваш стек TCP/IP и маршрутизатор шлюза по умолчанию), поскольку этот адрес не маршрутизируется через физический интерфейс.

Мне любопытно, почему ваша привязка не удалась, какая у вас ОС, версия Java и т. д.?

person Steve Moyer    schedule 19.09.2008

person    schedule
comment
Хотя код самовыражается, ответы, содержащие только код, не приветствуются. Рассмотрите возможность добавления ссылок на документацию, что он делает и так далее. - person edmz; 14.07.2015