para - ver puertos abiertos linux netstat
¿cómo investigar los puertos abiertos por un cierto proceso en Linux? (7)
Supongamos que ya se conoce el PID del proceso
Como nota al margen, netstat -ao leerá / proc / PID / tcp etc. para ver los puertos abiertos por el proceso. Esto significa que su información de lectura es suministrada por el sistema (el lintern KERNEL), y de ninguna manera está buscando directamente en la interfaz de red u otros medios. Lo mismo ocurre con lsof.
Si estás haciendo esto como una medida de seguridad, fallaste. Nunca (NUNCA) DEBERÁ confiar en el resultado de netstat, incluso si está 100% seguro de que está ejecutando realmente un programa netstat real (a diferencia de una versión troyatada) o cualquier otro programa que lea el sistema de archivos / proc. Algunas personas parecen pensar que netstat, ls, ps o cualquier otra de las herramientas estándar de Unix hacen algún tipo de información de magia y encuesta de las fuentes, la verdad es que todos ellos confían en el sistema de archivos / proc para obtener todos sus datos, que puede ser subvertido fácilmente por un rootkit o hipervisor.
Con ls puedes conocer la ruta del proceso.
Ejemplo:
fuser 25/tcp
El comando fuser dice que el proceso es: 2054
ls -l /proc/2054/exe
La ruta del proceso aparece
Extraído de: https://www.sysadmit.com/2018/06/linux-que-proceso-usa-un-puerto.html
En algunos dispositivos integrados o con una versión anterior de Linux, el problema es netstat
no tiene opciones de --process
o -p
disponibles.
La siguiente secuencia de comandos muestra el proceso con su IP y puerto, debe ser root.
#!/bin/bash
for protocol in tcp udp ;
do
#echo "protocol $protocol" ;
for ipportinode in `cat /proc/net/tcp | awk ''/.*:.*:.*/{print $2"|"$3"|"$10 ;}''` ;
do
#echo "#ipportinode=$ipportinode"
inode=`echo "$ipportinode" | cut -d"|" -f3` ;
if [ "#$inode" = "#" ] ; then continue ; fi
lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:/[$inode/]" 2>/dev/null` ;
pid=`echo "lspid=$lspid" | awk ''BEGIN{FS="/"} /socket/{print $3}''` ;
if [ "#$pid" = "#" ] ; then continue ; fi
exefile=`ls -l /proc/$pid/exe | awk ''BEGIN{FS=" -> "}/->/{print $2;}''`
#echo "$protocol|$pid|$ipportinode"
echo "$protocol|$pid|$ipportinode|$exefile" | awk ''
BEGIN{FS="|"}
function iphex2dec(ipport){
ret=sprintf("%d.%d.%d.%d: %d","0x"substr(ipport,1,2),"0x"substr(ipport,3,2),
"0x"substr(ipport,5,2),"0x"substr(ipport,7,2),"0x"substr(ipport,10,4)) ;
if( ret == "0.0.0.0:0" ) #compatibility others awk versions
{
ret= strtonum("0x"substr(ipport,1,2)) ;
ret=ret "." strtonum("0x"substr(ipport,3,2)) ;
ret=ret "." strtonum("0x"substr(ipport,5,2)) ;
ret=ret "." strtonum("0x"substr(ipport,7,2)) ;
ret=ret ":" strtonum("0x"substr(ipport,10)) ;
}
return ret ;
}
{
print $1" pid:"$2" local="iphex2dec($3)" remote="iphex2dec($4)" inode:"$5" exe=" $6 ;
}
'' ;
#ls -l /proc/$pid/exe ;
done ;
done
El resultado es como:
tcp pid:1454 local=1.0.0.127:5939 remote=0.0.0.0:0 inode:13955 exe=/opt/teamviewer/tv_bin/teamviewerd
tcp pid:1468 local=1.1.0.127:53 remote=0.0.0.0:0 inode:12757 exe=/usr/sbin/dnsmasq
tcp pid:1292 local=0.0.0.0:22 remote=0.0.0.0:0 inode:12599 exe=/usr/sbin/sshd
tcp pid:4361 local=1.0.0.127:631 remote=0.0.0.0:0 inode:30576 exe=/usr/sbin/cupsd
tcp pid:1375 local=1.0.0.127:5432 remote=0.0.0.0:0 inode:12650 exe=/usr/lib/postgresql/9.3/bin/postgres
He agregado compatibilidad con IPv6 e hice algunas correcciones. Además, en mi sistema los octetos de la dirección IP están invertidos. Las dependencias son solo para posix shell, awk y cut.
Mi versión se puede encontrar en Github
#!/bin/sh
# prints all open ports from /proc/net/*
#
# for pretty output (if available) start with
# ./linux-get-programm-to-port.sh | column -t -s $''/t''
#set -x
ip4hex2dec () {
local ip4_1octet="0x${1%???????????}"
local ip4_2octet="${1%?????????}"
ip4_2octet="0x${ip4_2octet#??}"
local ip4_3octet="${1%???????}"
ip4_3octet="0x${ip4_3octet#????}"
local ip4_4octet="${1%?????}"
ip4_4octet="0x${ip4_4octet#??????}"
local ip4_port="0x${1##*:}"
# if not used inverse
#printf "%d.%d.%d.%d:%d" "$ip4_1octet" "$ip4_2octet" "$ip4_3octet" "$ip4_4octet" "$ip4_port"
printf "%d.%d.%d.%d:%d" "$ip4_4octet" "$ip4_3octet" "$ip4_2octet" "$ip4_1octet" "$ip4_port"
}
# reoder bytes, byte4 is byte1 byte2 is byte3 ...
reorderByte(){
if [ ${#1} -ne 8 ]; then echo "missuse of function reorderByte"; exit; fi
local byte1="${1%??????}"
local byte2="${1%????}"
byte2="${byte2#??}"
local byte3="${1%??}"
byte3="${byte3#????}"
local byte4="${1#??????}"
echo "$byte4$byte3:$byte2$byte1"
}
# on normal intel platform the byte order of the ipv6 address in /proc/net/*6 has to be reordered.
ip6hex2dec(){
local ip_str="${1%%:*}"
local ip6_port="0x${1##*:}"
local ipv6="$(reorderByte ${ip_str%????????????????????????})"
local shiftmask="${ip_str%????????????????}"
ipv6="$ipv6:$(reorderByte ${shiftmask#????????})"
shiftmask="${ip_str%????????}"
ipv6="$ipv6:$(reorderByte ${shiftmask#????????????????})"
ipv6="$ipv6:$(reorderByte ${ip_str#????????????????????????})"
ipv6=$(echo $ipv6 | awk ''{ gsub(/(:0{1,3}|^0{1,3})/, ":"); sub(/(:0)+:/, "::");print}'')
printf "%s:%d" "$ipv6" "$ip6_port"
}
for protocol in tcp tcp6 udp udp6 raw raw6;
do
#echo "protocol $protocol" ;
for ipportinode in `cat /proc/net/$protocol | awk ''/.*:.*:.*/{print $2"|"$3"|"$10 ;}''` ;
do
#echo "#ipportinode=$ipportinode"
inode=${ipportinode##*|}
if [ "#$inode" = "#" ] ; then continue ; fi
lspid=`ls -l /proc/*/fd/* 2>/dev/null | grep "socket:/[$inode/]" 2>/dev/null` ;
pids=`echo "$lspid" | awk ''BEGIN{FS="/"} /socket/{pids[$3]} END{for (pid in pids) {print pid;}}''` ; # removes duplicats for this pid
#echo "#lspid:$lspid #pids:$pids"
for pid in $pids; do
if [ "#$pid" = "#" ] ; then continue ; fi
exefile=`ls -l /proc/$pid/exe | awk ''BEGIN{FS=" -> "}/->/{print $2;}''`;
cmdline=`cat /proc/$pid/cmdline`
local_adr_hex=${ipportinode%%|*}
remote_adr_hex=${ipportinode#*|}
remote_adr_hex=${remote_adr_hex%%|*}
if [ "#${protocol#???}" = "#6" ]; then
local_adr=$(ip6hex2dec $local_adr_hex)
remote_adr=$(ip6hex2dec $remote_adr_hex)
else
local_adr=$(ip4hex2dec $local_adr_hex)
remote_adr=$(ip4hex2dec $remote_adr_hex)
fi
echo "$protocol pid:$pid /t$local_adr /t$remote_adr /tinode:$inode /t$exefile $cmdline"
done
done
done
Puede usar la herramienta de línea de comando netstat con el argumento de línea de comando -p
:
-p
(Linux):Proceso: muestre qué procesos están usando qué sockets (similar a
-b
en Windows). Debes ser root para hacer esto.
La sección de ejemplo brinda este ejemplo:
Para mostrar todos los puertos abiertos por un proceso con id
$PID
:
netstat -ao | grep ''/b''$PID''/b''
Puedes usar el siguiente comando:
lsof -i -P |grep pid
netstat --all --program | grep ''3265''
-
--all
enchufes para escuchar y los que no. -
--program
muestra el PID y el nombre del programa al que pertenece el socket.
También podría usar un escáner de puertos como Nmap.