Quiero cerrar un puerto abierto que esté en modo de escucha entre mi cliente y la aplicación del servidor.
¿Hay alguna opción de línea de comando manual en Linux para cerrar un puerto?
NOTA: Llegué a saber que "solo la aplicación que posee el socket conectado debe cerrarlo, lo que sucederá cuando la aplicación finalice".
No entiendo por qué solo es posible mediante la aplicación que lo abre ... Pero todavía estoy ansioso por saber si hay otra forma de hacerlo.
Respuestas:
Tuve el mismo problema, el proceso debe mantenerse vivo pero el zócalo debe cerrarse. Cerrar un socket en un proceso en ejecución no es imposible pero difícil:
ubica el proceso:
Obtienes un
source/destination ip:port portstate pid/processname
mapalocalizar el descriptor de archivo del socket en el proceso
Obtiene una lista: nombre de proceso, pid, usuario, fileDescriptor, ... una cadena de conexión.
Localice el número de descriptor de archivo correspondiente para la conexión. Será algo así como "97u", que significa "97".
Ahora conecta el proceso:
Ahora cierre el zócalo:
ejemplo:
Luego separe gdb:
Y el zócalo está cerrado.
fuente
sudo lsof -np $pid
me da unas 200 líneas y estoy confundido acerca de cómo encontrar el FD deseado. En mi caso, el proceso es una pestaña de Chrome y estoy tratando de cerrar los websockets abiertos ...shutdown
:call shutdown($fileDescriptor, 0)
.Estás haciendo una pregunta equivocada aquí. Realmente no es posible simplemente "cerrar un puerto" desde fuera de la aplicación que abrió el socket escuchando en él. La única forma de hacerlo es eliminar por completo el proceso que posee el puerto. Luego, en aproximadamente un minuto o dos, el puerto volverá a estar disponible para su uso. Esto es lo que está sucediendo (si no te importa, salta al final donde te muestro cómo matar el proceso que posee un puerto en particular):
Los puertos son recursos asignados por el sistema operativo a diferentes procesos. Esto es similar a pedirle al sistema operativo un puntero de archivo. Sin embargo, a diferencia de los punteros de archivo, solo UN proceso a la vez puede tener un puerto. A través de la interfaz de socket BSD, los procesos pueden hacer una solicitud para escuchar en un puerto, que luego el sistema operativo otorgará. El sistema operativo también se asegurará de que ningún otro proceso tenga el mismo puerto. En cualquier momento, el proceso puede liberar el puerto cerrando el socket. El sistema operativo reclamará el puerto. Alternativamente, si el proceso finaliza sin liberar el puerto, el sistema operativo finalmente recuperará el puerto (aunque no sucederá de inmediato: tomará unos minutos).
Ahora, lo que desea hacer (simplemente cierre el puerto desde la línea de comandos), no es posible por dos razones. Primero, si fuera posible, significaría que un proceso simplemente podría robar el recurso de otro proceso (el puerto). Esta sería una mala política, a menos que esté restringida a procesos privilegiados. La segunda razón es que no está claro qué pasaría con el proceso que poseía el puerto si dejamos que continúe ejecutándose. El código del proceso se escribe asumiendo que posee este recurso. Si simplemente lo quitáramos, terminaría fallando por sí mismo, por lo que los sistemas operativos no le permiten hacer esto, incluso si es un proceso privilegiado. En cambio, simplemente debes matarlos.
De todos modos, aquí se explica cómo matar un proceso que posee un puerto en particular:
Eso generará la línea correspondiente al puerto de retención del proceso, por ejemplo:
En este caso, procHoldingPort es el nombre del proceso que abrió el puerto, 4683 es su pid y 8000 (tenga en cuenta que es TCP) es el número de puerto que posee.
Luego, mira en la última columna, verás /. Entonces ejecute esto:
Si eso no funciona (puede verificarlo volviendo a ejecutar el comando netstat). Hacer esto:
En general, es mejor evitar enviar SIGKILL si puedes. Por eso te digo que lo intentes
kill
anteskill -9
. Solo usandokill
envía la SIGTERM más suave.Como dije, aún se necesitarán unos minutos para que el puerto se vuelva a abrir si haces esto. No sé una manera de acelerar esto. Si alguien más lo hace, me encantaría escucharlo.
fuente
unix.tools.port.close(<my port number>)
yo usaríainit 6
.El fusor también se puede usar
Aquí el protocolo es tcp / udp y portno es el número que desea cerrar. P.ej
Más información en la página de manual de fuser
fuente
fuser
ejecutarse?fuser
encuentra el proceso usando el puerto y lo mata, pero no resuelve el hecho de que el socket no está cerrado. 60 segundos y el núcleo lo hace por mí.Alternativamente, podría usar iptables:
Básicamente logra lo que quieres. Esto soltará todo el tráfico TCP al puerto 80.
fuente
-j REJECT
para devolver el indicador de restablecimiento de TCP, que luego se vería en mi proceso de propiedad (pero solo cuando el otro lado lo intente para enviar algo).Debería decirle, si está ejecutando apache, "httpd" (esto es solo un ejemplo, use el puerto que usa su aplicación en lugar de 80)
o
fuente
Probablemente podría averiguar qué proceso abrió el socket con el que está asociado el puerto y eliminar ese proceso.
Pero, tendría que darse cuenta de que a menos que ese proceso tenga un controlador que inicialice todas las cosas que estaba usando (archivos abiertos, tomas, horquillas, cosas que pueden persistir a menos que se cierre correctamente al finalizar), entonces habría creado eso arrastre el rendimiento del sistema. Además, el socket permanecerá abierto hasta que el kernel se dé cuenta de que el proceso ha finalizado. Eso usualmente solo toma alrededor de un minuto.
Supongo que la mejor pregunta sería: ¿Qué puerto (que pertenece a qué proceso) desea detener?
Si está tratando de poner fin a una puerta trasera o un virus que encontró, al menos debe saber qué datos van y vienen antes de finalizarlos. (Wirehark es bueno para esto) (Y el nombre ejecutable del proceso para que pueda eliminarlo y evitar que vuelva a reiniciarse) o, si es algo que instaló (como HTTPD o FTPD o algo), entonces ya debería tener acceso a El proceso en sí.
Por lo general, tendrá un programa de control (HTTPD stop | start o algo así). O, si es algo del sistema, probablemente no deberías meterte con él. De todos modos, pensé que dado que todos los demás te están dando el ángulo de "cómo hacerlo", debería darte las advertencias.
fuente
Primero busqué los procesos mongo y nodo, luego hice lo siguiente:
Una vez identificado, simplemente elimine los procesos con el comando kill.
Por último, escriba
meteor
y debería estar funcionando nuevamente.fuente
Puede escribir un script que modifique las tablas ip y las reinicie. Un script para agregar una regla que descarte todos los paquetes en el puerto, otro script para eliminar dicha regla.
Las otras respuestas le han mostrado cómo matar el proceso vinculado al puerto; esto puede no ser lo que desea. Si desea que el servidor siga ejecutándose, pero para evitar conexiones de clientes, entonces desea bloquear el puerto, no detener el proceso.
fuente
Un problema más: en algún momento el núcleo posee puertos propios. Sé que el enrutamiento NAT mantiene algunos puertos abiertos para uso NAT. No puede eliminar un proceso para esto, este es un núcleo, y se requiere una reconfiguración y un reinicio.
fuente
Si desea que su puerto se libere antes, debe establecer el siguiente valor:
para configurarlo de 60 segundos (predeterminado) a 1 segundo
fuente
Puede usar el comando llamado killcx, cerrando una conexión sin que se elimine ningún proceso.
fuente
Soy consciente de que esta respuesta no responde a la pregunta en sí misma, estrictamente hablando, pero leerla podría ser información relevante:
El comportamiento predeterminado de vincular un socket a un puerto (y dirección) es que cuando el socket se cierra por la terminación abrupta del proceso, el socket permanecerá en TIME_WAIT por un tiempo. Esto significa que no puede volver a vincular inmediatamente a esta dirección / puerto. Si está desarrollando el sistema en sí a través de la interfaz de socket BSD estándar, puede (al menos hasta cierto punto) controlar este comportamiento con la opción de socket SO_REUSEADDR. Básicamente, esto le permitirá vincularse a la misma dirección / puerto nuevamente si el socket está en estado TIME_WAIT. ¡Todavía hay un zócalo por puerto!
Sin embargo, esta información solo debe usarse como ayuda para el desarrollo, ya que hay una razón para que TIME_WAIT exista en primer lugar, ya explicada en las otras respuestas.
fuente
Si no desea tráfico a través del socket pero quiere mantener vivo el proceso: tcpkill .
Comenzará un demonio de rastreo que intercepta y destruye todo el tráfico en ese puerto. Muy útil para probar sus aplicaciones para divisiones de red.
fuente
Puede cerrar una toma de escucha con ss :
Donde 1234 es su número de puerto.
ss es parte del paquete iproute2, por lo que hay un fuerte cambio, ya está instalado en un Linux moderno.
Aprendí sobre esto de una respuesta a una pregunta relacionada .
fuente