Recently, our company had a requirement to access the Google push server (https://android.googleapis.com/gcm/send) located abroad through a domestic server.
Initially, we considered setting up a VPN. However, since both sides of the connection use Linux servers, we temporarily avoided this method due to risk considerations.
After testing various methods, we summarized an effective solution:
Solution: Squid Authenticated Proxy + Stunnel
This method requires having your own VPS.
Configuration Steps
2. Install Squid on the Server Side
- Install Squid
# yum install squid openssl openssl-devel
- Generate Encrypted Proxy Certificate
# cd /etc/squid
# openssl req -new > example.csr // Enter password and confirm password
# openssl rsa -in privkey.pem -out example.key // Enter the password input above
# openssl x509 -in example.csr -out example.crt -req -signkey example.key -days 3650
Create Authentication User
# touch /etc/squid/passwd
# chown root.squid /etc/squid/passwd
# chmod 640 /etc/squid/passwd
# /usr/local/apache/bin/htpasswd /etc/squid/passwd 360push
- Configure Squid
# vim /etc/squid/squid.conf
visible_hostname push.360push.com
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 182.150.2.130/32 // push client
acl SSL_ports port 443
acl Safe_ports port 443 # https
acl Safe_ports port 1025-65535 # unregistered ports
acl CONNECT method CONNECT
https_port 443 cert=/etc/squid/example.crt key=/etc/squid/example.key
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
http_access allow localnet
http_access allow localhost
http_access deny all
cache_dir ufs /var/spool/squid 2048 16 256
coredump_dir /var/spool/squid
acl OverConnLimit maxconn 100 // Limit max connections per IP to 10 to prevent attacks
minimum_object_size 1 KB // Allow minimum file request body size
maximum_object_size 1 MB // Allow maximum file request body size
cache_swap_low 10 // Minimum allowed swap usage 10%
cache_swap_high 25 // Maximum allowed swap usage 25%
cache_mem 300 MB // Available memory
##Add auth##
auth_param basic program /usr/lib64/squid/basic_ncsa_auth /etc/squid/passwd
auth_param basic children 5
auth_param basic credentialsttl 12 hours
auth_param basic realm Push Server
acl 360push proxy_auth REQUIRED
Since VPS disk space and memory are limited, we need to control the memory and disk usage of Squid.
- Start Squid and Verify
# squid -z // Generate swap files
# squid -k parse // Check configuration file correctness
# /etc/init.d/squid start
VPS rarely has firewalls enabled by default. If yours does, turn it off first. Re-enable the ports after all configurations are complete.
3. Install and Configure Stunnel on the Client Side
- Install
# yum install stunnel
- Add Configuration to /etc/stunnel/stunnel.conf
client = yes
fips = no
[https]
accept = 8888
connect = VPS_IP:443
If you encounter the error FIPS_mode_set: 2D06C06E: error:2D06C06E:FIPS routines:FIPS_module_mode_set:fingerprint does not match, add fips = no to the stunnel.conf configuration file.
- Start Stunnel and Verify
# stunnel // Start, default config path is /etc/stunnel/stunnel.conf
Test Locally with Curl
curl -v -x 127.0.0.1:8888 -U 360push:360push https://android.googleapis.com/gcm/send
You can also use a proxy server in PHP:
function testCurl($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $gurl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, TRUE);
curl_setopt($ch, CURLOPT_PROXY, "127.0.0.1:8888"); // ip/port
curl_setopt($ch, CURLOPT_PROXYUSERPWD, '360push:360push'); // auth user and password
$result=curl_exec($ch);
curl_close($ch);
return $result;
}
echo testCurl("google.com");
Google Error Resolution
If Google returns the following error:
We’re sorry… but your computer or network may be sending automated queries. To protect our users, we can’t process your request right now
Solution 1: Edit /etc/sysctl.conf and add the following content:
net.ipv6.conf.all.disable_ipv6=1
net.ipv6.conf.default.disable_ipv6=1
net.ipv6.conf.lo.disable_ipv6=1
Restart the network interface:
# /etc/init.d/networking restart
Solution 2: Apply changes in real-time:
echo '1' > /proc/sys/net/ipv6/conf/lo/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/lo/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/all/disable_ipv6
echo '1' > /proc/sys/net/ipv6/conf/default/disable_ipv6