28.9.11

/bin/rm: Argument list too long - Como solucionarlo.

hoy me volvi a encontrar con este problema y me decidi a escibir una entrada para los q se lo encuentran x 1era vez... la 1era vez suele ser traumatica... xD

uno de los servers en los q trabajo esta todo el tiempo bajando datos q almacena en un directorio del sistema generando una gran cantidad de archivos q se van acumulando bastante rapido. dado q no uso personalmente los datos y no tengo muy claro hasta cuando sirven, suelo dejar q se acumulen hasta q el espacio en disco empieza a escasear y ahi es cuando viene el problema. la cantidad de archivos es tan grande q al intentar algo tan simple como un rm *.* la consola me devuelve:

/bin/rm: Argument list too long


el problema

como decia antes suele ser bastante traumatico encontrarse con q no se puede hacer algo tan basico como borrar archivos. buscando tanto la solucion como la causa me encontre con la interesante explicacion de que no es un problema del comando en si sino del kernel de linux.

traduccion de la debian wiki:

el limite afecta la funcion execve() del kernel, q es usada x todas las otras funciones exec() (execl, execlp, execle,etc). La funcion trabaja creando un buffer de 128k al final del espacio de memoria y copiando el comando y el entorno para el nuevo proceso en este espacio. entonces el kernel carga el nuevo programa en memoria, setea sus punteros argv y endv, y salta al punto de entrada del programa. El mensaje de error "argument list too long" es causado por el codigo de error !E2BIG, siendo devuelto por la funcion execve(), cuando es incapaz de introducir el argumento y entorno suministrados dentro del buffer de 128k.

x suerte el usuario normal no tiene q luchar normalmente con directorios q contienen tantos archivos... entonces me dio curiosidad de ver de cuantos archivos hablamos en realidad (mientras escribo esto voy haciendo el proceso), entonces meto en la consola:

# ls | wc -l

... y despues de un buen rato me devuelve... 1146724!!


la solucion

para poder borrar los archivos lo q tenemos q hacer es pasarselos a rm como argumento de a poco usando xargs. la linea q recomienda la misma debian wiki es esta:

find ./ -name '*' -print0 | xargs -0 -n 10 rm

hacemos un find de todos los archivos (*) y x medio de xargs se los vamos pasando a rm de a 10 (-n 10). el "-print0" en find y el -0 en xargs son para no tener problemas con los espacios en blanco de los archivos si es q los tienen, sino se pueden eliminar.

hay otras soluciones posibles como ls | xargs rm o ir borrando x partes pero la anterior es la mas simple y efectiva.

19.9.11

Port Forwarding - Como "abrir" puertos en cualquier router.

una de las preguntas de redes mas vistas en internet es "como abro mis puertos?", el proceso es bastante facil, pero el usuario q se encuentra x 1era vez con este tema puede llegar a tener problemas, no solo por el proceso en si, sino xq la mayoria de las veces no tiene idea de lo q esta haciendo. la masificacion del uso de routers en los ultimos años, dado el aumento de LANs (Local Area Network o "redes caseras"), trajo este "problema" q no existia (ni existe hoy dia) con los modems.

todos los routers tienen diferentes menus de configuracion pero el contenido es siempre mas o menos igual aunque no este en el mismo lugar exacto... solo hay q buscar un poco. esta guia es gral y sirve para cualquier marca/modelo, el nivel es practicamente 0 asi q todos lo van a entender. los conceptos de red obviamente son los mismos para cualquier dispositivo y la intencion final es q sepan lo q estan haciendo al "forwardear" (no "abrir") un puerto... ademas de aprender a hacerlo x supuesto.

para informacion mas detallada sobre los menus de configuracion de cada router existen varias paginas, de las cuales la q encuentro mas completa es:

http://portforward.com/

se puede elegir marca/modelo y siguiendo los pasos tambien el servicio a configurar.


q es un puerto?

un puerto logico, q es del q hablamos, puede ser considerado como una via de comunicacion entre dos programas, q normalmente estan en dos maquinas distintas, pero no siempre es asi... aunque esto no viene al caso ahora.

un numero de puerto esta compuesto x un numero de 16bits, lo cual nos da un total de 65535 (hffff) puertos posibles. de estos los 1eros 1024 son considerados "puertos bajos" (o well-known-ports) y 1024-65535 "puertos altos". los bajos son los comunmente usados en los servicios mas conocidos, x ej:

21 FTP
22 SSH
23 TELNET
25 SMTP (envio de correo)
53 DNS
80 HTTP
110 POP3 (lectura de correo)
137-139 NETBIOS

