目前针对于跨国业务,所以国内外访问的服务可能是不同的(至少不是同一个页面),但域名想要同一个域名,于是想到要区分开访问区域。
阿里云域名解析时,提供了域名解析业务,针对于不同的客户端,解析到不同的服务上。
这种方案可以不过多解释,就是浏览器的IP不同,解析到的服务器不同同一个服务器,所以部署两套不同的服务即可。
使用nginx配置GeoIP插件,就可以在nginx访问时,区分出来源IP所在的国家。
但是使用这个方案时,遇到了几个问题:
问题1:maxmind官网宣布“我们不再为新客户提供即时访问GeoIP Legacy产品的权限”。目前网络上可以查到的配置,基本上为GeoIP的配置方案。
解决方法:
官网提供了一个升级版GeoIP2。
GeoIP2有什么新的功能?MaxMind的GeoIP2 Precision服务和GeoIP2数据库是我们最初的GeoIP Web服务和数据库的演变,详细可见官网说明。
GeoIP2将数据库从GeoIP.dat换成GeoLite2-Country.mmdb。
问题2:我们使用的是docker的nginx镜像,如何在docker镜像中安装nginx插件。
解决方法:
1.搜索dockerhub,不过截至目前,dockerhub中能够搜到的官方nginx提供的是GeoIP的,非官方提供的GeoIP2 nginx,测试了一下,不可使用(也可能我测试方法不对,也可能是我没有搜到可用的)。
2.自己构建可使用的nginx镜像(目前我使用的是这种方法,具体方法后续提供)。
问题3:GeoIP2使用的nginx插件,在MaxMind官网提供的API提示“警告!MaxMind并没有提供对这些API的支持,并没有审查的代码,使用风险由您自己承担。”。
解决方法:忽略。
目前我应用的是方案二,并使用自建的nginx镜像。
Dockerfile
FROM alpine:3.5
MAINTAINER wencst "[email protected]"
ENV NGINX_VERSION 1.11.13
RUN GPG_KEYS=B0F4253373F8F6F510D42178520A9993A1C052F8 \
&& CONFIG="\
--prefix=/etc/nginx \
--sbin-path=/usr/sbin/nginx \
--modules-path=/usr/lib/nginx/modules \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--http-client-body-temp-path=/var/cache/nginx/client_temp \
--http-proxy-temp-path=/var/cache/nginx/proxy_temp \
--http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp \
--http-scgi-temp-path=/var/cache/nginx/scgi_temp \
--user=nginx \
--group=nginx \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module=dynamic \
--with-http_image_filter_module=dynamic \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-http_slice_module \
--with-mail \
--with-mail_ssl_module \
--with-compat \
--with-file-aio \
--with-http_v2_module \
--with-cpu-opt='amd64' \
--with-cc-opt='-I/usr/local/include' \
--with-ld-opt='-L/usr/local/lib' \
" \
&& addgroup -S nginx \
&& adduser -D -S -h /var/cache/nginx -s /sbin/nologin -G nginx nginx \
&& apk add --no-cache --virtual .build-deps \
gcc \
libc-dev \
git \
make \
automake \
autoconf \
libtool \
linux-headers \
openssl-dev \
pcre-dev \
zlib-dev \
curl \
gnupg \
libxslt-dev \
gd-dev \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz -o nginx.tar.gz \
&& curl -fSL http://nginx.org/download/nginx-$NGINX_VERSION.tar.gz.asc -o nginx.tar.gz.asc \
&& git clone --recursive https://github.com/maxmind/libmaxminddb.git \
&& git clone --recursive https://github.com/leev/ngx_http_geoip2_module.git \
&& export GNUPGHOME="$(mktemp -d)" \
&& found=''; \
for server in \
ha.pool.sks-keyservers.net \
hkp://keyserver.ubuntu.com:80 \
hkp://p80.pool.sks-keyservers.net:80 \
pgp.mit.edu \
; do \
echo "Fetching GPG key $GPG_KEYS from $server"; \
gpg --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$GPG_KEYS" && found=yes && break; \
done; \
test -z "$found" && echo >&2 "error: failed to fetch GPG key $GPG_KEYS" && exit 1; \
gpg --batch --verify nginx.tar.gz.asc nginx.tar.gz \
&& rm -r "$GNUPGHOME" nginx.tar.gz.asc \
&& mkdir -p /usr/src \
&& tar -zxC /usr/src -f nginx.tar.gz \
&& rm nginx.tar.gz \
&& cp -r ./libmaxminddb /usr/src \
&& cp -r ./ngx_http_geoip2_module /usr/src \
&& rm -rf libmaxminddb \
&& rm -rf ngx_http_geoip2_module \
&& export CFLAGS="-O2" \
CPPFLAGS="-O2" \
LDFLAGS="-O2" \
&& cd /usr/src/libmaxminddb \
&& ./bootstrap \
&& ./configure \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& make install \
&& cd /usr/src/nginx-$NGINX_VERSION \
&& ./configure $CONFIG --add-dynamic-module=/usr/src/ngx_http_geoip2_module \
&& make -j$(getconf _NPROCESSORS_ONLN) \
&& make install \
&& mkdir -p /usr/share/nginx/html/ \
&& install -m644 html/index.html /usr/share/nginx/html/ \
&& install -m644 html/50x.html /usr/share/nginx/html/ \
&& strip /usr/sbin/nginx* \
&& strip /usr/lib/nginx/modules/*.so \
&& rm -rf /usr/src/nginx-$NGINX_VERSION \
&& rm -rf /usr/src/libmaxminddb \
&& rm -rf /usr/src/ngx_http_geoip2_module \
&& apk add --no-cache --virtual .gettext gettext \
&& mv /usr/bin/envsubst /tmp/ \
&& runDeps="$( \
scanelf --needed --nobanner /usr/sbin/nginx /usr/lib/nginx/modules/*.so /tmp/envsubst \
| awk '{ gsub(/,/, "\nso:", $2); print "so:" $2 }' \
| sort -u \
| xargs -r apk info --installed \
| sort -u \
)" \
&& apk add --no-cache --virtual .nginx-rundeps $runDeps \
&& apk --no-cache add tzdata \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& apk del .build-deps \
&& apk del .gettext \
&& mv /tmp/envsubst /usr/local/bin/
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Copy
执行构建
docker build -t wencst/nginx .
Copy
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.mmdb.gz
wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.mmdb.gz
gunzip GeoLite2-Country.mmdb.gz
gunzip GeoLite2-City.mmdb.gz
Copy
docker run -d --name nginx wencst/nginx
docker exec -it nginx /bin/sh
Copy
服务中执行:mmdblookup命令,如果可以执行,说明安装成功。
基本命令:
mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8
Copy
访问某一个域:
mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8 country iso_code
Copy
nginx基本配置/etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
load_module /usr/lib/nginx/modules/ngx_http_geoip2_module.so;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
#GEOIP2 地址加载
geoip2 /usr/share/GeoIP/GeoLite2-Country.mmdb {
$geoip2_data_country_code default=CN country iso_code;
$geoip2_data_country_name country names en;
}
fastcgi_param COUNTRY_CODE $geoip2_data_country_code;
fastcgi_param COUNTRY_NAME $geoip2_data_country_name;
include /etc/nginx/conf.d/*.conf;
}
Copy
具体配置/etc/nginx/conf.d/default.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/log/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
if ($geoip2_data_country_code = CN) {
root /usr/share/nginx/html/cn;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Copy
docker run -d -p 80:80 --name nginx -v `pwd`/config/nginx:/etc/nginx -v `pwd`/GeoIP:/usr/share/GeoIP -v `pwd`/nginx:/usr/share/nginx -v `pwd`/logs:/var/log/nginx wencst/nginx
Copy
将配置文件配置好并映射到镜像中。
这样中国IP访问的是cn文件夹下的内容,其他国家访问的是根路径下的内容。注意这里测试时,最好使用实际国外的IP进行测试,使用VPN不会起作用。
备注:使用nginx -t 验证config文件的配置情况。