由于某些网络要求必须通过http代理认证才能上网,而目前市面上还没找到支持全局wan口代理上网的路由器,只能另辟蹊径。

一开始想到用linux全局http代理,修改/etc/profile增加http-proxy,ftp-proxy,https-proxy,但发现这种情况不支持全协议(例如DNS/UDP之类),而且只能让路由本身用上代理,所以这个方案pass。

后来想到用squid,折腾发现由于squid支持的协议虽然很多,但是如果作为transparent透明代理的话,需要配置iptable,使之将80等端口重定向到squid端口上才行,这样也很麻烦,由于不支持socket代理,所以仍然不可以用,这个方案也pass。

最后还是采用了openvpn over http proxy的解决方案。

先说说这个方案的缺点:
1.配置复杂,需要对端openvpn服务器支持。
2.出口带宽受限,不超过对端openvpn服务器的上行带宽。

优点是:
1.所有流量通过HTTP代理出去,兼容所有协议
2.可以实现HTTP代理认证
3.可以使用多个openvpn服务器做冗余。

下面是详细配置:
1.先贴一个对端openvpn服务器(也是基于openwrt路由)的配置:

vi /etc/config/openvpn
config openvpn 'tun_test'
        option port '3366'
        option proto 'tcp'
        option dev 'tun0'
        option ca '/etc/openvpn/ca.crt'
        option cert '/etc/openvpn/server.crt'
        option key '/etc/openvpn/server.key'
        option dh '/etc/openvpn/dh1024.pem'
        option server '10.8.0.0 255.255.255.0'
        option ifconfig '10.8.0.1 255.255.255.0'
        option log '/tmp/openvpn.log'
        option cipher 'AES-256-CBC'
        option ifconfig_pool_persist '/tmp/ipp2.txt'
        option duplicate_cn '1'
        option client_to_client '1'
        option keepalive '10 120'
        option comp_lzo 'yes'
        option persist_key '1'
        option persist_tun '1'
        option status '/tmp/openvpn-status2.log'
        option verb '3'
        option topology 'subnet'
        list push 'topology subnet'
        list push 'dhcp-option DNS 172.24.8.1'
        list push 'route 172.24.8.0 255.255.255.0'
        list push 'redirect-gateway def1'
        option enabled '1'

对端openvpn服务器上的防火墙和网络配置可以参考本站
《Openwrt路由上的Openvpn Server Tun模式配置和firewall配置》

2.openwrt的openvpn客户端配置:

vi /etc/config/openvpn

注意在里面使用了代理服务器:10.0.2.2:8000 并通过/etc/config/pw.txt 文本文件实现了认证,文本第一行是用户名,第二行是密码。

##############################################
# Sample client-side OpenVPN 2.0 uci config  #
# for connecting to multi-client server.     #
##############################################

config openvpn sample_client

        # Set to 1 to enable this instance:
        option enabled 1

        # Specify that we are a client and that we
        # will be pulling certain config file directives
        # from the server.
        option client 1

        # Use the same setting as you are using on
        # the server.
        # On most systems, the VPN will not function
        # unless you partially or fully disable
        # the firewall for the TUN/TAP interface.
#       option dev tap
        option dev tun0

        # Are we connecting to a TCP or
        # UDP server?  Use the same setting as
        # on the server.
        option proto tcp
#       option proto udp

        # The hostname/IP and port of the server.
        # You can have multiple remote entries
        # to load balance between the servers.
        list remote "对端openvpn服务器地址 3366"
#       list remote "my_server_2 1194"

        # Choose a random host from the remote
        # list for load_balancing.  Otherwise
        # try hosts in the order specified.
#       option remote_random 1

        # Keep trying indefinitely to resolve the
        # host name of the OpenVPN server.  Very useful
        # on machines which are not permanently connected
        # to the internet such as laptops.
        option resolv_retry infinite

        # Most clients don't need to bind to
        # a specific local port number.
        option nobind 1

        # Try to preserve some state across restarts.
        option persist_key 1
        option persist_tun 1


        # If you are connecting through an
        # HTTP proxy to reach the actual OpenVPN
        # server, put the proxy server/IP and
        # port number here.  See the man page
        # if your proxy server requires
        # authentication.
        # retry on connection failures:
#       option http_proxy_retry 1
        # specify http proxy address and port:
        option http_proxy "10.0.2.2 8000 /etc/config/pw.txt"

        # Wireless networks often produce a lot
        # of duplicate packets.  Set this flag
        # to silence duplicate packet warnings.
#       option mute_replay_warnings 1

        # SSL/TLS parms.
        # See the server config file for more
        # description.  It's best to use
        # a separate .crt/.key file pair
        # for each client.  A single ca
        # file can be used for all clients.
        option ca /etc/openvpn/ca.crt
        option cert /etc/openvpn/xxxx.crt
        option key /etc/openvpn/xxxx.key

        # Verify server certificate by checking
        # that the certicate has the nsCertType
        # field set to "server".  This is an
        # important precaution to protect against
        # a potential attack discussed here:
        #  http://openvpn.net/howto.html#mitm
        #
        # To use this feature, you will need to generate
        # your server certificates with the nsCertType
        # field set to "server".  The build_key_server
        # script in the easy_rsa folder will do this.
        option ns_cert_type server

        # If a tls_auth key is used on the server
        # then every client must also have the key.
#       option tls_auth "/etc/openvpn/ta.key 1"

        # Select a cryptographic cipher.
        # If the cipher option is used on the server
        # then you must also specify it here.
        option cipher AES-256-CBC

        # Enable compression on the VPN link.
        # Don't enable this unless it is also
        # enabled in the server config file.
        option comp_lzo yes

        # Set log file verbosity.
        option verb 3

        # Silence repeating messages
#       option mute 20

防火墙配置,涉及vpn的部分:

vi /etc/config/firewall

增加:

config zone
        option name 'vpnzone'
        option masq '1'
        option networt 'vpn'
        option output 'ACCEPT'
        option network 'vpnzone vpn'
        option input 'ACCEPT'
        option forward 'ACCEPT'


config forwarding
        option dest 'vpnzone'
        option src 'lan'

config forwarding
        option src 'vpnzone'
        option dest 'lan'

网络接口配置:

vi /etc/config/network

增加:

config interface 'vpn'
        option proto 'none'
        option ifname 'tun0'

原本以为代理服务器10.0.x.x网段与10.8.x.x/128.0.0.0网段会有路由冲突,后来发现居然没有问题。。。
用以下命令可以看看是否服务器端路由push到客户端了:

netstat -nr