59

如何设置根据不同的IP地址所在地域访问不同的服务?

 5 years ago
source link: https://www.wencst.com/archives/1564?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

现象

目前针对于跨国业务,所以国内外访问的服务可能是不同的(至少不是同一个页面),但域名想要同一个域名,于是想到要区分开访问区域。

方案

方案一:

阿里云域名解析时,提供了域名解析业务,针对于不同的客户端,解析到不同的服务上。

这种方案可以不过多解释,就是浏览器的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镜像。

步骤一:构建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;"]

执行构建

docker build -t wencst/nginx .

步骤二:下载IP数据库

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

步骤三:测试服务可用性

docker run -d --name nginx wencst/nginx
docker exec -it nginx /bin/sh

服务中执行:mmdblookup命令,如果可以执行,说明安装成功。

基本命令:

mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8

Qzq2iay.png!web

访问某一个域:

mmdblookup --file /usr/share/GeoIP/GeoLite2-Country.mmdb --ip 8.8.8.8 country iso_code

zU77Rzi.png!web

步骤四:nginx服务配置

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;
}

具体配置/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;
    }
}

步骤五:执行完整验证

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

将配置文件配置好并映射到镜像中。

这样中国IP访问的是cn文件夹下的内容,其他国家访问的是根路径下的内容。注意这里测试时, 最好使用实际国外的IP进行测试,使用VPN不会起作用


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK