Raspberry Pi + Android手机 搭建无线移动网站 (上)

已经有好长时间没有发博文了, 其实这两天也没有闲着, 在鼓捣树莓派, 一来可以帮着巩固一下Linux 的知识, 其次Rpi B二代上市之后就入手了, 看着这个小东西, 确实打心底喜欢.

标题中的移动网站, 是一个真的可以移动的网站…

在搭建的时候还真的遇到了一个瓶颈 – 为什么不直接用手机?

我研究了一下, 手机上网其实并不是手机直接和网站沟通, 当中还要经过运营商的DNS, 可以看作是运营商的路由器, 所以,当你查看手机IP的时候,往往会显示两个, 一个是内部IP,一个是外部IP. 内部IP是运营商分配给你手机的, 相当于内网IP, 外部IP,其实就是运营商的路由器的IP. 所以, 当你把服务器架在手机上的时候, 是无法通过外部IP直接访问的. 当然, 你又没有办法通知运营商,让它更改路由设置, 把所有80端口的消息全都转发到你的手机上… 仔细想想就知道这个是几乎不可能的, 因为你的手机无时无刻不在移动, 手机需要不停寻找可用的基站, 运营商不可能为你一个人更改所有的基站设置.

另外, 推荐一个查询Android手机IP的利器: IP Tools, 免费版的就非常好用了.

言归正传:

实现方案(前提): OpenVPN + Android Hotspot + 端口转发 + Android 手机最好已经root, 否则只能转发1024以上的端口.

硬件: 一台用于VPN连接的树莓派(下文称为Rpi1)或者普通Linux电脑 + 手机 + 一个已经安装无线网卡和apache2的树莓派(下文称为Rpi2) + 移动电源(用于给Rpi2供电)

首先第一步是怎么安装搭建OpenVPN 服务器 (以下步骤是在Rpi1上执行的)

  • sudo apt-get update
  • sudo apt-get install openvpn openssl
  • cd /etc/openvpn
  • sudo cp -r /usr/share/doc/openvpn/examples/easy-rsa/2.0 ./easy-rsa
  • sudo nano ./easy-rsa/vars # replace the export EASY_RSA with =”/etc/openvpn/easy-rsa”
  • sudo . ./easy-rsa/vars
  • sudo ./easy-rsa/clean-all
  • cd easy-rsa
  • sudo ln -s openssl-1.0.0.cnf openssl.cnf
  • cd ..
  • ./easy-rsa/build-ca OpenVPN #这一步会构建根证书 ca.crt
  • ./easy-rsa/build-key-server server #生成服务器端公钥证书以及服务器密钥
  • ./easy-rsa/build-key client1 #生成客户端公钥证书以及客户端密钥
  • ./easy-rsa/build-dh #生成Diffie-Hellman密钥, 用于成功建立SSL连接.
  • 建立OpenVPN.conf, 输入以下内容:

    #######From Here#######

    dev tun

    proto tcp #这里也可以设置成udp [TCP会校验packt, udp不会校验. 具体区别参见wiki…]

    port 1194

    ca /etc/openvpn/easy-rsa/keys/ca.crt

    cert /etc/openvpn/easy-rsa/keys/server.crt

    key /etc/openvpn/easy-rsa/keys/server.key

    dh /etc/openvpn/easy-rsa/keys/dh1024.pem

    user nobody

    group nogroup

    server 10.8.0.0 255.255.255.0

    persist-key

    persist-tun

    status /var/log/openvpn-status.log

    verb 3

    client-to-client

    push “redirect-gateway def1″

    #set the dns servers

    push “dhcp-option DNS 8.8.8.8″ #这是GoogleDNS国内可能会被和谐

    push “dhcp-option DNS 8.8.4.4″ #这是GoogleDNS国内可能会被和谐

    log-append /var/log/openvpn

    comp-lzo

    #######End#######

 

  • echo 1 > /proc/sys/net/ipv4/ip_forward #This enables ip forwarding
  • ifconfig #note whether the ip address is for wlan0 or eth0
  • iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o wlan0 -j SNAT –to 192.xxx.xxx.xxx #change the ip here and also with the proper wlan0 or eth0
  • 使用locate sysctl.conf 或者 sudo find / -name “sysctl.*” 命令找到你在/etc下的sysctl.conf文件, 去掉ipv4_forwarding前面# 保存退出
  • 如果你是使用无线网络的话, 需要修改ifplugd, 因为连上开启VPN后, 会自动关闭无线网络, 转而使用有线网络. 反之, 如果你当前使用的是有线网络, 开启VPN后, 会转而使用无线网卡. 修改过程如下:
  • sudo nano /etc/default/ifplugd, 按需修改HOTPLUG_INTERFACES=”wlan0 wlan0 eth0″ 或者 HOTPLUG_INTERFACES=”eth0 eth0 wlan0 “, 保存退出
  • sudo /etc/init.d/openvpn/ start #这一步将启动VPN服务器
  • sudo nano openvpn.ovpn #建立Android手机上用于建立VPN连接的文件

     

    输入以下内容:

     

     

    #######From Here#######

     

    dev tun

    client

    proto tcp #This could also be udp, if you choose to use udp in previous steps

    remote 220.xxx.xxx.xxx 1194 #This is should be your Router/Home/External IP, which is reachable via Internet

    resolv-retry infinite

    nobind

    persist-key

    persist-tun

    ca ca.crt

    cert client1.crt

    key client1.key

    comp-lzo

    verb 3

    #######To Here#######

 

  • sudo nano /etc/rc.local

在exit 0 前输入如下内容

iptables -t nat -A INPUT -i eth0 -p tcp -m tcp –dport 1194 -j ACCEPT #这里的tcp可以按需修改成udp

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o wlan0 -j SNAT –to-source 192.xxx.xxx.xxx #这个是你的VPN服务器内网地址

 

配置路由器, 确保1194端口能转发到Rpi1上.

 

下面是在Android手机上的配置:

  • 安装OpenVPN 客户端, 直接上Google Play或者国内的应用市场, 应该都能下载到
  • 拷贝Rpi1上的 /etc/openvpn/easy-rsa/keys/ 到手机上
  • 手机上在OpenVPN下点击Import, 找到上一步的文件夹下的 .ovpn文件, 导入.
  • 测试是不是可以连接.

 

如果连接成功, 说明你已经拥有了一台属于自己的基于OpenVPN的VPN服务器!

 

现在在你的Android手机上查看一下手机的IP的话会发现, 内部IP是你的VPN服务器分配给你的IP, 而外部IP则是你路由器的Internet IP.

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>