Manualmente fechando uma porta da linha de comando

95

Eu quero fechar uma porta aberta que está em modo de escuta entre o meu aplicativo cliente e servidor.

Existe alguma opção de linha de comando manual no Linux para fechar uma porta?

NOTA: eu vim a saber que "apenas a aplicação que possui o socket ligado deve fechá-lo, o que acontecerá quando a aplicação terminar."

Eu não entendo porque isso só é possível pelo aplicativo que o abre ... Mas ainda estou ansioso para saber se existe alguma outra maneira de fazê-lo.

    
por Glorfindel 06.04.2010 / 05:39

13 respostas

114

Eu tive o mesmo problema, o processo deve manter-se vivo, mas o socket deve fechar. Fechar um soquete em um processo em execução não é impossível, mas é difícil:

  1. localize o processo:

    netstat -np
    

    Você recebe um source/destination ip:port portstate pid/processname map

  2. localize o descritor de arquivo do soquete no processo

    lsof -np $pid
    

    Você obtém uma lista: nome do processo, pid, user, fileDescriptor, ... uma string de conexão.

    Localize o número correspondente de fileDescriptor para a conexão.

    Agora conecte o processo:

    gdb -p $pid
    
  3. Agora feche o soquete:

    call close($fileDescritor)
    
    //does not need ; at end.
    

    Em seguida, destaque:

    quit
    

    E o soquete está fechado.

por 01.11.2013 / 02:43
74

Você está fazendo a pergunta errada aqui. Não é realmente possível simplesmente "fechar uma porta" de fora do aplicativo que abriu o soquete escutando. A única maneira de fazer isso é matar completamente o processo que possui a porta. Então, em cerca de um minuto ou dois, a porta ficará disponível novamente para uso. Aqui está o que está acontecendo (se você não se importa, pule para o final, onde mostrarei como matar o processo que possui uma porta específica):

Portas são recursos alocados pelo SO para diferentes processos. Isso é semelhante a perguntar ao SO por um ponteiro de arquivo. No entanto, ao contrário dos ponteiros de arquivo, somente UM processo por vez pode possuir uma porta. Através da interface do socket BSD, os processos podem fazer um pedido para escutar em uma porta, que o SO irá então conceder. O sistema operacional também garante que nenhum outro processo receba a mesma porta. A qualquer momento, o processo pode liberar a porta fechando o soquete. O SO irá então recuperar a porta. Como alternativa, se o processo terminar sem liberar a porta, o SO acabará recuperando a porta (embora isso não aconteça imediatamente: levará alguns minutos).

Agora, o que você deseja fazer (basta fechar a porta na linha de comando) não é possível por dois motivos. Primeiro, se fosse possível, significaria que um processo poderia simplesmente roubar o recurso de outro processo (a porta). Isso seria uma política ruim, a menos que restritas a processos privilegiados. A segunda razão é que não está claro o que aconteceria com o processo que possuía a porta se a deixássemos continuar em execução. O código do processo é escrito assumindo que possui este recurso. Se nós simplesmente o retirássemos, ele acabaria caindo sozinho, então os sistemas operacionais não permitem que você faça isso, mesmo que você seja um processo privilegiado. Em vez disso, você deve simplesmente matá-los.

De qualquer forma, aqui está como matar um processo que possui uma porta específica:

sudo netstat -ap | grep :<port_number>

Isso gerará a linha correspondente à porta de retenção do processo, por exemplo:

tcp  0  0 *:8000   *:* LISTEN  4683/procHoldingPort

Neste caso, procHoldingPort é o nome do processo que abriu a porta, 4683 é o seu pid, e 8000 (note que é TCP) é o número da porta que ele contém.

Então, olhe na última coluna, você verá /. Então execute isto:

kill  <pid>

Se isso não funcionar (você pode verificar executando novamente o comando netstat). Faça isso:

kill -9 <pid>

Em geral, é melhor evitar enviar SIGKILL se puder. É por isso que eu digo para você tentar kill antes de kill -9 . Apenas usando kill envia o gentil SIGTERM.

Como eu disse, ainda levará alguns minutos para a porta reabrir, se você fizer isso. Eu não sei como acelerar isso. Se alguém o fizer, adoraria ouvir.

    
por 06.04.2010 / 06:05
18

O fusor também pode ser usado

fuser -k -n *protocol portno*

Aqui o protocolo é tcp / udp e portno é o número que você deseja fechar. Por exemplo,

fuser -k -n tcp 37

Mais informações em página de manual do fuser

    
por 13.02.2012 / 09:44
5

Você pode alternativamente usar o iptables:

iptables -I INPUT -p tcp --dport 80 -j DROP

Basicamente, ele realiza o que você quer. Isso eliminará todo o tráfego TCP na porta 80.

    
por 06.04.2010 / 11:38
3
netstat -anp | grep 80

