Etiquetas

jueves, 24 de diciembre de 2015

Access Point / Repetidor Wi-Fi con raspberry PI y dongle RTL8192CU

A veces cuando viajamos queremos tener internet en varios dispositivos: notebooks, smartphones, etc y dependemos de un punto de acceso Wi-Fi distante que no tiene buena cobertura entonces contar con un repetidor que enrute el tráfico entre una interfaz (dongle RTL8192CU por ejemplo) y otra interfaz conectada a al wi-fi remota puede ser útil.
Esta entrada en el blog es más bien un paso a paso en español de información que está disponible en ingles. La primera parada en este camino es crear un AP Wi-Fi que enrutee a una red cableada. Luego modificaremos la configuración para hacer bridge a otra interfaz wireless y que la raspberry pi sirva como repetidor Wi-Fi. Para esto utilizaremos hostapd y eventualmente dnsmasq si hay necesidad de que el router (Rpi) asigne direcciones IP.


Antes de comenzar, unas breves palabras sobre el rendimiento de este dispositivo. La raspberry Pi no es el dispositivo ideal si buscamos un router de alto rendimiento. Inevitablemente, el rendimiento será algo menor que un dispositivo dedicado y diseñado para esa función. Dicho esto, invertir tiempo y algo de dinero en este proyecto de fin de semana tiene varias motivaciones: divertirnos en el proceso (habrá que compilar varios softs si usamos un dongle basado en el chipset RTL8192CU) y quizá dispongamos de alguna Raspberry Pi por ahí disponible para la diversión. Dicho sea de paso, siempre se aprende algo sobre networking con estos proyectos, así sean "just for fun".

Primero, crear un router wi-fi y red cableada. Manos a la obra

Para esta primera etapa, que nos servirá para probaer que hayamos configurado correctamente hostapd lo que haremos será: una interfaz wi-fi (ej wlan0) servirá como Access Point al cual se conectarán "clientes" usando encriptación WPA2 y autenticación basada en password. Muy similar a un router comercial convencional.

Primero, siguen las fuentes que me sirvieron para el paso a paso:

http://wannabe-nerd.tweakblogs.net/blog/10870/wifi-access-point-using-a-realtek-8192cu-based-usb-wifi-dongle-with-a-raspberry-pi.html

https://bogeskov.dk/UsbAccessPoint.html

Y especialmente este post me fue de suma utilidad, para mantener las cosas simples:

https://www.raspberrypi.org/forums/viewtopic.php?f=91&t=29752&start=75


Como dije, en mi caso debía usar un dongle marca TP-LINK modelo TL-WN823N, que está basado en el chipset RTL8192CU.

# lsusb
Bus 001 Device 004: ID 0bda:8178 Realtek Semiconductor Corp. RTL8192CU 802.11n WLAN Adapter

Este chipset tiene la particularidad de que el módulo que viene con el kernel no soporta el modo AP. Por lo que es necesario compilar el módulo.
Antes que nada, el "router" precisará que se establezca un bridge (dispositivo de capa 2 similar a un switch) que creará un puente entre dos interfaces. En esta primera etapa, entre wlan0 y eth0.

Instalamos las herramientas para bridges:
# apt-get install bridge-utils

Luego, configuramos la interfaz eth0 y el puente, editando /etc/network/interfaces:

# The loopback network interface
auto lo
iface lo inet loopback


# Setup bridge con bridge
allow-hotplug eth0
iface eth0 inet manual

auto br0
iface br0 inet static
bridge_ports wlan0 eth0
address 192.168.1.19
netmask 255.255.255.0
network 192.168.1.0
## isp router ip, 192.168.1.1 also runs DHCPD ##
gateway 192.168.1.1
dns-nameservers 192.168.1.1

En esta configuración estamos utilizando una dirección fija para la interfaz eth0 y otro dispositivo en la red (con dir 192.168.1.1) será el gateway hacia internet. También ese otro dispositivo se encargará de correr un servidor dhcp, que será el encargado de otorgar direcciones IP a los dispositos que se conecten al router (Raspberry Pi). Si fuera necesario correr el servidor dhcp en le propia raspberry habría que agregar dnsmasq, por ejemplo.

Compilar el modulo adecuado para el 8192CU

Debemos instalar la misma versión de gcc que se haya usado para compilar el kernel, en este caso podemos verla con:

$ cat /proc/version
Linux version 4.1.13+ (dc4@dc4-XPS13-9333) (gcc version 4.8.3 20140303 (prerelease) (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) ) #826 PREEMPT Fri Nov 13 20:13:22 GMT 2015

Instalamos la versión adecuada:

# apt-get update
# apt-get install -y gcc-4.8 g++-4.8

Si este no es la versión default de gcc podemos alterar el symlink de /usr/bin/gcc

