由于公司海外和国内业务的需求,需要使用到谷歌服务,因为不可描述的原因,谷歌在国内一直处于404状态。所以本文记录一下针对谷歌地图服务反代的配置操作。
原理介绍
谷歌地图 javascript 的调用是通过引入一个入口js文件 https://maps.googleapis.com/maps/api/js
,然后加载所有谷歌地图所需要的资源链接。
但是这个入口js文件中还存在很多谷歌的资源链接, 所以只反代入口js文件,事实上还是无法去正常加载 地图资源。
所以如果想要能在国内正常使用谷歌地图,则需要将该入口js 文件中所有的 资源链接都进行反代。
配置流程:
- 一台可以访问Google Map的服务器,并且未被墙;
- 提取入口js文件中的资源链接地址;
- 编写Nginx配置文件,对反代过来的文件中的地址进行替换
- 定时更新入口js文件的资源链接地址,防止有新的域名未进行配置
生成配置文件
我这边使用的是coderecord编写的Python 脚本。
URLExtract库库可以提取文本中的链接地址。
1 2 3 4 5 6 7 8 9
| pip install idna pip install uritools pip install urlextract
# python3 pip3 install idna pip3 install uritools pip3 install urlextract
|
安装Python Requests库
Requests库,http库。
1 2 3 4 5
| pip install requests
# python3 pip3 install requests
|
python 脚本
新建py脚本 main.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| import hashlib import requests from urlextract import URLExtract
sourceurl = "https://maps.googleapis.com/maps/api/js" maindomain = "maps.your-domain.com" mainapidomain = "mapsapis.your-domain.com"
def getmd5(txt): hl = hashlib.md5() hl.update(txt.encode(encoding='utf-8')) return hl.hexdigest()
def getAllLink(txt): extractor = URLExtract() urls = extractor.find_urls(txt) return urls
def save(filename,content): with open(filename,"w") as w: for row in content: w.write(row+"\n")
def main(): source = requests.get(sourceurl) alllink = getAllLink(source.text) linkdata = []
for link in alllink: if "https" in link and link not in linkdata and "www.google.cn" not in link and "maps.google.cn" not in link: linkdata.append(link)
replacefilter = [] location =[] alldomain = [] for row in linkdata: if(len(row)>0): domain = row.replace("https://","").split("/")[0] if domain in alldomain: continue alldomain.append(domain)
if "maps.googleapis.com" in row: replacefilter.append("replace_filter %s %s ig;"%(domain,mainapidomain)) elif "www.google.com" in row: replacefilter.append("replace_filter %s %s ig;"%(domain,"www.google.cn")) else: md5val = getmd5(domain.replace(".","")) replacefilter.append("replace_filter %s %s ig;"%(domain,maindomain+"/"+md5val)) location.append("location /%s/ { proxy_pass %s; }"%(md5val,"https://"+domain+"/"));
save("replace.conf",replacefilter) save("location.conf",location)
if __name__ == "__main__": main()
|
生成配置
运行 main.py
文件
1 2 3 4 5
| python main.py
# python3 python3 main.py
|
此时会生成replace.conf、location两个文件,这两个文件可以直接引入到NGINX中。
NGINX 配置
NGINX我们需要使用到 replace-filter-nginx-module 模块。
检查环境
运行
1 2 3 4 5 6 7 8
| nginx -V ----------- nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.1.1g 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-pcre-jit --with-ld-opt=-ljemalloc --add-module=../replace-filter-nginx-module
|
注意查看configure argument
中 是否存在replace-filter-nginx-module
,如果存在可以直接跳到NGINX配置文件步骤, 如果不存在则需要重新编译安装NGINX。
安装 replace-filter-nginx-module
如果你之前编译的文件还存在 直接之前的目录中编译是最好的,如果没有重新下载也是可以的, 但是注意,如果你的NGINX有其他的编译配置,记得也要在相应目录中下载这些依赖。
安装此模块需要先安装 sregex 运行库:
1 2 3 4
| git clone https://github.com/agentzh/sregex cd sregex make make install
|
下载replace-filter-nginx-module源码
需要和NGINX源码文件夹 在同一层, 如果不在同一层,那么注意下面编译时的地址。
1
| git clone https://github.com/agentzh/replace-filter-nginx-module
|
重新编译 NGINX
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| > nginx -V nginx -V ----------- nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.1.1g 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-pcre-jit --with-ld-opt=-ljemalloc
# 得知NGINX版本是 1.18.0 下载NGINX源码 > wget http://nginx.org/download/nginx-1.18.0.tar.gz
> tar xzf nginx-1.18.0.tar.gz
> cd nginx-1.18.0
# nginx -V 中的configure arguments参数最后面添加--add-module=./replace-filter-nginx-module > ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-pcre-jit --with-ld-opt=-ljemalloc --add-module=./replace-filter-nginx-module
# 编译。 > make
# 编译成功后测试是否正常,如果显示replace-filter-nginx-module则说明成功 > ./objs/nginx -V
nginx version: nginx/1.18.0 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) built with OpenSSL 1.1.1g 21 Apr 2020 TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --user=www --group=www --with-http_stub_status_module --with-http_v2_module --with-http_ssl_module --with-http_gzip_static_module --with-http_realip_module --with-http_flv_module --with-http_mp4_module --with-openssl=../openssl-1.1.1g --with-pcre=../pcre-8.44 --with-pcre-jit --with-ld-opt=-ljemalloc --add-module=./replace-filter-nginx-module
# 替换 > cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak > cp -rfp ./objs/nginx /usr/local/nginx/sbin/
|
添加NGINX配置文件
在NGINX配置目录下新建一个 googlemap
的文件夹,将之前生成的replace.conf、location两个文件放入其中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| server { listen 80; listen 443 ssl http2; ssl_certificate /usr/local/nginx/conf/ssl/maps.your-domain.com.crt; ssl_certificate_key /usr/local/nginx/conf/ssl/maps.your-domain.com.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-GCM-SHA256:TLS13-AES-128-CCM-8-SHA256:TLS13-AES-128-CCM-SHA256:EECDH+CHACHA20:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5; ssl_prefer_server_ciphers on; ssl_session_timeout 10m; ssl_session_cache builtin:1000 shared:SSL:10m; ssl_buffer_size 1400; add_header Strict-Transport-Security max-age=15768000; ssl_stapling on; ssl_stapling_verify on; server_name maps.your-domain.com mapsapis.your-domain.com; if ($ssl_protocol = "") { return 301 https://$host$request_uri; }
error_page 404 /404.html; #error_page 502 /502.html;
location /maps/ { default_type text/javascript; proxy_set_header Accept-Encoding ''; proxy_pass https://maps.googleapis.com/maps/; replace_filter_max_buffered_size 500k; replace_filter_last_modified keep; replace_filter_types text/javascript application/javascript; include /usr/local/nginx/conf/googlemap/replace.conf; } location /maps-api-v3/ { proxy_pass https://maps.googleapis.com/maps-api-v3/; }
include /usr/local/nginx/conf/googlemap/location.conf; }
|
NGINX重载配置。这样就成功了。
之后就调用https://maps.your-domain.com/maps/api/js
使用
自动更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #!/bin/bash googlemap_dir="/data/googlemap" nginx_dir="/usr/local/nginx"
pushd ${googlemap_dir} python3 ${googlemap_dir}/main.py
if [ -f "location.conf" ]; then /bin/mv ${nginx_dir}/conf/googlemap/location.conf ${nginx_dir}/conf/googlemap/location.conf.bak /bin/mv ${nginx_dir}/conf/googlemap/replace.conf ${nginx_dir}/conf/googlemap/replace.conf.bak /bin/cp ${googlemap_dir}/location.conf ${nginx_dir}/conf/googlemap/location.conf /bin/cp ${googlemap_dir}replace.conf ${nginx_dir}/conf/googlemap/replace.conf ${nginx_dir}/sbin/nginx -t if [ $? == 0 ]; then echo "Reload Nginx......" ${nginx_dir}/sbin/nginx -s reload else /bin/mv ${nginx_dir}/conf/googlemap/location.conf.bak ${nginx_dir}/conf/googlemap/location.conf /bin/mv ${nginx_dir}/conf/googlemap/replace.conf.bak ${nginx_dir}/conf/googlemap/replace.conf echo "Update googlemap ... FAILED]" exit 1 fi else echo "nginx conf failed" fi
|
将脚本放入定时任务中即可。