se puede consultar la lista completa aca:

http://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml


hay muchos otros servicios considerados "normales" hoy dia q usan puertos mucho mas altos como el remote desktop de win x ejempo (3389), vnc (5900) o cualquier messenger o esas porquerias. a pesar de existir un standard, en la practica se puede hacer correr un servicio en cualquier puerto, lo cual muchas veces es util para ocultarlo un poco.

ya sabemos entonces q un puerto es un acceso para comunicacion, q es identificado por un numero y que necesitamos dos partes para establecer la conexion. en estas dos partes esta la mayor parte de la confusion de la mayoria... una parte es el servidor y la otra es el cliente. el servidor, como su nombre lo indica es el q ofrece el servicio y el cliente el q lo solicita. cuando abrimos una pagina web, la maquina donde se aloja corre el servidor en su puerto 80 y la nuestra se conecta x medio del cliente (el navegador) a traves de un puerto aleatorio estableciendo la conexion.

al mismo tiempo, el mismo servidor puede estar corriendo FTP y podriamos conectar a el x el puerto 21 y asi con el resto de los puertos/servicios. todo esto parece no tener mucha relacion para abrir puertos para un troyano o el emule pero la teoria es la misma asi q sigan leyendo...


el router

este maravilloso aparato nos permite compartir la conexion entre las maquinas de nuestra red hogareña x medio del protocolo NAT (Network Adress Translation), haciendo q todas esten conectadas a internet... salvo x el pequeño detalle de las aplicaciones q necesitan sus puertos expuestos al exterior...

no voy a explicar lo q es una direccion ip (aca pueden leer algo... http://locvtvs.blogspot.com/2010/12/arpageddon-ipcalipsis-o-como-lo-quieran.html) ni lo q es nat... pero alcanza con saber q cada dispositivo conectado a una red debe tener una ip para identificarlo... y q dentro de esta direccion se encuentran contenidos los 65535 puertos. tenemos dos tipos de direcciones, publicas y privadas, las 1eras son las que se usan en internet y las 2das en una red local (la mayoria de las veces del rango 192.168.x.x). para saber nuestra ip publica podemos verla desde alguna pagina de internet como:

http://ip-adress.com

y para saber la interna basta con abrir una consola y poner "ipconfig" en windows o "ifconfig" en linux.

el problema x el cual tenemos q "forwardear" los puertos es q la unica direccion visible desde internet es la ip publica y esta la tiene el router, q es el dispositivo q en realidad esta conectado, nosotros estamos "detras" de el y tenemos una direccion q solo es visible para las maquinas de nuestra red (y el mismo router). en lo q se refiere a "salir" hacia el exterior no tiene diferencia para lo q nos interesa, pero cuando se requiere q la otra aplicacion conecte con nuestra maquina se encuentra con el obstaculo del router ya que el puerto esta en el (ip publica), y no en nuestra maquina.

q es lo q hacemos entonces? redirigirlo hacia nuestra ip privada x supuesto...


port forwarding

en realidad el termino "abrir un puerto" es una mala traduccion de "forward a port" o el mas conocido "port forwarding" q en este caso en particular podria ser traducido como "reenviar un puerto" o "redireccionarlo".

con este proceso hacemos q cuando una aplicacion exterior busca X puerto lo haga en la maquina q queremos nosotros y no en el router, imaginense un tunel q conecta el puerto del router al correspondiente en la pc server. supongamos q queremos instalar un servidor web y q sea visible desde internet, instalamos y configuramos la ultima version de apache (o el q les guste), checkeamos antes q nada q funcione localmente poniendo 127.0.0.1 (localhost) en nuestro navegador, averiguamos la ip de la maquina (ipconfig/ifconfig) y vamos a la configuracion el router.

al router se puede ingresar x el navegador o x telnet en muchos casos, el navegador es mas facil asi q solo hay q abrirlo y poner la ip del router... cual es la ip del router??.. je

en win, haciendo el famoso "ipconfig", es la ip q sale en "puerta de enlace" o "gateway". en linux con "route -n".

una vez en la pagina del router va a pedir una pass q me imagino q la tienen o sino fijense en alguna lista de default passwords con la marca/modelo del router. si la cambiaron lo resetean y vuelve a esa misma pass. aca hay una lista bastante completa:

http://www.phenoelit-us.org/dpl/dpl.html

una vez dentro, todos (si... TODOS) los routers tienen un apartado de port forwarding, puede estar bajo muchos nombres pero el formato es siempre:

nombre de la regla
direccion ip de destino
puerto publico
puerto privado
protocolo

puede tener alguno mas pero estos son los necesarios para hacer el forward.


Menu de configuracion en Linksys

nombre de la regla: es solo una etiqueta, le pueden poner el nombre q quieran... seria bueno ponerle uno q recuerde lo q hace... ;)