Ele deve informar, se você estiver executando o apache, "httpd" (este é apenas um exemplo, use a porta que seu aplicativo está usando em vez de 80)

pkill -9 httpd 

ou

killall -9 httpd
    
por 06.04.2010 / 05:45
2

Você provavelmente poderia descobrir qual processo abriu o soquete que a porta é associado e elimine esse processo.

Mas, você teria que perceber que a menos que esse processo tem um manipulador que não inicializa todas as coisas que estava usando (aberto arquivos, soquetes, garfos, coisas que podem permanecer a menos que sejam fechadas corretamente na finalização) então você teria criado esse arrasto no desempenho do sistema. Além disso, o soquete permanecerá aberto até que o kernel perceba que o processo foi morto. Isso geralmente só leva cerca de um minuto.

Suponho que a melhor pergunta seria: qual porta (pertencente a que processo) você quer parar?

Se você está tentando colocar um fim em um backdoor ou vírus que você encontrou, então você deve pelo menos aprender quais dados estão indo e voltando antes de terminá-lo. (wireshark é bom para isso) (E o nome executável do processo para que você possa excluí-lo e impedir que ele seja reiniciado) ou, se for algo que você instalou (como HTTPD ou FTPD ou algo assim), você já deve ter acesso a o processo em si.

Normalmente, ele terá um programa de controle (HTTPD stop | start ou algo assim). Ou, se é uma coisa do sistema, você provavelmente não deve mexer com isso. De qualquer forma, eu pensei que desde que todo mundo está dando a você o "como fazer" ângulo, eu deveria dar-lhe as advertências.

    
por 22.04.2012 / 07:02
2

Eu primeiro procurei pelos processos mongo e node e fiz o seguinte:

ps -A | grep node

10418 pts/23   00:00:05 node

10551 pts/23   00:00:00 node

ps -A | grep mongo

10490 pts/23   00:00:00 mongod

Uma vez identificado, apenas mate os processos com o comando kill.

kill -9 10418
kill -9 10490

Por fim, digite meteor e ele deve estar funcionando novamente.

    
por 27.05.2015 / 05:46
1

Você pode escrever um script que modifique o iptables e reinicie-o. Um script para adicionar uma regra descartando todos os pacotes na porta, outro script para remover essa regra.

As outras respostas mostraram como matar o processo ligado à porta - isso pode não ser o que você deseja. Se você quiser que o servidor continue em execução, mas para evitar conexões de clientes, você deseja bloquear a porta e não interromper o processo.

    
por 06.04.2010 / 06:10
1

Mais um problema: em algum momento, o kernel possui as próprias portas. Eu sei que o roteamento NAT mantém algumas portas abertas para o uso do NAT. Você não pode matar um processo para isso, isso é um kernel, e uma reconfiguração e uma reinicialização são necessárias.

    
por 01.11.2013 / 03:08
1

Se você deseja que sua porta seja lançada mais cedo, é necessário definir o seguinte valor:

echo 1 > /proc/sys/net/ipv4/tcp_fin_timeout

para definir de 60 segundos (padrão) a 1 segundo

    
por 23.04.2015 / 08:06
1

Você pode usar o comando chamado killcx, fechando uma conexão sem que nenhum processo seja eliminado.

  • sintaxe:
killcx [dest_ip:dest_port] {interface}

  dest_ip              : remote IP
  dest_port            : remote port
  interface (optional) : network interface (eth0, lo etc).
  • exemplo:
killcx 120.121.122.123:1234
killcx 120.121.122.123:1234 eth0
    
por 29.07.2015 / 04:25
1

Estou ciente de que esta resposta não responde à pergunta em si, estritamente falando, mas lendo isso pode ser uma informação relevante:

O comportamento padrão de ligar um soquete a uma porta (e endereço) é que quando o soquete é fechado pela interrupção abrupta do processo, o soquete permanecerá em TIME_WAIT por um tempo. Isso significa que você não pode se religar imediatamente a este endereço / porta. Se você está desenvolvendo o próprio sistema através da interface de socket BSD padrão, você pode (pelo menos até certo ponto) controlar este comportamento com a opção de socket SO_REUSEADDR. Isso basicamente permitirá que você conecte novamente ao mesmo endereço / porta se o soquete estiver no status TIME_WAIT. Ainda assim, um soquete por porta!

No entanto, esta informação só deve ser usada como ajuda ao desenvolvimento, uma vez que existe uma razão para existir TIME_WAIT, já explicado nas outras respostas.

    
por 15.10.2015 / 10:45
0

Se você não quiser tráfego sobre o soquete, mas quiser manter vivo o processo: tcpkill .

tcpkill -i eth0 host xxx.xxx.xxx.xxx and port yyyy

Inicia um daemon sniffing que intercepta e elimina todo o tráfego nessa porta. Muito útil para testar seus aplicativos para divisões de rede.

    
por 30.03.2016 / 12:02