Thursday, August 3, 2017

Policy Based IPv6 Routing on LEDE

My home router runs LEDE 17.01. It has two IPv6 connections, an ISATAP tunnel and TunnelBroker. The ISATAP connection has shorter latency than the TunnelBroker. However, ISATAP only allows one IPv4 address to have one IPv6 address. In order to let my home computers have IPv6 connections, I have two choices. The first is to use NAT on IPv6 so that hosts behind the router appears as one hosts on the IPv6 Internet. The second choice is to assign home computers addresses allocated on TunnelBroker and route all their traffic through TunnelBroker. And installing a SOCKS/HTTP proxy on the router, so a host can enjoy the low latency ISATAP link via the proxy.

So, I configured the router to have the following IPv6 routing table

default from 2001:xxxxx::/64 dev 6in4-henet proto static metric 16 pref medium
default from 2001:xxxxx::/64 dev 6in4-henet proto static metric 16 pref medium
2000::/3 via 2001:da8:xxxx dev isatap src 2001:da8:xxxx metric 2 pref medium

As a result, the router will opt for the ISATAP link over the TunnelBroker link. However, I found that although hosts behind the router can get IPv6 addresses, they cannot connect to any IPv6 hosts outside my home, because the router puts all IPv6 traffic whose destination matches 2000::/3 through the ISATAP link!

Later, I came up with a solution. Linux supports policy-based routing. So the router can have two IPv6 routing tables, namely the `main` and `henet` table. For IPv6 packets whose source addresses are within my TunnelBroker's block, the router should lookup the `henet` table, which contains

2001:xxxxx/64 dev br-lan
default from 2001:xxxxx::/64 dev 6in4-henet

I wrote a script to achieve this effect

ip -6 route flush table henet
ip -6 route add 2001:xxxx/64 dev br-lan metric 128 table henet
ip -6 route add default dev 6in4-henet metric 256 table henet
ip -6 rule add from 2001:xxxxx/64 table henet

You should also add `252 henet` to /etc/iproute2/rt_tables before invoking the above commands.

Thursday, August 25, 2016

Setting up IKEv2 with strongSwan on OpenWrt 15.05.1

I have been using OpenVPN on my OpenWrt router for remote access. OpenVPN is a SSLVPN solution similar to Anyconnect from Cisco. IPsec is a IETF standard for providing network layer security. The support of IPsec is builtin to recent Linux kernel. However, the kernel needs the encryption key before setting up IPsec. You can manually create IPsec tunnels with a preshared key, but this approach does not support mobile clients which have dynamic IP addresses.

The Internet Key Exchange protocol is aimed at negotiating security parameters before setting up an IPsec tunnel. Usually, an IKE daemon listens on UDP/500 for requests and then does several rounds of exchanges with the remote client and then send negotiated parameters to the Linux kernel and thus sets up an IPsec tunnel.

IKEv2 is the latest one which is much easier to deploy than its predecessor IKEv1. StrongSwan is an IKE daemon with full support of IKEv2. To install strongSwan on OpenWrt, you need install strongswan-minimal package. You also need to install strongswan-mod-openssl in order to use pubkey authentication.

There are several configuration files:

/etc/ipsec.conf contains information of IPsec tunnels.
/etc/strongswan.conf contains configuration for strongswan.
/etc/ipsec.secrets contains various credentials of IPsec tunnels.


The following is all needed to setup a tunnel with PSK. PSK is not so safe as public key, especially if the PSK is very weak.

in /etc/ipsec.conf:

conn mytunnel
left=%any
 leftsubnet=10.1.0.0/16
leftid=home
leftfirewall=yes
right=IP_OF_THE_PEER
 rightsubnet=10.2.0.0/16
rightid=moon
auto=add
mobike=no
authby=psk

in /etc/ipsec.secrets:

moon : PSK YOUR_PSK_FOR_TUNNEL

use `ipsec up mytunnel` to establish the tunnel and `ipsec statusall` to check tunnel status.

Saturday, July 23, 2016

Configuring Raspberry Pi 3 via Serial Console

I got several RPi 3 recently. I tried to set them up via the UART console as I did with RPi 2. But I could not see anything on my computer. After googling around, I found that the serial console is disabled by default. So I added enable_uart=1 to /boot/config.txt. And then I could see login prompt on my computer.
As RPi 3 has a builtin WiFi module, I can connect it to my wireless router and access it via SSH. If the network is secured with WPA2-PSK, just add the following to /etc/wpa_supplicant/wpa_supplicant.conf.
network={
    ssid="your_ssid"
    psk="your_password"
}
If your wireless network is open, add the following.
network={
    ssid="your_ssid"
    key_mgmt=NONE
}
and run sudo ifdown wlan0 and then sudo ifup wlan0. You can test the connection with ifconfig, pingand iwconfig.

Friday, July 22, 2016

Adding an Intel Wireless-AC 7260 Card on ThinkPad T420s

I bought an Intel 7260AC card from jd.com yesterday in order to replace the 6205 card on my T420s and enjoy the speed of 11ac. The card arrived this morning. The card is not specially made for ThinkPads.

As all ThinkPad's BIOS is equipped with a whitelist of authorized wirless cards. I need to flash a BIOS with whitelist removed. I found one made by TimeWalker75a on bios-mods.com. Here is the link. Apart from removing the whitelist, the modified BIOS also unlocks RAM clock speed and some advanced settings. But before flashing the modified BIOS, you need to flash the original 1.41 BIOS offered by Lenovo.