direccion ip de destino: es la direccion de la maquina en la red interna a la cual queremos redirigir el puerto.

puerto publico: el puerto del router q queremos redirigir (x ej el 80 en el caso de un servidor web)

puerto privado: el puerto en la maquina. x lo gral ponemos el mismo q el publico pero se pueden llegar a crear reglas mas avanzadas redirigiendo un puerto a otro. x ejemplo podemos hacer q el servidor web corra en el puerto 30000 localmente, en ese caso pondriamos 30000 en este campo y el 80 seria redirigido a este de manera transparente para el cliente q conecta desde internet... para este la conexion seria normal, al 80.

protocolo (tcp/udp/both): tcp y udp son protocolos de transporte de datos, son los q llevan la informacion de un puerto a otro. para hacerlo rapido, las aplicaciones para las cuales queremos abrir puertos pueden usar tcp, udp o ambos, x lo gral en las instrucciones del soft se indica cual se debe abrir y sino funciona simplemente prueben con both (ambos).

Menu de configuracion en DLink


explicando un poco mejor la diferencia, tcp (Transmission Control Protocol) es el mas usado ya que posee control de flujo, el cual facilita la correccion de errores. cuando un paquete es enviado corre peligro de sufrir una colision, la cual haria q no llegue a destino, en ese caso el cliente vuelve a pedir el paquete al server hasta tener la informacion completa.

Menu de configuracion en 3com

udp (User Datagram Protocol) es mas usado x aplicaciones de streaming, asi tambien como troyanos y ataques DoS entre otras cosas, en resumen nada q requiera 100% de fiabilidad en los datos. lo q si ofrece udp es mucha velocidad, al no tener q preocuparse de checkear y reenviar paquetes.


caso practico

vamos a suponer ahora q queremos instalar un server de ftp en nuestra pc y q sea accesible desde internet mientras estamos en nuestra red local, detras de un router.

sabemos q el sevicio ftp usa el puerto 21, x lo tanto ese es el q tenemos q forwardear (o "abrir" hablando mal). abrimos una consola y con ipconfig vemos nuestra ip y la del router como explique mas arriba. vamos a suponer entonces q nuestra ip es 192.168.1.51 y la del router 192.168.1.1.

abrimos el navegador y le ponemos la ip del router (192.168.1.1), nos lleva a la pantalla de logueo donde ingresamos user/pass. una vez dentro buscamos el menu de forwarding y creamos una nueva regla:

nombre: FTP (o lo q quieran)
direccion ip: 192.168.1.51 (la de la pc q corre el server ftp)
puerto exterior: 21 (puede aparecer como "external", "public", "start" o algunas otras)
puerto interior: 21 (tambien puede salir con otro nombre o en otros casos como en algunos tp-link no aparecer)
protocolo: TCP (el FTP usa solamente TCP, poniendo "both" funcionaria igual pero... para q abrir algo q no vamos a usar?)

guardar la configuracion y el server ya deberia ser accesible desde internet. cambiando direcciones ip y puertos x los adecuados, el mismo proceso sirve para cualquier aplicacion, ya sea p2p, juegos online, troyanos o un server como el del ejemplo.


firewall, dmz y algunos otros conceptos

ademas de forwardear el puerto debemos, ahora si, "abrirlo" en el/los firewall q esten en la red. seria muy largo explicar lo q es un firewall y creo q el q lee esto, tratando de forwardear puertos, ya sabe lo q es. obviamente si el puerto esta forwardeado pero cerrado en el firewall nunca se va a establecer la conexion, asi q hay q abrirlo en el q usemos en nuestro sistema (firewall de xp, iptables, algun av o lo q sea) y si hay otro firewall en el router o cualquier otro dispositivo q se encuentre entre nosotros y el exterior hacer lo mismo en este.

la opcion DMZ (De Militarized Zone) o "zona desmilitarizada" sirve para exponer todos los puertos de un dispositivo hacia el exterior como si estuviera conectado a un simple modem. si activamos esta opcion no tenemos q preocuparnos de forwardear nada ya q todo esta abierto al exterior... de lo q si tenemos q preocuparnos es de tanta exposicion, esta opcion no es para nada segura y no recomiendo usarla salvo para propositos de testeo o bien q sepan lo q estan haciendo.