Bài 21: Tự động cấu hình mạng

A. RPI đã có cổng ethernet, giả sử ta có thêm usb wifi.

Tùy theo thiết bị được cắm vào RPI, ta có các cấu hình mạng như sau:

  1. ethernet
  2. wireless
  3. ethernet + wireless (access point)

B. Trường hợp có thêm usb 3G, ta có thêm nhiều cấu hình mạng:

  1. ethernet
  2. wireless
  3. 3G
  4. ethernet + wireless (access point)
  5. 3G + wireless (access point)
  6. 3G + ethernet (router 3G)
  7. 3G + wireless + ethernet (router, access point 3G)

Tuy có thể lần lượt cấu hình thủ công cho từng loại hình mạng, nhưng yêu cầu của chúng ta là RPI nhận dạng thiết bị cắm/rút và tự động cấu hình.

Udev có thể giúp nhận biết thiết bị usb wifi hay usb 3G cắm/rút, nhưng cổng LAN luôn luôn kết nối với hệ thống nên phải có phương pháp định kỳ kiểm tra kết nối ethernet.

Đoạn mã sau đây ứng dụng cho trường hợp A, RPI có thể có thêm usb wifi.

1. Kiểm tra tình trạng kết nối ethernet

Tạo file /root/eth.sh

#!/bin/bash
delay=1
carr=/sys/class/net/eth0/carrier
path=$( cd "$(dirname $0)" && pwd )
old_eth=$(cat $carr)
while [ 1 ]; do
   cur_eth=$(cat $carr)
   if [ "$cur_eth" != "$old_eth" ]; then
      old_eth=$cur_eth
      $path/autonet.sh
   fi
   sleep $delay
done

Cho chạy file eth.sh khi khởi động bằng cách chạy lệnh crontab -e, thêm vào dòng

@reboot /root/eth.sh

2. Kiểm tra tình trạng cắm/rút của usb wifi

Tạo file /etc/udev/rules.d/10-network.rules có nội dung như sau

ACTION=="add|remove", KERNEL=="wlan?|wwan?", RUN+="/root/autonet.sh"

sau đó, mỗi khi cắm/rút usb wifi hay usb 3G thì /root/autonet.sh được gọi chạy

3. Cài đặt và cấu hình isc-dhcp-server và hostapd

Xem Bài 15

4. Tự động cấu hình mạng

Tạo file /root/autonet.sh để cấu hình mạng tùy theo thiết bị được cắm vào RPI, mạng hoạt động sau vài giây mà không cần khởi động lại

#!/bin/bash

### Customize section ------->
### static IP of RPI
ADDR="192.168.0.100"
### Network
NWRK="192.168.0.0"
### Netmask
NMSK="255.255.255.0"
### Gateway
GWAY="192.168.0.1"
### SSID, Use wpa_passphrase mySSID myPASSWORD to encode myPassword
SSID='mySSID'
PSK='3098018d727d706782e8cde4b0b52714bca298c0000d38194908b08214165104'
### IP of Access point
APADDR="192.168.1.1"
APNWRK="192.168.1.0"

CONF='/etc/network/interfaces'
### End of customize section <--

initNAT(){ # $1=WLAN, $2=[LAN,WWAN]
   iptables -t nat -A POSTROUTING -o $2 -j MASQUERADE
   iptables -A FORWARD -i $2 -o $1 -m state --state RELATED,ESTABLISHED -j ACCEPT
   iptables -A FORWARD -i $1 -o $2 -j ACCEPT
   sync
}

rstacmd="invoke-rc.d networking stop; sleep 2; invoke-rc.d networking start"

### config for access point
infc_ap(){ # $1=[LAN,WWAN], $2=WLAN
   cat << EOF > $CONF
auto lo
iface lo inet loopback
auto $1
allow-hotplug $1
iface $1 inet static
address $ADDR
netmask $NMSK
network $NWRK
gateway $GWAY

auto $WLAN
allow-hotplug $WLAN
iface $WLAN inet static
   address $APADDR
   netmask $NMSK
   gateway $GWAY
EOF
sync
nohup sh -c "$rstacmd" > /dev/null 2>&1
}

### config for unique network device
infc_default(){
   inet=$1
   wpa=''
   if [[ $inet == "wlan"* ]]; then
      wpa=$(cat << STA
wpa-scan-ssid 1
wpa-ap-scan 1
wpa-key-mgmt WPA-PSK
wpa-proto RSN WPA
wpa-pairwise CCMP TKIP
wpa-group CCMP TKIP
wpa-ssid "$SSID"
wpa-psk "$PSK"
STA
)
   fi
   cat << EOF > $CONF
auto lo
iface lo inet loopback

auto $inet
allow-hotplug $inet
$wpa
iface $inet inet static
address $ADDR
netmask $NMSK
network $NWRK
gateway $GWAY
EOF
   sync
   nohup sh -c "$rstacmd" > /dev/null 2>&1
}

### List of devices
ignr='-I*.*'
if [ "$(cat /sys/class/net/eth0/carrier)" = "0" ]; then
   ignr="$ignr -Ieth*"
fi
devs=$(ls -1 $ignr /sys/class/net|grep -E '(eth|wlan)[0-9]')
[[ -z "$devs" ]] && exit 0
for dev in $devs; do
   if [[ $dev == "eth"* ]]; then
      LAN=$dev
   elif [[ $dev == "wlan"* ]]; then
      WLAN=$dev
   fi
done

### Congiguration---------->
[ $(pidof hostapd) ] && service hostapd stop
[ $(pidof isc-dhcp-server) ] && service isc-dhcp-server stop
if [[ -n $LAN ]]; then ### LAN
   if [[ -n $WLAN ]]; then ### LAN + WLAN = access point
      infc_ap $LAN
      initNAT $WLAN $LAN
      service hostapd start
      service isc-dhcp-server restart
   else ### LAN ONLY
      infc_default $LAN
   fi
else
   if [[ -n $WLAN ]]; then ### WIFI only
      sudo ifplugd eth0 –kill
      infc_default $WLAN
   fi
fi
exit 0
### End of Configuration----<<<

Chú thích

  • Cấu hình tự động cho (3G, wifi) tương tự như trên
  • Cấu hình B (ethernet, 3G, wifi) chỉ thêm vài trường hợp riêng lẻ hoặc thay đổi định hướng trafic

Leave a Comment

Filed under Software

Leave a Reply