More and more, the big phone companies want to control how you use the data you're paying for. One of their relatively new tricks is to sniff out "tethering" by inspecting the traffic coming from your device and then disabling your connection if you're using it "incorrectly."
Now, modern consumer broadband has gotten fast enough that you can reasonably establish a VPN to your home and proxy all traffic through that to bypass this. Most carriers do still allow SSL traffic (since so much of the web requires it these days), and this is (relatively) safe from such eavesdropping. Therefore it becomes feasible to set up OpenVPN (which uses SSL) and avoid the carrier's shenanigans.
In my case I have an OpenVPN server running on my openwrt router at home, but I also have a Linode virtual server. I stick to Linode when I just want to avoid this snooping but I will demonstrate both configurations.
You need to follow the OpenVPN docs to set up your CA and certs. Once you do so the configuration is fairly straightforward.
OpenVPN server (UCI for OpenWRT):
# /etc/config/openvpn
config 'openvpn' 'routing_server'
option 'cert' '/lib/uci/upload/cbid.openvpn.custom_config.cert'
option 'key' '/lib/uci/upload/cbid.openvpn.custom_config.key'
option 'ca' '/lib/uci/upload/cbid.openvpn.custom_config.ca'
option 'dh' '/lib/uci/upload/cbid.openvpn.custom_config.dh'
option 'port' '1194'
option 'proto' 'udp'
option 'dev' 'tun0'
option 'server' '192.168.168.0 255.255.255.0'
list 'push' 'route 192.168.3.0 255.255.255.0'
option 'keepalive' '10 120'
option 'comp_lzo' '1'
option 'enable' '1'
option 'client_to_client' '1'
option 'persist_key' '1'
option 'persist_tun' '1'
option 'status' '/tmp/openvpn-routing-status.log'
option 'verb' '3'
That's where the certs end up if you use LUCI. You can of course put them somewhere else. I'm pushing the route for 192.168.3.0/24 since that subnet is at home and I want to route to it.
On my linode:
# cat /etc/openvpn/server-routed.conf
cert /etc/openvpn/server.crt
key /etc/openvpn/server.key
ca /etc/openvpn/easy-rsa/keys/ca.crt
dh /etc/openvpn/easy-rsa/keys/dh1024.pem
dev tun1
comp-lzo
persist-tun
persist-key
server 10.8.0.0 255.255.255.0
keepalive 10 120
proto udp
verb 3
script-security 3
I'm not pushing any routes here since this is purely to act as a proxy.
IPtables:
iptables -I INPUT -m udp -p udp --dport 1194 -j ACCEPT
iptables -I INPUT -m tcp -p tcp --dport 1194 -j ACCEPT
iptables -A FORWARD -i tun1 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o tun1 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
Now, on my client:
# cat openvpn.cfg
ca ca.crt
cert client.crt
key client.key
client
nobind
remote openvpn.myserver.com 1194
route-delay 10
dev tun
ifconfig-nowarn
ping 10
comp-lzo
verb 4
proto udp
resolv-retry infinite
persist-key
persist-tun
redirect-gateway
On an Android device, you can just write that openvpn.cfg and toss the certs in there, then you can read it from the OpenVPN app (from the Play Store) which will create the profile for you.
One thing I haven't worked out yet is how to start the VPN connection on my phone and then "tether" other devices behind it and have them all route through the VPN. For now I just connect to the VPN on the devices which are behind the phone (not the phone which is doing the routing).