Siguiente instalamos rpi-source que es la herramienta que facilita la descarga del código fuente del kernel a nuestro dir home. Véase que mejor usar un usuario sin privilegios:

$ cd ~
$ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

Acto seguido descargamos el source code del kernel

$ rpi-source

En nuestro directorio home, tendremos un directorio con un nombre linux-hash...blah creamos un symlink:

$ cd ~
$ ln -s linux-bc1669c846b629cface0aaa367afb2b9c6226faf linux

Ahora, compilamos el módulo:

cd linux
make mrproper

# config del kernel .config
zcat /proc/config.gz > .config
make modules_prepare

# compilar modulo 8192cu

cd ~/rt8192cu
CONFIG_RTL8192CU=m make -C /home/pi/linux M=`pwd`

Si todo fue bien, instalar el módulo:

sudo install -p -m 644 8192cu.ko /lib/modules/4.1.13+/kernel/net/wireless/
sudo insmod /lib/modules/4.1.13+/kernel/net/wireless/8188eu.ko
sudo depmod -a

Lógicamente ajustar la versión del kernel a tu medida. Este es sin dudas el punto más dificil, que va a requerir insistir si alguna dependencia está faltando.

Compilar hostapd

Como dijimos, el encargado de la magia será hostapd. Este es un daemon de user space para Linux y BSDs que implementa todas las funcionalidades de un AP wifi tales como AP management IEEE 802.11, IEEE 802.1X/WPA/WPA2/EAP Authenticators, cliente RADIUS, EAP server, etc.
Como vamos a usar este dongle basado en 8192CU, tendremos que compilar un hostapd modificado, y no usar el que está disponible vía gestor de paquetes. Para eso, descargamos los drivers del fabricante desde aquí Realtek el que indica linuxLinux Kernel 2.6.18~3.9.

Vamos a compilar simplemente la parte de hostapd, de esta forma

$ unzip RTL8192xC_USB_linux_*.zip
$ tar zxvf RTL8188C_8192C_USB_linux_*/wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_rtw_*.tar.gz
$ cd wpa_supplicant_hostapd-0.8_*/hostapd/
$ make
$ sudo cp hostapd hostapd_cli /usr/local/sbin/

Ahora creamos la configuración para hostapd, en /etc/hostapd/hostapd.conf:

interface=wlan0
bridge=br0
driver=rtl871xdrv
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=roadconn
country_code=AR
hw_mode=g
channel=6
beacon_int=100
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wmm_enabled=1
wmm_ac_bk_cwmin=4
wmm_ac_bk_cwmax=10
wmm_ac_bk_aifs=7
wmm_ac_bk_txop_limit=0
wmm_ac_bk_acm=0
wmm_ac_be_aifs=3
wmm_ac_be_cwmin=4
wmm_ac_be_cwmax=10
wmm_ac_be_txop_limit=0
wmm_ac_be_acm=0
wmm_ac_vi_aifs=2
wmm_ac_vi_cwmin=3
wmm_ac_vi_cwmax=4
wmm_ac_vi_txop_limit=94
wmm_ac_vi_acm=0
wmm_ac_vo_aifs=2
wmm_ac_vo_cwmin=2
wmm_ac_vo_cwmax=3
wmm_ac_vo_txop_limit=47
wmm_ac_vo_acm=0
eapol_key_index_workaround=0
eap_server=0
own_ip_addr=127.0.0.1
wpa=2
wpa_passphrase=supersecreta
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

Fíjense los parámetros driver=rtl871xdrv que es donde especificamos el driver a usar, ssid= donde definimos el nombre del ssid y wpa_passphrase donde definimos la autenticación.

Se puede probar hostapd con el siguiente comando:

# hostapd -dd /etc/hostapd/hostapd.conf

Si todo va bien podemos crear el script de inicio sysv:

#!/bin/bash
# /etc/init.d/hostapd

### BEGIN INIT INFO
# Provides: hostapd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Managing hostapd
# Description: This service is used to manage hostapd (WiFi Access Point)
### END INIT INFO


case "$1" in
start)
echo
echo "Starting hostapd..."
echo
if [ ! -d /var/run/hostapd ]; then
rm -rf /var/run/hostapd
mkdir /var/run/hostapd
fi

/usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf
;;
stop)
echo
echo "Stopping hostapd..."
echo
if [ -e /var/run/hostapd/wlan0.pid ]; then
read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi ;; restart) echo echo "Restarting hostapd..." echo if [ -e /var/run/hostapd/wlan0.pid ]; then read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi if [ ! -d /var/run/hostapd ]; then rm -rf /var/run/hostapd mkdir /var/run/hostapd fi /usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf ;; *) echo echo "Usage: /etc/init.d/hostapd start|stop|restart" echo exit 1 ;; esac exit 0


Proximo paso, brevemente es convertir el dispositivo a un repetidor wi-fi, haciendo bridge a una segunda interfaz wifi.
Continuar »