Then, I removed the battries and the shield above the RAM modules and saw the 6205 mini-PCI-E wireless card. I unplugged the two antenna cables, loosed the screw and removed the old card. And then installed the new 7260 card and plugged the cables. The gray cable should be connected to the main port while the black one should be connected to the aux port.

I plugged in the power cord and turn it on. Fedora identified the new card successfully, and the hardware wireless switch worked flawlessly. But all WiFi history is lost. This 7260AC card also contains a Bluetooth 4.0 module, and the laptop also has a embedded Bluetooth module(BCM2045B) from Broadcom, I can see both of them by running hciconfig. Removing BCM2045B needs opening the palm rest. I found a way to blacklist it with udev at here.

Update:

Do not remove the embedded BCM2045B module, or the BIOS will disable Bluetooth even if there is one module in 7260.

Friday, December 4, 2015

How WiFiDog Works

I introduced WiFiDog in a previous post. In this post, I examine how WiFiDog works by exploiting Netfilter/Iptables.

WiFiDog creates the following chains in magle table, WiFiDog_br-wlan_Incoming /Outgoing /Trusted, and WiFiDog_br-wlan_AuthServers /Global /Internet /Known /Locked /Unknown /Validate in filter table. br-wlan is the GatewayInterface set in /etc/wifidog.conf

WiFiDog_br-wlan_Outgoing is chained in mangle PREROUTING. If a client passes authentication, WiFiDog daemon inserts a rule in WiFiDog_br-wlan_Outgoing, marking the packets from this user with mark 0x2.

WiFiDog_br-wlan_Internet is chained in filter FORWARD table. The contents in this chain is derived from /etc/wifidog.conf, which resembles the following:

Chain WiFiDog_br-wlan_Internet (1 references)
target     prot opt source               destination         
DROP       all  --  anywhere             anywhere             state INVALID
TCPMSS     tcp  --  anywhere      anywhere    tcp flags:SYN,RST/SYN TCPMSS clamp to PMTU
WiFiDog_br-wlan_AuthServers  all  --  anywhere        anywhere            
WiFiDog_br-wlan_Locked  all  --  anywhere             anywhere         mark match 0x254
WiFiDog_br-wlan_Global  all  --  anywhere             anywhere            
WiFiDog_br-wlan_Validate  all  --  anywhere           anywhere         mark match 0x1
WiFiDog_br-wlan_Known  all  --  anywhere              anywhere         mark match 0x2
WiFiDog_br-wlan_Unknown  all  --  anywhere            anywhere            

At this point, WiFiDog is capable of separating known users and unknown users. However, there is one more thing, redirecting unknown users to the web portal. This is done with WiFiDog_br-wlan_Unknown chain in the nat table. There is a rule:
REDIRECT   tcp  --  anywhere             anywhere         tcp dpt:www redir ports 2060
which redirects unkown user's HTTP connection to 2060 port on the router.

Enable Web Proxy Auto-discovery on OpenWrt with Dnsmasq

Recently, I set up shaodowsocks and polipo on an OpenWrt router. I'd like every client connected be able to bypass the Great Fire Wall of China automatically. This can be done by pushing an proxy auto-config to the client. And there exists a protocol called Web Proxy Autodiscovery (WPAD).

Dnsmasq is capable of WPAD. Just add this line in /etc/config/dhcp.conf under config dhcp lan section

list dhcp_option '252,http://192.168.10.1:8000/proxy.pac'

the HTTP URL should be replaced adequately. There should be no spaces between the comma and URL. You can convert GFWlist to a PAC file with gfwlist2pac.

A note for iPad users:
iPad do not enable WPAD by default (because WPAD can redirect a client's HTTP connection without informing the user). The user can enable it in the configuration for wireless access points.

Saturday, November 21, 2015

WifiDog on Openwrt

WifiDog is a Captive Portal on Openwrt. It utilizes Linux netfilter in order to force a client to log in before granting access to the Internet. Although there is a Wifi in its name, it can work on wired network as well. WifiDog has two components, a gateway and an auth server. The gateway is running on an access point, and redirects unknown clients to the auth server's login page. The auth server is simply a Web server which implements WifiDog's auth protocol.

To install wifidog gateway on openwrt, just type opkg install wifidog in command line. It's config file is at /etc/wifidog.conf. You may want to customize GatewayID, GatewayInterface,  AuthServer, CheckInterval, and TrustedMACList. The comments in the config file explains these options clearly.

The crucial part is the AuthServer section. Upon connection, the client will be redirected to the auth server for authentication. You should have at least one AuthServer section. If you have multiple AuthServer sections, WifiDog will use the first auth server that responses to its ping request. The auth server implements wifidog's auth and ping protocols. An auth server written in php is available at https://github.com/wifidog/wifidog-auth. You may also write an auth server which suits you need. I have written one in python.

You should understand wifidog's protocols before writing an auth server. The protocol is fully describe in http://dev.wifidog.org/wiki/doc/developer/WiFiDogProtocol_V1. I will give a summary below.

Wifidog gateway keeps a list of authorized users' IP, MAC and token. If an unknown user tries to visit a website, it will be redirect to the auth server's login page. If login is successful, the user will be redirected to the gateway's portal with the URL containing the user's IP, MAC and token (a random string). The gateway will verify these information with auth server via auth protocol. Every check interval (default value is 60 seconds), the gateway will contact the auth server and check every user's token by the auth protocol. If the re-authorization for a user fails, the gateway will remove the user from the list and then blocks its internet access. The auth protocol also allow the gateway to send accounting information for a user to the auth server.