Przerabianie debiana pod WiFi Access Point
Kategoria: Artykuły, etykiety: access point, dnsmasq, hostapd, wifi, wpasupplicant
Dodany: 2014-09-21 07:47
(zmodyfikowany: 2014-09-21 07:48)
Przez: morfik
Wyświetleń: 18382
Podczas pisania artykułu na temat freeradiusa, znalazłem kilka ciekawych informacji niezbyt powiązanych jako tako z tematem freeradiusa ale jakże użytecznych pod kątem zastosowania. Jakiś czas temu dokonałem zakupu adaptera wifi TP-Link TL-WN722n -- potrzebowałem zewnętrznej karty sieciowej do mojego lapka, bo ten z kolei ma na pokładzie niezbyt użytecznego broadcoma. Chodziło mi głównie o pozyskanie odpowiedniej karty w celu przeprowadzania szeregu testów, których nie mogłem w standardzie wykonać korzystając z wbudowanej w mój laptop karty wifi. Jak się później okazało, zakupiony adapter posiada też dodatkowy ficzer -- tryb AP, który umożliwia przerobienie zwykłej maszyny z debianem na Access Pointa sieci wifi. W prawdzie ta karta nie może się równać z routerami wifi, bo te zwykle mają więcej anten, z których każda jest lepszej jakości, co przekłada się na lepszy zasięg i transfer ale daje ona nam możliwość połączenia dwóch i więcej maszyn w sieć -- zwykle karty wifi nie posiadają trybu AP, a jedynie tryb STA (czasem też i monitor), co uniemożliwia komunikację.
Jeśli nie wiemy czy nasza karta wifi potrafi przełączyć się w tryb AP, możemy to sprawdzić przez wydanie poniższego polecenia:
root:~# iw list
Wiphy phy0
...
Supported interface modes:
* IBSS
* managed
* AP
* AP/VLAN
* monitor
* mesh point
* P2P-client
* P2P-GO
...
Adapter TP-Link TL-WN722n wymaga dodatkowo doinstalowania firmware:
[ 95.976030] usb 1-3: new high-speed USB device number 2 using ehci-pci
[ 96.124912] usb 1-3: New USB device found, idVendor=0cf3, idProduct=9271
[ 96.124919] usb 1-3: New USB device strings: Mfr=16, Product=32, SerialNumber=48
[ 96.124923] usb 1-3: Product: USB2.0 WLAN
[ 96.124927] usb 1-3: Manufacturer: ATHEROS
[ 96.124930] usb 1-3: SerialNumber: 12345
[ 96.244516] cfg80211: Calling CRDA to update world regulatory domain
[ 96.333668] usb 1-3: ath9k_htc: Firmware htc_9271.fw requested
[ 96.334049] usbcore: registered new interface driver ath9k_htc
[ 96.344163] usb 1-3: firmware: failed to load htc_9271.fw (-2)
[ 96.344176] usb 1-3: Direct firmware load failed with error -2
[ 96.344180] usb 1-3: Falling back to user helper
[ 96.344926] usb 1-3: ath9k_htc: USB layer deinitialized
Na maszynie, do której podepniemy wspomniane urządzonko, musimy zainstalować również odpowiednie oprogramowanie. Poniżej jest lista potrzebnych nam pakietów:
# aptitude install hostapd dnsmasq firmware-atheros crda
Oprogramowanie, które właśnie zainstalowaliśmy, jest używane również przez OpenWRT i to dokładnie w tym samym celu, w którym my zamierzamy je wykorzystać na debianie. Jeśli chcemy połączyć tylko dwie maszyny ze sobą, to niekoniecznie potrzebujemy pakietu dnsmasq -- możemy skonfigurować klienta statycznie. Natomiast, jeśli w grę wchodzi więcej maszyn, to praktycznym rozwiązaniem byłoby zaprzęgnąć serwer DHCP, który automatycznie będzie konfigurował klientów.
Jeśli nie będziemy korzystać z dnsmasq, ustawiamy ręcznie konfigurację interfejsu w /etc/network/interfaces na maszynie klienckiej:
#auto wlan0
#allow-hotplug wlan0
iface wlan0 inet static
address 192.168.20.200
network 192.168.20.0/24
netmask 255.255.255.0
broadcast 192.168.20.255
wpa-driver nl80211
wpa-debug-level -1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
W debianie pakiet hostapd jest skompilowany domyślnie z obsługą trybu N i nie musimy sobie głowy zawracać rekompilacją źródeł. Na wypadek gdybyśmy mieli nieszczęście trafić na pakiety bez obsługi trybu N, warto wiedzieć, gdzie ewentualnie zmienić konfigurację. Niekoniecznie trzeba pobierać i kompilować źródła ręcznie -- możemy wykorzystać debianowe, czyli pobrać je przy pomocy apt-get source i w pliku wpa-1.1/debian/config/hostapd/linux odhashować poniższe linijki:
...
CONFIG_DRIVER_NL80211=y
...
CONFIG_IEEE80211N=y
...
I zrobić odpowiednią paczuszkę -- nie będę tutaj opisywał procesu tworzenia paczki, bo to jest temat na osobny artykuł.
Po ponownym podłączeniu adaptera do portu usb, powinniśmy mieć w systemie nowy interfejs sieciowy -- wlan0:
# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 00:16:e6:34:c4:e0 brd ff:ff:ff:ff:ff:ff
5: wlan0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether e8:94:f6:1e:15:e9 brd ff:ff:ff:ff:ff:ff
Musimy jeszcze przypisać interfejsowi wlan0 statyczny adres IP:
auto wlan0
iface wlan0 inet static
address 192.168.20.1
network 192.168.20.0/24
netmask 255.255.255.0
broadcast 192.168.20.255
Konfiguracja hostapd
Z pakietem hostapd jest dostarczany obszerny plik konfiguracyjny. Znajduje się on w /usr/share/doc/hostapd/examples/hostapd.conf.gz -- trzeba go przekopiować do /etc/hostapd/hostapd.conf :
# zcat /usr/share/doc/hostapd/examples/hostapd.conf.gz > /etc/hostapd/hostapd.conf
Edytujemy także plik /etc/default/hostapd i zmieniamy w nim:
DAEMON_CONF="/etc/hostapd/hostapd.conf"
Przechodzimy teraz do konfiguracji AP -- edytujemy plik /etc/hostapd/hostapd.conf i uzupełniamy w nim odpowiednie linijki:
interface=wlan0
driver=nl80211
ctrl_interface_group=0
ssid=Valar Morgulis
country_code=PL
ieee80211d=1
hw_mode=g
channel=8
auth_algs=1
ignore_broadcast_ssid=0
ap_max_inactivity=600
ieee80211n=1
require_ht=0
eapol_version=2
wpa=2
wpa_psk=363686d31b1cda24ef42b76452baf8fbca0fa55535df2f8aa04a7884a13e7946
wpa_key_mgmt=WPA-PSK WPA-PSK-SHA256
wpa_pairwise=CCMP
rsn_pairwise=CCMP
wpa_group_rekey=600
wpa_gmk_rekey=21600
peerkey=1
wps_state=0
W celu wygenerowania hasła do naszej sieci wifi, użyjemy wpa_passphrase :
# wpa_passphrase 'Valar Morgulis' 'morfik-ma-kota'
...
psk=363686d31b1fda24ef42b86452baf8fbca0faa3f35df2f8ad04a7884213e7916
...
Istnieje możliwość sprecyzowania więcej niż jednego hasła do sieci wifi. W tym celu potrzebny będzie osobny plik, za który odpowiada parametr wpa_psk_file . My ograniczymy się do jednego hasła zakodowanego w base64.
Restartujemy daemona hostapd i sieć powinna być już widoczna przy skanowaniu pasma:
# wpa_cli scan
Selected interface 'wlan0'
OK
# wpa_cli scan_results
Selected interface 'wlan0'
bssid / frequency / signal level / flags / ssid
...
e8:94:f6:1e:15:e9 2447 -29 [WPA2-PSK+PSK-SHA256-CCMP][ESS] Valar Morgulis
...
Trzeba nam jeszcze odpowiedniej konfiguracji dla wpasupplicanta, którą to musimy dopisać do pliku /etc/wpa_supplicant/wpa_supplicant.conf :
network={
id_str="home_wifi_static"
priority=5
ssid="Valar Morgulis"
bssid=e8:94:f6:1e:15:e9
#psk="morfik-ma-kota"
psk=363686d31b1fda24ef42b86452baf8fbca0faa3f35df2f8ad04a7884213e7916
proto=RSN
key_mgmt=WPA-PSK-SHA256
pairwise=CCMP
group=CCMP
auth_alg=OPEN
scan_ssid=0
disabled=0
}
Spróbujmy się podłączyć do sieci by sprawdzić czy wszystko jest w porządku. W tym celu odpalany wpasupplicanta w trybie debug wpisując w terminal dwie poniższe linijki:
# /sbin/wpa_supplicant -P /var/run/wpa_supplicant.wlan0.pid -i wlan0 -W -b bond0 -D nl80211,wext -c /etc/wpa_supplicant/wpa_supplicant.conf
# /sbin/wpa_cli -P /var/run/wpa_action.wlan0.pid -i wlan0 -p /var/run/wpa_supplicant -a /sbin/wpa_action
Jeśli połączenie działa jak należy, powinniśmy zobaczyć na pierwszej konsoli poniższy log:
wlan0: SME: Trying to authenticate with e8:94:f6:1e:15:e9 (SSID='Valar Morgulis' freq=2447 MHz)
wlan0: Trying to associate with e8:94:f6:1e:15:e9 (SSID='Valar Morgulis' freq=2447 MHz)
wlan0: Associated with e8:94:f6:1e:15:e9
wlan0: WPA: Key negotiation completed with e8:94:f6:1e:15:e9 [PTK=CCMP GTK=CCMP]
wlan0: CTRL-EVENT-CONNECTED - Connection to e8:94:f6:1e:15:e9 completed (auth) [id=5 id_str=]
Dodatkowo w syslogu powinniśmy ujrzeć:
Sep 21 02:44:59 morfikownia wpa_action: WPA_IFACE=wlan0 WPA_ACTION=CONNECTED
Sep 21 02:44:59 morfikownia wpa_action: WPA_ID=5 WPA_ID_STR= WPA_CTRL_DIR=/var/run/wpa_supplicant
Sep 21 02:44:59 morfikownia wpa_action: network settings not defined for default in /etc/network/interfaces
Sep 21 02:44:59 morfikownia wpa_action: ifup wlan0=default
Sep 21 02:44:59 morfikownia wpa_action: creating sendsigs omission pidfile: /run/sendsigs.omit.d/wpasupplicant.wpa_supplicant.wlan0.pid
Sep 21 02:44:59 morfikownia wpa_action: bssid=e8:94:f6:1e:15:e9
Sep 21 02:44:59 morfikownia wpa_action: ssid=Valar Morgulis
Sep 21 02:44:59 morfikownia wpa_action: id=5
Sep 21 02:44:59 morfikownia wpa_action: mode=station
Sep 21 02:44:59 morfikownia wpa_action: pairwise_cipher=CCMP
Sep 21 02:44:59 morfikownia wpa_action: group_cipher=CCMP
Sep 21 02:44:59 morfikownia wpa_action: key_mgmt=WPA2-PSK-SHA256
Sep 21 02:44:59 morfikownia wpa_action: wpa_state=COMPLETED
Sep 21 02:44:59 morfikownia wpa_action: address=c0:cb:38:01:f0:f5
Jak widać powyżej, wszystkie parametry konfiguracyjne sieci wifi są takie jak być powinny.
Konfiguracja dnsmasq
Konfiguracja serwera DHCP i DNS trzymana jest w pliku /etc/dnsmasq.conf ale zanim tam przejdziemy, zajrzyjmy pierw do pliku /etc/default/dnsmasq i upewnijmy się, że dnsmasq jest włączony.
Poniżej znajduje się konfiguracja dnsmasq:
domain-needed
bogus-priv
local=/mhouse.lh/
interface=wlan0
no-hosts
expand-hosts
domain=mhouse.lh
dhcp-range=192.168.20.100,192.168.20.250,2h
#read-ethers
dhcp-lease-max=150
dhcp-leasefile=/etc/dnsmasq.leases
dhcp-authoritative
cache-size=1000
no-negcache
W przypadku gdybyśmy chcieli statyczne lease DHCP, możemy skorzystać z pliku /etc/ethers przez odhashowanie read-ethers . Ja tam jednak wolę precyzować hosty bezpośrednio w konfiguracji dnsmasq przy pomocy wpisów takich jak ten poniżej:
dhcp-host=c0:cb:38:01:f0:f5,morfikownia,192.168.20.200,2h
Powyższa linijka przydziela hostowi o adresie MAC c0:cb:38:01:f0:f5 adres IP 192.168.20.200 i nazwę morfikownia na 2 godziny.
Na kliencie ustawiamy poniższą konfigurację interfejsu wifi w /etc/network/interfaces :
#auto wlan0
#allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-driver nl80211
wpa-debug-level -1
wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf
Restartujemy dnsmasq i łączymy się do sieci -- serwer DHCP powinien nam przydzielić odpowiedni adres:
# ifup wlan0
Internet Systems Consortium DHCP Client 4.3.1
Copyright 2004-2014 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/
Listening on LPF/wlan0/c0:cb:38:01:f0:f5
Sending on LPF/wlan0/c0:cb:38:01:f0:f5
Sending on Socket/fallback
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 5
DHCPDISCOVER on wlan0 to 255.255.255.255 port 67 interval 6
DHCPREQUEST on wlan0 to 255.255.255.255 port 67
DHCPOFFER from 192.168.20.1
DHCPACK from 192.168.20.1
bound to 192.168.20.200 -- renewal in 2903 seconds.
Jeśli planujemy wdrożyć jakiś filtr pakietów, trzeba uwzględnić w nim regułki przepuszczające ruch na portach 53/udp (zapytania DNS) oraz 67/udp (serwer DHCP).
AP z dostępem do internetu
Stworzony w ten sposób access point nie będzie miał dostępu do internetu. W przypadku jednak gdybyśmy chcieli go podłączyć, musimy dodać kilka regułek do filtra iptables. Poniżej jest skrypt firewalla, który wszystko ustawi jak trzeba:
#!/bin/sh
### BEGIN INIT INFO
# Provides: firewall
# Required-Start: mountkernfs $local_fs
# Required-Stop: $local_fs
# Should-Start:
# Should-Stop:
# Default-Start: S
# Default-Stop: 0 6
# X-Start-Before:
# X-Stop-After:
# Short-Description: firewall configuration
# Description: firewall configuration
### END INIT INFO
do_start ()
{
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -s 192.168.20.0/24 -d 0/0 -j MASQUERADE
iptables -t filter -P INPUT DROP
iptables -t filter -P FORWARD DROP
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -N tcp
iptables -t filter -N udp
iptables -t filter -N icmp_in
iptables -t filter -N fw-interfaces
iptables -t filter -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A INPUT -i lo -j ACCEPT
iptables -t filter -A INPUT -m conntrack --ctstate INVALID -j DROP
iptables -t filter -A INPUT -p icmp -m conntrack --ctstate NEW -j icmp_in
iptables -t filter -A INPUT -p udp -m conntrack --ctstate NEW -j udp
iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j tcp
iptables -t filter -A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
iptables -t filter -A INPUT -p tcp -j REJECT --reject-with tcp-reset
iptables -t filter -A icmp_in -p icmp -i eth0 -s 192.168.1.0/24 -d 192.168.1.166 -j ACCEPT
iptables -t filter -A icmp_in -p icmp -i wlan0 -s 192.168.20.0/24 -d 192.168.20.1 -j ACCEPT
iptables -t filter -A udp -p udp --dport 53 -j ACCEPT -m comment --comment "DNS"
iptables -t filter -A udp -p udp --dport 68 -j ACCEPT -m comment --comment "Allow-DHCP-Renew"
iptables -t filter -A udp -p udp --dport 67 -j ACCEPT -m comment --comment "DHCP-Server"
iptables -t filter -A tcp -p tcp --dport 22 -s 192.168.1.0/24 -j ACCEPT -m comment --comment "SSH"
iptables -t filter -A tcp -p tcp --dport 22 -s 192.168.20.0/24 -j ACCEPT -m comment --comment "SSH"
iptables -t filter -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -t filter -A FORWARD -m conntrack --ctstate INVALID -j DROP
iptables -t filter -A FORWARD -m conntrack --ctstate NEW -j fw-interfaces
iptables -t filter -A FORWARD -j REJECT --reject-with icmp-host-unreachable
iptables -t filter -A fw-interfaces -i wlan0 -o eth0 -s 192.168.20.0/24 -j ACCEPT
}
do_stop ()
{
iptables -t filter -P INPUT ACCEPT
iptables -t filter -P FORWARD ACCEPT
iptables -t filter -P OUTPUT ACCEPT
iptables -t filter -F
iptables -t filter -X
}
case "$1" in
start)
do_start
;;
stop)
do_stop
;;
force-reload|restart)
do_stop && sleep 1
do_start
;;
*)
echo "Usage: firewall {start|stop|restart}"
exit 1
;;
esac
exit 0
Zapisujemy go w /etc/init.d/firewall i dodajemy do autostartu systemu:
# update-rc.d firewall defaults
I w taki oto sposób mamy pseudo router wifi z debianem na pokładzie.
Pisane w oparciu o:
http://ariandy1.wordpress.com/2013/04/18/wifi-access-point-with-tp-link-tl-wn722n-on-ubuntu-12-04/
http://forum.doozan.com/read.php?2,6300
http://wireless.kernel.org/en/users/Documentation/hostapd
http://w1.fi/